- 定义
- 作用:
- 使用数据卷
- MySQL 容器的数据持久化问题
- 获取镜像
- 运行容器, 需要做数据挂载
- 安装启动mysql, 需要配置密码的!
- 官方命令
- 命令实例:
- 启动成功之后, 可以使用客户端工具连接MySQL
- 启动nginx
- -P: 随机映射端口
- 查看所有volume 情况
- 以下都是匿名卷挂载, 因为在-v 时只写了容器内的路径, 没有写容器外的路径
- 通过 -v 容器内路径: ro/rw 来改变读写权限
- ro readonly 只读
- rw readwrite 可读可写
- 一旦设置了容器权限, 容器对我们挂载出来的内容就有限定了
- ro: 只能从宿主机改变, 不能从容器内部改变
- rw: 都能改变
- 数据卷容器
- 启动3 个容器, 通过自定义镜像启动
- 启动第1 个容器, 容器名为docker01
- 在容器中发现有volume01 目录
- 启动第二个容器, 容器名为docker02, 且与docker01 进行数据共享
- —volumes-from: 后面跟需要同步数据的容器名
- 在docker02 创建文件
- 在docker01 查看同步过来的文件
定义
- Docker 理念回顾:
- 将应用和环境打包成一个镜像
- 将数据保存在容器中的后果:
- 如果将容器删除, 数据就会丢失
- 需要将数据持久化, 例如将MySQL 的数据存储在本地
- 解决方案:
- 容器之间有一个数据共享的技术, Docker 容器中产生的数据, 同步到本地
- 以上的实现技术叫做卷技术, 本质上就是目录的挂载, 将容器内的目录挂载到Linux 文件系统中, 如下图所示:

- 总结: **容器的持久化和同步操作, 且容器间的数据共享.**
作用:
- 修改配置, 数据等的数据只需在本地修改即可, 无需进入容器, docker 会自动同步
使用数据卷
方式1: 使用命令来挂载 -v
#命令说明docker run -it -v 主机目录: 容器内目录
例子:
docker run -it -v /home/test:/home centos /bin/bash

进入容器的home 目录创建test.java 文件, 可以发现自动同步到了Linux 宿主机上的/home/test 目录下
- 首先要确保selinux未禁用:
setenforce 0getenforcePermissive
[root@5428417d8963 /]# cd /home[root@5428417d8963 home]# touch test.java

- 首先要确保selinux未禁用:
注: 即使容器关闭, 在宿主机上改变文件内容, 再下次启动容器后, docker 也会同步修改到容器中
方式2: 通过Dockerfile 生成镜像启动自动挂载
运行容器, 需要做数据挂载
安装启动mysql, 需要配置密码的!
官方命令
docker run —name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
命令实例:
-d: 后端运行 -p: 端口映射 -v: 数据卷挂载 -e: 环境配置 —name: 容器名字 docker run -d -p 3310:3306 -v /home/mysql/conf:/ect/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 —name mysql01 mysql:5.7
启动成功之后, 可以使用客户端工具连接MySQL
- 这时再创建手动创建一个数据库, 可以发现宿主机上的映射目录中出现了test 文件夹<br />- 注: **即使删除MySQL 容器, 宿主机上的数据也不会随容器的删除而删除, 实现了数据的持久化**<a name="kF2oO"></a># 名称- 具名挂载:- 通过-v 卷名:容器内路径来指定卷名, 例子如下```shell#通过-v 卷名:容器内路径来指定卷名docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx nginx9d9a9d184971432ff31e6e767c0631013515e4c0da2cc373013097480ef4952a#查看数据卷列表docker volume lsDRIVER VOLUME NAMElocal 7f5e2029289f9601887597fb8f8c5d4b81cb9e8f89e746e4cd50d5d74c692bbelocal b118ffbba045826181f85030c3741a0afaf539d82b736a7d64d2dffa8e16f721local bf2950ea03c1f06f0e8eb29bca1ee856ac27212564c2cb6e48b8ce5bc95d3835local juming-nginx
查看所有volume 情况
以下都是匿名卷挂载, 因为在-v 时只写了容器内的路径, 没有写容器外的路径
docker volume ls DRIVER VOLUME NAME local 7f5e2029289f9601887597fb8f8c5d4b81cb9e8f89e746e4cd50d5d74c692bbe local b118ffbba045826181f85030c3741a0afaf539d82b736a7d64d2dffa8e16f721 local bf2950ea03c1f06f0e8eb29bca1ee856ac27212564c2cb6e48b8ce5bc95d3835
- 指定路径挂载- -v /宿主机路径:容器内路径<a name="LKDuF"></a># 查看数据卷的映射目录- 命令:```shell#命令模板docker volume inspect 卷名#命令实例docker volume inspect juming-nginx
#查看上例中nginx 挂载的数据卷的映射目录docker volume inspect juming-nginx[{"Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data","Name": "juming-nginx","Options": {},"Scope": "local"}]
- 注: 所有的docker 容器内的卷, 没有指定目录的情况下都是在 /var/lib/docker/volumes/xxx/_data 目录

