Docker容器数据卷
什么是容器数据卷
如果数据都在容器中,那么容器删除,数据就会丢失!需求:数据可以持久化
Mysql,容器删除=删库跑路!需求:Mysql数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将容器内的目录,挂载到Linux上面!
总结一句话:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
方式一:直接使用命令来挂载 -v
# 命令
docker run -it -v 主机目录:容器目录
# 测试
[root@iz2zeaet7s13lfkc8r3e2kz /]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@iz2zeaet7s13lfkc8r3e2kz ~]# cd /home
[root@iz2zeaet7s13lfkc8r3e2kz home]# ls
ceshi www ysl
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7dbb19e4fb8c centos "/bin/bash" About a minute ago Up About a minute objective_cartwright
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker inspect 7dbb19e4fb8c
测试文件的同步
# 在容器挂载的目录下创建一个test.java文件
[root@7dbb19e4fb8c home]# touch test.java
[root@7dbb19e4fb8c home]# ls
test.java
# 对应的主机目录下也存在了test.java文件
[root@iz2zeaet7s13lfkc8r3e2kz ceshi]# ls
test.java
# 退出容器,在本机的目录下修改test.java文件
[root@7dbb19e4fb8c home]# exit
exit
[root@iz2zeaet7s13lfkc8r3e2kz /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iz2zeaet7s13lfkc8r3e2kz /]# cd /home/ceshi
[root@iz2zeaet7s13lfkc8r3e2kz ceshi]# ls
test.java
[root@iz2zeaet7s13lfkc8r3e2kz ceshi]# vim test.java
[root@iz2zeaet7s13lfkc8r3e2kz ceshi]# cat test.java
hello,linux updata
# 进入容器查看,容器内的test.java文件也修改了
[root@iz2zeaet7s13lfkc8r3e2kz ceshi]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS
7dbb19e4fb8c centos "/bin/bash" 25 minutes ago Exited (0)
[root@iz2zeaet7s13lfkc8r3e2kz ceshi]# docker start 7dbb19e4fb8c
7dbb19e4fb8c
[root@iz2zeaet7s13lfkc8r3e2kz ceshi]# docker attach 7dbb19e4fb8c
[root@7dbb19e4fb8c /]# cd /home
[root@7dbb19e4fb8c home]# ls
test.java
[root@7dbb19e4fb8c home]# cat test.java
hello,linux updata
好处:以后就可以直接在本机下修改配置文件即可,不需要在进入容器修改
结论:双向同步,不管在哪一方更新,另一方也会同步
实战:安装MySql
思考:MySql的数据持久化的问题!
# 获取镜像
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker pull mysql:5.7
# 运行容器,需要做数据挂载!
# 启动
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 --name mysql01 mysql:5.7
启动成功之后,在本地用 sqlyog 在测试一下
sqlyog -- 链接到服务器的3310 ---- 3310 和容器内的 3306 映射,这个时候就可以链接上了!
注意:安全组端口一定要开
# 在本机中查看data文件以有内容
[root@iz2zeaet7s13lfkc8r3e2kz home]# ls
ceshi mysql www ysl
[root@iz2zeaet7s13lfkc8r3e2kz home]# cd mysql
[root@iz2zeaet7s13lfkc8r3e2kz mysql]# ls
conf data
[root@iz2zeaet7s13lfkc8r3e2kz mysql]# cd data
[root@iz2zeaet7s13lfkc8r3e2kz data]# ls
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem
[root@iz2zeaet7s13lfkc8r3e2kz data]#
测试在sqlyog中创建一个数据库,看本机data下会不会同步!
查看
测试删除mysql容器
[root@iz2zeaet7s13lfkc8r3e2kz mysql]# docker rm -f mysql01
mysql01
[root@iz2zeaet7s13lfkc8r3e2kz mysql]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iz2zeaet7s13lfkc8r3e2kz mysql]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7dbb19e4fb8c centos "/bin/bash" About an hour ago Exited (0) 29 minutes ago objective_cartwright
ca829305596e tomcat "catalina.sh run" 42 hours ago Exited (143) 42 hours ago elated_wiles
585d63efcef0 tomcat "catalina.sh run" 42 hours ago Exited (130) 42 hours ago mystifying_bohr
[root@iz2zeaet7s13lfkc8r3e2kz mysql]# cd data
[root@iz2zeaet7s13lfkc8r3e2kz data]# ls
auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem test
挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化技术
具名和匿名挂载
# 匿名挂载
-v 容器内路径!
-P 大写P 随机映射端口号
docker run -d -P --name nginx01 -v /ect/nginx nginx
#查看卷的所有情况
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker volume ls
DRIVER VOLUME NAME
local 772d8510d653781ce4cd6538e7f5365969810882d415c276048cf9ae945220c1
local ca79699085e317d91f240456218413237e93f2ffcae60b6225900eb64a5df3d2
# 这种就是匿名挂载,我在-v 只写了容器内的路径,没有写容器外的路径!
# 具名挂载
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
5d599ed31df0b2fbc309d9a5633bbee69ef740d1079c90b7fb073c4f844a575d
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker volume ls
DRIVER VOLUME NAME
local 772d8510d653781ce4cd6538e7f5365969810882d415c276048cf9ae945220c1
local ca79699085e317d91f240456218413237e93f2ffcae60b6225900eb64a5df3d2
local juming-nginx
# 通过 -v 卷名:容器内路径
# 查看一下这个卷
所有的docker容器内的卷,没有指定目录的情况下都是在/ver/lib/docker/volumes/xxx.../_data
[root@iz2zeaet7s13lfkc8r3e2kz home]# cd /var/lib/docker
[root@iz2zeaet7s13lfkc8r3e2kz docker]# ls
builder buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
[root@iz2zeaet7s13lfkc8r3e2kz docker]# cd volumes/
[root@iz2zeaet7s13lfkc8r3e2kz volumes]# ls
772d8510d653781ce4cd6538e7f5365969810882d415c276048cf9ae945220c1 juming-nginx
ca79699085e317d91f240456218413237e93f2ffcae60b6225900eb64a5df3d2 metadata.db
[root@iz2zeaet7s13lfkc8r3e2kz volumes]# cd juming-nginx/
[root@iz2zeaet7s13lfkc8r3e2kz juming-nginx]# ls
_data
[root@iz2zeaet7s13lfkc8r3e2kz juming-nginx]# cd _data/
[root@iz2zeaet7s13lfkc8r3e2kz _data]# ls
conf.d fastcgi_params koi-utf koi-win mime.types modules nginx.conf scgi_params uwsgi_params win-utf
[root@iz2zeaet7s13lfkc8r3e2kz _data]# cat nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
通过具名挂载可以方便的找到卷,大多数情况在使用具名挂载
# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载!
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载!
拓展:
# 通过 -v 容器内路径:ro 或 rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写
# 一旦设置了容器权限,容器对我们挂载出来的内容就有限定了!
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
初始DockerFile
DockerFile就是用来构建docker镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成一个镜像,镜像是一层一层的,脚本一个个的命令,每个命令都是一层!
# 创建一个dockerfile文件,名字随意,建议DockerFile
root@iz2zeaet7s13lfkc8r3e2kz home]# mkdir docker-test-volume
[root@iz2zeaet7s13lfkc8r3e2kz home]# ls
ceshi docker-test-volume mysql www ysl
[root@iz2zeaet7s13lfkc8r3e2kz home]# cd docker-test-volume/
# 文件中的内容 指令(大写) 参数
[root@iz2zeaet7s13lfkc8r3e2kz docker-test-volume]# vim dockerfile1
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#这里的每个命令,就是镜像的一层!
# 生成镜像!
[root@iz2zeaet7s13lfkc8r3e2kz docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile1 -t ysl/centos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 470671670cac
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in 4b26f821413a
Removing intermediate container 4b26f821413a
---> db972d1980d1
Step 3/4 : CMD echo "----end----"
---> Running in 118c175c4dd5
Removing intermediate container 118c175c4dd5
---> 272db10e0e63
Step 4/4 : CMD /bin/bash
---> Running in 7a462aaab949
Removing intermediate container 7a462aaab949
---> bf97aef123f3
Successfully built bf97aef123f3
Successfully tagged ysl/centos:1.0
[root@iz2zeaet7s13lfkc8r3e2kz docker-test-volume]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ysl/centos 1.0 bf97aef123f3 36 seconds ago 237MB
tomcat02 1.0 b0152d8846e1 44 hours ago 652MB
mysql 5.7 a4fdfd462add 3 days ago 448MB
tomcat latest 1b6b1fe7261e 8 days ago 647MB
nginx latest 9beeba249f3e 9 days ago 127MB
elasticsearch 7.6.2 f29a1ee41030 8 weeks ago 791MB
portainer/portainer latest 2869fc110bf7 2 months ago 78.6MB
centos latest 470671670cac 4 months ago 237MB
启动自己的容器
这个卷和外部一定有一个同步的目录!
查看卷挂载路径
测试文件是否同步
#在容器中添加container.txt
[root@743222b34d51 volume01]# touch container.txt
[root@743222b34d51 volume01]# ls
container.txt
#查看主机挂载目录下
[root@iz2zeaet7s13lfkc8r3e2kz home]# cd /var/lib/docker/volumes/8d8d71a545b7155ca545c1314e9d9c87e15d66a48bf4360f32ec1a03a0d5404e/_data
[root@iz2zeaet7s13lfkc8r3e2kz _data]# ls
container.txt
这种方式未来使用的十分多,因为我们通常会构建自己的镜像!
假设构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径
数据卷容器
两个mysql同步数据
# 测试
# 启动容器
[root@iz2zeaet7s13lfkc8r3e2kz docker-test-volume]# docker run -it --name docker01 ysl/centos:1.0
[root@4c87665bf62e /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@4c87665bf62e /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 06:37 dev
drwxr-xr-x 1 root root 4096 May 25 06:37 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64
drwx------ 2 root root 4096 Jan 13 21:48 lost+found
drwxr-xr-x 2 root root 4096 May 11 2019 media
drwxr-xr-x 2 root root 4096 May 11 2019 mnt
drwxr-xr-x 2 root root 4096 May 11 2019 opt
dr-xr-xr-x 105 root root 0 May 25 06:37 proc
dr-xr-x--- 2 root root 4096 Jan 13 21:49 root
drwxr-xr-x 11 root root 4096 Jan 13 21:49 run
lrwxrwxrwx 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 May 11 2019 srv
dr-xr-xr-x 13 root root 0 May 9 09:17 sys
drwxrwxrwt 7 root root 4096 Jan 13 21:49 tmp
drwxr-xr-x 12 root root 4096 Jan 13 21:49 usr
drwxr-xr-x 20 root root 4096 Jan 13 21:49 var
drwxr-xr-x 2 root root 4096 May 25 06:37 volume01 #数据卷
drwxr-xr-x 2 root root 4096 May 25 06:37 volume02 #数据卷
# Ctrl+p+q 退出容器容器继续运行
[root@iz2zeaet7s13lfkc8r3e2kz docker-test-volume]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c87665bf62e ysl/centos:1.0 "/bin/sh -c /bin/bash" 3 minutes ago Up 3 minutes docker01
# 在启动一个容器挂载这个容器
[root@iz2zeaet7s13lfkc8r3e2kz docker-test-volume]# docker run -it --name docker02 --volumes-from docker01 ysl/centos:1.0
[root@d92eaa59323a /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 06:45 dev
drwxr-xr-x 1 root root 4096 May 25 06:45 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64
drwx------ 2 root root 4096 Jan 13 21:48 lost+found
drwxr-xr-x 2 root root 4096 May 11 2019 media
drwxr-xr-x 2 root root 4096 May 11 2019 mnt
drwxr-xr-x 2 root root 4096 May 11 2019 opt
dr-xr-xr-x 106 root root 0 May 25 06:45 proc
dr-xr-x--- 2 root root 4096 Jan 13 21:49 root
drwxr-xr-x 11 root root 4096 Jan 13 21:49 run
lrwxrwxrwx 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 May 11 2019 srv
dr-xr-xr-x 13 root root 0 May 9 09:17 sys
drwxrwxrwt 7 root root 4096 Jan 13 21:49 tmp
drwxr-xr-x 12 root root 4096 Jan 13 21:49 usr
drwxr-xr-x 20 root root 4096 Jan 13 21:49 var
drwxr-xr-x 2 root root 4096 May 25 06:37 volume01 #数据卷
drwxr-xr-x 2 root root 4096 May 25 06:37 volume02 #数据卷
#测试
# 在docker01中添加文件
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker attach 4c87665bf62e
[root@4c87665bf62e /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin
drwxr-xr-x 5 root root 360 May 25 06:37 dev
drwxr-xr-x 1 root root 4096 May 25 06:37 etc
drwxr-xr-x 2 root root 4096 May 11 2019 home
lrwxrwxrwx 1 root root 7 May 11 2019 lib -> usr/lib
lrwxrwxrwx 1 root root 9 May 11 2019 lib64 -> usr/lib64
drwx------ 2 root root 4096 Jan 13 21:48 lost+found
drwxr-xr-x 2 root root 4096 May 11 2019 media
drwxr-xr-x 2 root root 4096 May 11 2019 mnt
drwxr-xr-x 2 root root 4096 May 11 2019 opt
dr-xr-xr-x 107 root root 0 May 25 06:37 proc
dr-xr-x--- 2 root root 4096 Jan 13 21:49 root
drwxr-xr-x 11 root root 4096 Jan 13 21:49 run
lrwxrwxrwx 1 root root 8 May 11 2019 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 May 11 2019 srv
dr-xr-xr-x 13 root root 0 May 9 09:17 sys
drwxrwxrwt 7 root root 4096 Jan 13 21:49 tmp
drwxr-xr-x 12 root root 4096 Jan 13 21:49 usr
drwxr-xr-x 20 root root 4096 Jan 13 21:49 var
drwxr-xr-x 2 root root 4096 May 25 06:37 volume01
drwxr-xr-x 2 root root 4096 May 25 06:37 volume02
[root@4c87665bf62e /]# cd volume01
[root@4c87665bf62e volume01]# ls
[root@4c87665bf62e volume01]# touch docker01
[root@4c87665bf62e volume01]# ls
docker01
# 在docker02中查看是否同步
[root@d92eaa59323a /]# cd volume01
[root@d92eaa59323a volume01]# ls
docker01
# docker01 中创建的文件同步到了 docker02 中
# 测试再启动一个docker03容器,挂载docker01
[root@iz2zeaet7s13lfkc8r3e2kz docker-test-volume]# docker run -it --name docker03 --volumes-from docker01 ysl/centos:1.0
[root@edf6f8821d29 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@edf6f8821d29 /]# cd volume01
[root@edf6f8821d29 volume01]# ls
docker01
# 在docker03 中创建一个未见
[root@edf6f8821d29 volume01]# touch docker03
[root@edf6f8821d29 volume01]# ls
docker01 docker03
# 去docker01中查看
[root@4c87665bf62e volume01]# ls
docker01 docker03
# 发现已同步
# 删除docker01 再去docker02和docker03中查看
[root@4c87665bf62e volume01]# exit
exit
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
edf6f8821d29 ysl/centos:1.0 "/bin/sh -c /bin/bash" 5 minutes ago Up 5 minutes docker03
d92eaa59323a ysl/centos:1.0 "/bin/sh -c /bin/bash" 14 minutes ago Up 14 minutes docker02
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
edf6f8821d29 ysl/centos:1.0 "/bin/sh -c /bin/bash" 6 minutes ago Up 6 minutes docker03
d92eaa59323a ysl/centos:1.0 "/bin/sh -c /bin/bash" 15 minutes ago Up 15 minutes docker02
4c87665bf62e ysl/centos:1.0 "/bin/sh -c /bin/bash" 22 minutes ago Exited (127) About a minute ago docker01
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker rm -f 4c87665bf62e
4c87665bf62e
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
edf6f8821d29 ysl/centos:1.0 "/bin/sh -c /bin/bash" 7 minutes ago Up 7 minutes docker03
d92eaa59323a ysl/centos:1.0 "/bin/sh -c /bin/bash" 15 minutes ago Up 15 minutes docker02
# 去docker02中查看
[root@iz2zeaet7s13lfkc8r3e2kz home]# docker attach d92eaa59323a
[root@d92eaa59323a volume01]# ls
docker01 docker03
# 发现文件还在
# 去docker03 中查看
[root@edf6f8821d29 volume01]# ls
docker01 docker03
#也存在
多个mysql实现数据共享
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=1234 --name mysql01 mysql:5.7
docker run -p 3310:3306 -e MYSQL_ROOT_PASSWORD=1234 --name mysql02 --volumes-form mysql01 mysql:5.7
结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止!
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!