Docker——Docker 容器数据卷(Volumes)

Posted Pakho`

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker——Docker 容器数据卷(Volumes)相关的知识,希望对你有一定的参考价值。

容器数据卷(Volumes)

容器数据卷概述

  • Docker的理念回顾
    • 应用环境打包成一个镜像
    • 很多时候容器是需要保存数据,如果数据都保存在容器中,那么删除容器数据就会丢失, 需求:数据持久化
    • 如现有mysql,将MySQL容器删除,删除容器,但MySQL中存储了数据,就等于删库跑路,需要:MySQL数据可以存储在本地
    • 此时我们就需要一个容器共享的技术,Docker容器中产生的数据,同步到本地!
    • 这就是卷技术,目录的挂载,将容器内的目录,挂载到Linux
    • 同步机制,类似有点类似我们Redis里面的RDBAOF
      在这里插入图片描述
  • 总结一句话,使用容器数据卷技术为了容器的持久化同步操作
  • 特点:
    • 数据卷可在容器之间共享或重用数据
    • 卷中的更改可以直接生效
    • 数据卷中的更改不会包含在镜像的更新中
    • 数据卷容器的生命周期一直持续到没有容器使用它为止 (–volumes from)
  • 总结:
    • 容器数据的持久化
    • 容器间继承+共享数据

使用数据卷

方式一 直接使用命令挂载

  • Docker -v (Volumes)
docker run -it -v 主机目录:容器内目录

#启动一个容器不用提前创建test目录,启动容器后会自动创建
[root@docker ~]# docker run -it -v /home/test:/home/ centos /bin/bash
[root@d42da1fe7f0b /]#

#在主机查看容器挂载信息
[root@docker ~]# docker inspect d42da1fe7f0b
"Mounts": [
            {
                "Type": "bind",                    #绑定模式
                "Source": "/home/test",            #主机内地址
                "Destination": "/home",            #Docker容器内地址
                "Mode": "",                        
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

测试数据共享
#在容器内创建文件在Linux查看是否同步
[root@d42da1fe7f0b home]# touch index.html
[root@docker test]# ls
index.html
#同理在主机上给文件中接入数据在容器中依旧可以查看
  • 好处:我们以后修改文件只需在本地修改即可,容器会自动同步!

实战:MySQL同步数据

  • 思考:MySQL的数据持久化问题
#获取MySQL镜像
[root@docker ~]# docker pull mysql:5.7

#运行容器,需要做数据卷挂载
#-d:后台运行 -p:端口映射 -v:数据卷挂载 两个-v挂载两个目录 -e:环境配置 --name:容器名字 通过MySQL5.7镜像启动
[root@docker ~]# 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=123456 --name mysql01 mysql:5.7

#测试连接MySQL,使用SQLyog

在这里插入图片描述

#进入容器创建数据库
[root@docker ~]# docker exec -it mysql01 /bin/bash
root@cfe440b11537:/# mysql -uroot -p
Enter password:

mysql> create database docker;

#退出容器查看主机数据卷挂载点
[root@docker data]# ll
drwxr-x--- 2 polkitd input       20 Jun 23 12:35 docker

#最后将MySQL容器干掉
[root@docker data]# docker rm -f mysql01

#再次查看主机容器卷挂载点,数据依旧没有丢失,这就实现了容器数据持久化功能!

具名挂载和匿名挂载

  • 匿名挂载
    • -v 容器内路径
-P :随机映射端口 -v不指定路径直接选择容器内路径
[root@docker ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
  • Docker volume
[root@docker ~]# docker volume --help

Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume                                      #创建一个数据卷
  inspect     Display detailed information on one or more volumes  #查看卷的详细信息
  ls          List volumes                                         #查看当前所有的数据卷
  prune       Remove all unused local volumes                      #删除所有未使用的本地卷
  rm          Remove one or more volumes                           #删除一个或多个卷
#这种就是匿名挂载,我们在-v的时候只写了容器内的路径,没有写容器外的路径!
[root@docker ~]# docker volume ls                                  
DRIVER    VOLUME NAME
local     6fd1e7ed2332934314d58bd10639dd8d8739440c2eccb571b5bce2bb451201a8
  • 具名挂载
#通过 -v 卷名:容器内路径
[root@docker ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
[root@docker ~]# docker volume ls
DRIVER    VOLUME NAME
local     juming-nginx

#查看一下这个卷
[root@docker ~]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2021-06-23T21:16:52+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]
  • 所有的Docker容器内的卷,没有指定目录的情况下都是在/var.lib/docker/volumes/xxxx_data
    • 我们通过具名挂载可以方便地找到我们的一个卷,大多数情况在使用具名挂载
    • 如何区分具名挂载匿名挂载,还是指定路径挂载
      • 匿名:-v 容器内的路径
      • 具名:-v卷名:容器内路径
      • 指定路径:-v /宿主机路径:容器内路径
  • 扩展
    • ro readonly(只读)
    • rw readwrite(读写)
#一旦设置容器权限,容器对挂载出来的内容就有限定了!

#ro 只要看到ro就说明只能通过宿主机来操作,容器内部无法操作
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镜像构建文件!命令脚本!
  • 通过脚本可以生成镜像!镜像是一层一层的,脚本就是一个个的命令,每个命令都是一层!
[root@docker docker-test-volume]# pwd   #创建一个文件夹
/home/docker-test-volume

#创建一个dockerfile文件,名字可以随意,建议dockerfile
#文件中的指令(大写) 参数
[root@docker docker-test-volume]# vim dockerfile1 #编写一个测试文件
FROM centos                     #本镜像是用centos镜像作为基础

VOLUME ["/volume01","/volume02"]#通过volume挂载

CMD echo "----end----"          #构建完成后输出end
CMD /bin/bash                   #构建完成后进入默认是/bin/bash控制台
#这里的每个命令就是镜像的一层

docker build -f /home/docker-test-volume/dockerfile1 -t pakho/centos:1.0 .

docker images
REPOSITORY     TAG       IMAGE ID       CREATED          SIZE
pakho/centos   1.0       7a249dc716f2   43 minutes ago   209MB

#启动自己生成的容器
[root@docker docker-test-volume]# docker run -it 7a249dc716f2 /bin/bash
[root@e79dc11945cb /]#
  • 这两个目录就是我们生成镜像的时候自动挂载的,数据卷目录
  • 这个卷和外部一定有一个同步的目录
  • 这个属于匿名挂载

在这里插入图片描述

#在容器内部创建一个文件
[root@82d2427d0d67 volume01]# touch volume.txt

#查看挂载信息
docker inspect 82d2427d0d67

#测试创建文件是否同步
[root@docker _data]# ls
volume.txt

数据卷容器

  • 多个MySQL同步数据!容器与容器间同步!
    在这里插入图片描述
启动3个容器,通过我们自己写的镜像启动
docker images

docker run -it --name docker01 7a249dc716f2
docker run -it --name docker02 --volumes-from docker01 7a249dc716f2

docker01 volumes创建测试文件,去docker02查看数据是否同步
[root@66c335f24239 volume01]# touch docker01.txt

[root@f5350f562104 volume01]# ls
docker01.txt
  • docker01创建的数据同步到了docker02上
启动docker03依旧挂载至docker01

docker run -it --name docker03 --volumes-from docker01 7a249dc716f2
#存在docker01数据
[root@b827fdafb258 volume01]# ls
docker01.txt

#docker03创建文件
[root@b827fdafb258 volume01]# touch docker03.txt

#docker01查看数据,同步成功
[root@66c335f24239 volume01]# ls
docker01.txt  docker03.txt
  • 停止docker01并删除
    • 删除docker01,查看docker02和docker03是否还可以访问这个文件
    • 测试依旧可以访问 拷贝的概念
docker rm -f 66c335f24239

#此时docker03查看数据,依旧存在,不会因为父容器kill而丢失数据
[root@b827fdafb258 volume01]# ls
docker01.txt  docker03.txt
  • 容器数据卷一般使用
    • 多个MySQL实现数据共享
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

#这个时候,可以实现两个容器数据同步!

容器数据卷(Volumes)的总结

  • 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
  • 但是一旦持久化到了本地,-v,这个时候,本地的数据是不会删除的。

以上是关于Docker——Docker 容器数据卷(Volumes)的主要内容,如果未能解决你的问题,请参考以下文章

Docker 数据卷

Docker之七:Docker数据卷管理

黑马二Docker容器的数据卷 & Docker应用部署

黑马二Docker容器的数据卷 & Docker应用部署

运维实战 容器部分 Docker数据卷

docker 12 docker容器数据卷