- 通过具名挂载, 可以方便的找到具体的数据卷, 大多数情况下使用具名挂载
一旦设置了容器权限, 容器对我们挂载出来的内容就有限定了
docker run -d -P —name nginx02 -v juming-nginx:/ect/nginx:ro nginx docker run -d -P —name nginx02 -v juming-nginx:/ect/nginx:rw nginx
ro: 只能从宿主机改变, 不能从容器内部改变
rw: 都能改变
<a name="DsGyj"></a># 初识Dockerfile- 定义:- 用来构建Docker 镜像的构建文件- 本质:- 命令脚本, 通过这本脚本可以生成镜像, 镜像是一层一层的, 脚本是一个个的命令, 每个命令就是一层- 测试:```shell#创建dockerfile 文件, 名字可以随机, 建议使用dockerfile 即可#以下是文件中的内容, 指令(大写) 参数FROM centos#这里将volume01 和volume02 两个目录挂载到容器VOLUME ["volume01", "volume02"]CMD echo "----end----"CMD /bin/bash#这里的每个命令, 可以理解为镜像的一层
# 通过build 命令生成镜像#-f: 后面跟dockerfile 路径#-t: 后面跟镜像名:版本#最后的.: 表示生成在当前目录下docker build -f ./dockerfile1 -t flm/centos:1.0 .#查看本地镜像docker images#发现有flm/centos 根据dockerfile 生成的镜像REPOSITORY TAG IMAGE ID CREATED SIZEflm/centos 1.0 2a2883c6abed 27 seconds ago 231 MBtomcat-2 1.0 6fd68ca2420f 7 hours ago 684 MBdocker.io/tomcat 9.0 df8f7f1177ca 3 days ago 680 MBdocker.io/tomcat latest 413407dddb5e 3 days ago 680 MBdocker.io/mysql 5.7 0712d5dc1b14 4 days ago 448 MBdocker.io/mysql 8.0 d1dc36cf8d9e 4 days ago 519 MBdocker.io/mysql latest d1dc36cf8d9e 4 days ago 519 MBdocker.io/redis latest f1b6973564e9 4 days ago 113 MBdocker.io/nginx latest c316d5a335a5 5 days ago 142 MBdocker.io/hello-world latest feb5d9fea6a5 4 months ago 13.3 kBdocker.io/centos latest 5d0da3dc9764 4 months ago 231 MBdocker.io/portainer/portainer latest 580c0e4e98b0 10 months ago 79.1 MBdocker.io/elasticsearch 7.6.2 f29a1ee41030 22 months ago 791 MB#启动镜像docker run -it 2a2883c6abed#可以看到容器中存在两个目录volume01 和volume02, 且这两个目录就是在生成镜像的时候自动挂载的数据卷的目录#因为挂载了数据卷, 说明外部一定有对应的目录ls -ltotal 0lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bindrwxr-xr-x. 5 root root 360 Jan 31 14:03 devdrwxr-xr-x. 1 root root 66 Jan 31 14:03 etcdrwxr-xr-x. 2 root root 6 Nov 3 2020 homelrwxrwxrwx. 1 root root 7 Nov 3 2020 lib -> usr/liblrwxrwxrwx. 1 root root 9 Nov 3 2020 lib64 -> usr/lib64drwx------. 2 root root 6 Sep 15 14:17 lost+founddrwxr-xr-x. 2 root root 6 Nov 3 2020 mediadrwxr-xr-x. 2 root root 6 Nov 3 2020 mntdrwxr-xr-x. 2 root root 6 Nov 3 2020 optdr-xr-xr-x. 236 root root 0 Jan 31 14:03 procdr-xr-x---. 2 root root 162 Sep 15 14:17 rootdrwxr-xr-x. 1 root root 21 Jan 31 14:03 runlrwxrwxrwx. 1 root root 8 Nov 3 2020 sbin -> usr/sbindrwxr-xr-x. 2 root root 6 Nov 3 2020 srvdr-xr-xr-x. 13 root root 0 Jan 31 06:44 sysdrwxrwxrwt. 7 root root 171 Sep 15 14:17 tmpdrwxr-xr-x. 12 root root 144 Sep 15 14:17 usrdrwxr-xr-x. 20 root root 262 Sep 15 14:17 vardrwxr-xr-x. 2 root root 6 Jan 31 14:03 volume01drwxr-xr-x. 2 root root 6 Jan 31 14:03 volume02#通过inspect 或者volume ls + volume inspect 卷ID 命令来查看数据卷的映射目录#这边选择第一种..."Mounts": [{"Type": "volume","Name": "3fdc6a39f02de016a8beda5ede1bf64be701d20c9f29dc124750c8e738ae472d","Source": "/var/lib/docker/volumes/3fdc6a39f02de016a8beda5ede1bf64be701d20c9f29dc124750c8e738ae472d/_data","Destination": "volume02","Driver": "local","Mode": "","RW": true,"Propagation": ""},{"Type": "volume","Name": "ffa8017d3624850d8a355778266f0363e4a056aebfcebe365f71d071e5c9f254","Source": "/var/lib/docker/volumes/ffa8017d3624850d8a355778266f0363e4a056aebfcebe365f71d071e5c9f254/_data","Destination": "volume01","Driver": "local","Mode": "","RW": true,"Propagation": ""}]...#进入容器的volume01 目录, 创建文件, 观察宿主机中的映射目录, 可以发现刚才在容器中创建的文件自动同步到了宿主机上[root@bf805ada549c volume01]# touch container.txt[root@localhost _data]# ls -ltotal 0-rw-r--r--. 1 root root 0 Jan 31 09:15 container.txt
- 注: 如果在构建镜像的时候没有挂载卷, 则需要手动挂载, 使用-v 卷名:容器内路径
数据卷容器
- 定义:
- 实现两个或者多个容器之间的数据共享

