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

结论:

​ 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止!

​ 但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!

Tags: