容器数据卷
(通过学习B站up主狂神说Java视频进行编写)
如果数据都在容器中,那么我们容器删除,数据就会丢失!
需求: 数据可以持久化MySQL ,容器删了,删库跑路!需求: MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术! Docker 容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
一、使用讲解
1.使用数据卷
方式1:直接使用命令挂载 -v(写法与-p差不多)
$ docker run -it -v /home/ceshi:/home centos /bin/bash
2.查看是否挂载成功
#查看元数据
$ docker inspect db189268e0bf
#挂载部分如下
"Mounts": [
{
"Type": "bind",#绑定方式
"Source": "/home/ceshi",#主机内地址
"Destination": "/home",#容器内地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
3.测试
在主机创建test1.java,再在容器创建test2.java,在主机与容器中查看是否存在。
停止运行容器后,在主机编辑test1.java,在进入容器验证是否有修改。
二、mysql8实战
docker的mysql坑巨多,以下是我能够运行的版本。
1.下载镜像略
2.运行挂载
#需要注意的是,进入mysql是需要密码的
#官网上测试的语句如下:
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#若为最新版mysql,TAG可以省略
#-d 后台运行
#-p 端口映射
#自测:mysql8不能直接使用其视频挂载,否则无法运行容器
$ docker run --name mysql01 -d -p 3344:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql mysql
1.先创建目录并把my.cnf文件编辑好
$ mkdir -p /home/docker/mysql/conf && mkdir -p /home/docker/mysql/datadir
$ cd /home/docker/mysql/conf
$ vim my.cnf
my.cnf内容如下,可根据自己需要写
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Custom config should go here
!includedir /etc/mysql/conf.d/
2.开启并挂载容器
docker run --name mysql8 \
-p 3344:3306 -e MYSQL_ROOT_PASSWORD=root \
--mount type=bind,src=/home/docker/mysql/conf/my.cnf,dst=/etc/mysql/my.cnf \
--mount type=bind,src=/home/docker/mysql/datadir,dst=/var/lib/mysql \
-d mysql
3.进入容器,修改配置
# 进入mysql 容器
docker exec -it mysql8 bash
# 进入mysql
mysql -u root -p
# 修改登录权限(使得远程连接)
grant all privileges on *.* to 'root'@'%' with grant option;
#或者
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';
# 刷新数据库
flush privileges;
3.测试mysql是否能连接上
4.查看对应文件夹下的数据是否已同步(略)
三、具名与匿名挂载
名字是目录的就是指定路径挂载,没有名字是匿名挂载,有名字非目录为具名挂载。
匿名挂载
#这种就是匿名的挂载,只写了容器内的路径,没写容器外的
#-P 随机端口
$ docker run -d -P --name nginx01 -v /etc/ngnix nginx
# 获得volume(卷)集时,没有指定的名称
$ docker volume list
DRIVER VOLUME NAME
local 7864564c4c4daa2189b8b004f01aedb86b73ae2c95529147b23960d5421dfa7d
local be1b2f11ae04571db87624246bef737ebcf1d9e9d9c9553d890f93226dd4b157
local d3169c0dbcc9e78c0483ceab6d6952b8cfc2f25842c2c7775f146ae2d519f182
具名挂载
#-P 随机端口
$ docker run -d -P --name nginx02 -v jump-nginx:/etc/ngnix nginx
# 获得volume(卷)集时,有指定的名称
$ docker volume list
DRIVER VOLUME NAME
local 7864564c4c4daa2189b8b004f01aedb86b73ae2c95529147b23960d5421dfa7d
local be1b2f11ae04571db87624246bef737ebcf1d9e9d9c9553d890f93226dd4b157
local d3169c0dbcc9e78c0483ceab6d6952b8cfc2f25842c2c7775f146ae2d519f182
local jump-nginx
查看卷的位置
所有docker容器内的卷,如若没有指定目录,就会在/var/lib/docker/volumes/xxxxx中。
$ docker volume inspect jump-nginx
[
{
"CreatedAt": "2021-07-03T22:50:46+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/jump-nginx/_data",
"Name": "jump-nginx",
"Options": null,
"Scope": "local"
}
]
有关权限的挂载
# :ro read only 只能从外部改变挂载出来的内容,容器内部不能改变挂载内容,即只能通过宿主机操作
$ docker run -d -P --name nginx02 -v jump-nginx:/etc/ngnix:ro nginx
# :rw read write 可读可写
$ docker run -d -P --name nginx02 -v jump-nginx:/etc/ngnix:ro nginx
四、数据卷之Dockerfile
Dockerfile是用来构建docker镜像的构建文件,命令脚本。
通过脚本,通过一个个命令一层一层生成镜像。
编写脚本
$ vim dockerfile1
#内容如下,需要注意空格!!指令(大写) 参数
FROM centos
#如果后面步骤不能run,记得加斜杠/volume01
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
# -f file文件路径 -t 生成 注意后面带.
$ docker build -f dockerfile1 -t hx-centos:1.0 .
启动容器
$ docker run -it hx-centos:1.0 /bin/bash
[root@fe831a8a8363 /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Jul 3 15:36 dev
drwxr-xr-x. 1 root root 66 Jul 3 15:36 etc
drwxr-xr-x. 2 root root 6 Nov 3 2020 home
lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------. 2 root root 6 Dec 4 2020 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 2020 media
drwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x. 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x. 246 root root 0 Jul 3 15:36 proc
dr-xr-x---. 2 root root 162 Dec 4 2020 root
drwxr-xr-x. 11 root root 163 Dec 4 2020 run
lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x. 13 root root 0 Jul 3 07:16 sys
drwxrwxrwt. 7 root root 145 Dec 4 2020 tmp
drwxr-xr-x. 12 root root 144 Dec 4 2020 usr
drwxr-xr-x. 20 root root 262 Dec 4 2020 var
drwxr-xr-x. 2 root root 6 Jul 3 15:36 volume01
drwxr-xr-x. 2 root root 6 Jul 3 15:36 volume02
#上面的两个目录就是我们生成镜像时自动挂载(匿名挂载)的,启动是外部会有一个相同的目录产生。
查看匿名挂载路径
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fe831a8a8363 hx-centos:1.0 "/bin/bash" 9 minutes ago Up 9 minutes jolly_pare
$ docker inspect fe831a8a8363
"Mounts": [
{
"Type": "volume",
"Name": "d414d6c40944f07012714b59359aa06ddb5c59cb40b9fcebb9ba69f37c9fd342",
"Source": "/var/lib/docker/volumes/d414d6c40944f07012714b59359aa06ddb5c59cb40b9fcebb9ba69f37c9fd342/_data",
"Destination": "/volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "37b61e1d98d4ff8fe54e9a64c11c3966a546e597936655fd4b2c96b6a05e1793",
"Source": "/var/lib/docker/volumes/37b61e1d98d4ff8fe54e9a64c11c3966a546e597936655fd4b2c96b6a05e1793/_data",
"Destination": "/volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
测试数据是够同步到宿主机
1.先在容器内创建一个文件
[root@fe831a8a8363 /]# cd volume01
[root@fe831a8a8363 volume01]# ls
[root@fe831a8a8363 volume01]# touch test1.java
[root@fe831a8a8363 volume01]# ls
test1.java
2.在宿主机内查找访问文件是否存在
$ cd /var/lib/docker/volumes/d414d6c40944f07012714b59359aa06ddb5c59cb40b9fcebb9ba69f37c9fd342/_data
$ ls
test1.java
五、数据卷容器
1.通过我们刚刚写的镜像,启动三个容器
$ docker run -it --name centos01 hx-centos:1.0
#按住ctrl+p+q即可退出容器继续创建,实现同步
$ docker run -it --name centos02 --volumes-from centos01 hx-centos:1.0
$ docker run -it --name centos03 hx-centos:1.0
2.进入刚刚启动的容器1(centos01)
[root@localhost hx]# docker exec -it d08f25a5aa35 /bin/bash
[root@d08f25a5aa35 /]# ls -l
total 0
lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x. 5 root root 360 Jul 4 02:35 dev
drwxr-xr-x. 1 root root 66 Jul 4 02:35 etc
drwxr-xr-x. 2 root root 6 Nov 3 2020 home
lrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwx------. 2 root root 6 Dec 4 2020 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 2020 media
drwxr-xr-x. 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x. 2 root root 6 Nov 3 2020 opt
dr-xr-xr-x. 253 root root 0 Jul 4 02:35 proc
dr-xr-x---. 2 root root 162 Dec 4 2020 root
drwxr-xr-x. 11 root root 163 Dec 4 2020 run
lrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 2020 srv
dr-xr-xr-x. 13 root root 0 Jul 4 01:58 sys
drwxrwxrwt. 7 root root 145 Dec 4 2020 tmp
drwxr-xr-x. 12 root root 144 Dec 4 2020 usr
drwxr-xr-x. 20 root root 262 Dec 4 2020 var
drwxr-xr-x. 2 root root 6 Jul 4 02:48 volume01
drwxr-xr-x. 2 root root 6 Jul 4 02:35 volume02
[root@d08f25a5aa35 /]#
#进入volume01目录,并创建文件查看是否会同步
[root@d08f25a5aa35 /]# cd volume01
[root@d08f25a5aa35 volume01]# touch aaa.txt
[root@d08f25a5aa35 volume01]# ls
aaa.txt
3.在centos02中查看是否已经同步
[root@92f91f18e875 volume01]# ls
aaa.txt
有结果可知,已同步。
4.探究根本,查看挂载的地方是否在宿主机的同一目录下
#先查看centos02的挂载信息
"Mounts": [
{
"Type": "volume",
"Name": "5a95aa6339450734bd46f7b3c97416b8daff3c66d2219b3ff1adfaef23c01622",
"Source": "/var/lib/docker/volumes/5a95aa6339450734bd46f7b3c97416b8daff3c66d2219b3ff1adfaef23c01622/_data",
"Destination": "/volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "965af424de763017232857aabe061a6ab735b0364d0d3b07a57c006ee7970326",
"Source": "/var/lib/docker/volumes/965af424de763017232857aabe061a6ab735b0364d0d3b07a57c006ee7970326/_data",
"Destination": "/volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
#查看centos01的挂载信息
"Mounts": [
{
"Type": "volume",
"Name": "5a95aa6339450734bd46f7b3c97416b8daff3c66d2219b3ff1adfaef23c01622",
"Source": "/var/lib/docker/volumes/5a95aa6339450734bd46f7b3c97416b8daff3c66d2219b3ff1adfaef23c01622/_data",
"Destination": "/volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "965af424de763017232857aabe061a6ab735b0364d0d3b07a57c006ee7970326",
"Source": "/var/lib/docker/volumes/965af424de763017232857aabe061a6ab735b0364d0d3b07a57c006ee7970326/_data",
"Destination": "/volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
以下分别是centos01与centos02的volume01的挂载目录:
"Source": "/var/lib/docker/volumes/965af424de763017232857aabe061a6ab735b0364d0d3b07a57c006ee7970326/_data",
"Source": "/var/lib/docker/volumes/965af424de763017232857aabe061a6ab735b0364d0d3b07a57c006ee7970326/_data",
由此可知,容器间实现数据共享是基于数据卷挂载目录放在同一位置来实现的,即使用的卷是同一个。(与视频观点不一致)
(如有错误,欢迎指正)