使用命令:
run 命令中的参数: --volumes-from 容器名
测试: ```shell
启动3 个容器, 通过自定义镜像启动
启动第1 个容器, 容器名为docker01
docker run -it —name docker01 2a2883c6abed
在容器中发现有volume01 目录
[root@00e5f74ef4c3 /]# ls -l total 0 lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x. 5 root root 360 Jan 31 14:32 dev drwxr-xr-x. 1 root root 66 Jan 31 14:32 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 Sep 15 14:17 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. 238 root root 0 Jan 31 14:32 proc dr-xr-x—-. 2 root root 162 Sep 15 14:17 root drwxr-xr-x. 1 root root 21 Jan 31 14:32 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 Jan 31 06:44 sys drwxrwxrwt. 7 root root 171 Sep 15 14:17 tmp drwxr-xr-x. 12 root root 144 Sep 15 14:17 usr drwxr-xr-x. 20 root root 262 Sep 15 14:17 var drwxr-xr-x. 2 root root 6 Jan 31 14:30 volume01 drwxr-xr-x. 2 root root 6 Jan 31 14:30 volume02 [root@00e5f74ef4c3 /]# cd ./volume01
启动第二个容器, 容器名为docker02, 且与docker01 进行数据共享
—volumes-from: 后面跟需要同步数据的容器名
docker run -it —name docker02 —volumes-from docker01 2a2883c6abed
在docker02 创建文件
[root@localhost home]# docker attach ac106f5bbb4b [root@ac106f5bbb4b /]# cd /volume01 [root@ac106f5bbb4b volume01]# touch docker01
在docker01 查看同步过来的文件
[root@00e5f74ef4c3 volume01]# ls -l total 0 -rw-r—r—. 1 root root 0 Jan 31 14:33 docker01
- 注:- **docker01 叫做数据卷容器 (被同步的容器), 即使再创建容器将docker01 挂载上, 一样可以实现数据同步**- **即使删除docker01, 其他容器中的数据依然存在**- **数据卷容器的数据同步是一个双向拷贝的概念, 可以理解为各个容器的数据进行互相备份 (拷贝的过程), 即使删除其中一个, 也不会因为这一个容器被删除了, 其他容器的数据也不会丢失**- **容器之间配置信息的传递, 数据卷容器的生命周期一直持续到没有容器使用为止, 但是一旦持久化到了本地, 这个时候, 本地的数据是不会删除的**<a name="IrXZ3"></a># 多个MySQL 实现数据共享```shell#启动第一个MySQLdocker run -d -p 3310:3306 -v /home/mysql/conf:/ect/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7#启动第二个MySQL 进行数据卷挂载docker run -d -p 3310:3306 -v /home/mysql/conf:/ect/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
