文章目录
Docker 容器数据卷
什么是Docker容器数据卷?
当我们在使用docker容器的时候,会产生一系列的数据文件,这些数据文件在我们关闭docker容器时是会消失的,但是其中产生的部分内容我们是希望能够把它给保存起来另作用途的,Docker将应用与运行环境打包成容器发布,我们希望在运行过程钟产生的部分数据是可以持久化的的,而且容器之间我们希望能够实现数据共享。
通俗地来说,docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。
特点:
- 数据卷可以在容器之间共享或重用数据
- 数据卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
使用容器数据卷
docker run -it -v (主机目录:容器内目录)
[root@VM-8-9-centos centos]# docker run -it -v /root/data/centos/home:/home centos /bin/bash
[root@334f4a042e05 /]# cd home
[root@334f4a042e05 home]# ls
[root@334f4a042e05 home]# touch newFile
[root@334f4a042e05 home]# ls
newFile
# 到主机中对应目录中查看
[root@VM-8-9-centos centos]# ls /root/data/centos/home
newFile
通过docker inspect 334f4a042e05
查看信息可以找到对应容器卷绑定信息
优点:
绑定后,只需要在本地修改文件即可,容器内会自动同步
数据卷命令文档
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
实战:安装MySQL
# 1. 获取镜像
docker pull mysql:5.7
# 2. 运行mysql并且挂载数据卷 配置mysql密码
# 官方配置: docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# -d 后台运行
# -p 端口映射
# -v 卷挂载
# -e 环境配置
# --name 容器名字
[root@VM-8-9-centos home]# docker run -d -p 8688:3306 -v /root/data/mysql/conf:/etc/mysql/conf.d -v /root/data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
远程连接到8688端口数据库 连接成功!
远程测试创建一个数据库,检查文件是否同步
当我们删除mysql01容器
[root@VM-8-9-centos centos]# docker rm -f mysql01
mysql01
[root@VM-8-9-centos centos]# ls /root/data/mysql/data
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 (容器内路径)
# 匿名挂载
[root@VM-8-9-centos centos]# docker run -d -P --name nginx01 -v /etc/nginx nginx
5e103cdc1ddfb63622cda5a28979a559724367ac193d7c6d530f46b613acc0ba
[root@VM-8-9-centos centos]# docker volume ls
DRIVER VOLUME NAME
local 26febf097831005c5fb23037107dbdb5aa47ee47a5491993376e37451bb8d110
local 525d9edea1301e8e0971593de6e03eee7f0c699fbe0a3691c32153a81f3a4934
local 782bcd18b72c2fa03470cdd6251d48ee57919c2f54140516e1489b012ae78e04
local 7665d7edd2d832de44ee136d7c726df9802c00a122776a0315cf5b067bb5e070
local e523c503043e88d48da3f70fe774e784e8c0eab0ee1c2d5295a0e2bcf29339ac
具名挂载
-v (卷名:容器内路径)
# 具名挂载
[root@VM-8-9-centos centos]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
bd427e82fb38b02f1d15ea4d6f7e2644860b307fd61913591f2b313a0d0447cc
[root@VM-8-9-centos centos]# docker volume ls
DRIVER VOLUME NAME
local 26febf097831005c5fb23037107dbdb5aa47ee47a5491993376e37451bb8d110
local 525d9edea1301e8e0971593de6e03eee7f0c699fbe0a3691c32153a81f3a4934
local 782bcd18b72c2fa03470cdd6251d48ee57919c2f54140516e1489b012ae78e04
local 7665d7edd2d832de44ee136d7c726df9802c00a122776a0315cf5b067bb5e070
local e523c503043e88d48da3f70fe774e784e8c0eab0ee1c2d5295a0e2bcf29339ac
local juming-nginx # 卷名被指定了名称
# 查看卷 获取挂载的地址
[root@VM-8-9-centos centos]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2022-03-29T16:10:27+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/www/server/docker/volumes/juming-nginx/_data", # 挂载地址
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定目录的情况下都是在...docker/volumes/
中
通过具名挂载可以方便的找到卷,大多数情况下使用具名挂载
Dockerfile
通过dockerfile脚本生成镜像
-
创建一个dockerfile文件 testDockerfile:
# 指令(大写) + 参数 FROM centos VOLUME ["volume01","volume02"] CMD echo "--end--" CMD /bin/bash # dockerfile的每一个指令相当于镜像的一层
-
创建自定义镜像
[root@VM-8-9-centos dockerfile]# docker build -f /root/data/dockerfile/testDockerfile -t test-centos:1.0 . Sending build context to Docker daemon 2.048kB Step 1/4 : FROM centos ---> 5d0da3dc9764 Step 2/4 : VOLUME ["volume01","volume02"] ---> Running in ed981029fea2 Removing intermediate container ed981029fea2 ---> 62bae0da3650 Step 3/4 : CMD echo "--end--" ---> Running in bf7b91a0baed Removing intermediate container bf7b91a0baed ---> 0c0aac1db8ff Step 4/4 : CMD /bin/bash ---> Running in b7ae17322dda Removing intermediate container b7ae17322dda ---> 53663a8f3bb9 Successfully built 53663a8f3bb9 Successfully tagged test-centos:1.0
-
启动容器
这两个卷一定和外部一一对应!同步![root@da0d8959333d /]# cd volume01 [root@da0d8959333d volume01]# touch newFile
docker inspect 容器id
查看卷地址到对应卷地址查看文件列表,可以看见文件已经同步
[root@VM-8-9-centos _data]# cd /www/server/docker/volumes/01fd1ce93a70a0af363dd9a9e85cf8b33bb085e17c83bdb5ae4a3ee7e49dc4bd/_data [root@VM-8-9-centos _data]# ls newFile
这种方式比较常用,假设构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径
数据卷容器
除了宿主机与容器数据共享之外
还可以通过--volumes-from
实现多个容器之间的数据共享!!
- 启动有容器卷的容器docker01(上一栏中自定义的test-centos镜像)
docker run -it --name docker01 test-centos:1.0
- 启动新的容器docker02并同步docker01的数据卷!
docker run -it --name docker02 --volumes-from docker01 test-centos:1.0
- 在docker02中的同步卷volume01中创建文件docker02-file
touch volume01/docker2-file
- 发现在docker01中的同步卷volume01中也出现了docker02-file
# docker01 [root@6a158f5971c8 /]# ls volume01 docker2-file
实践:实现多个mysql数据共享!
# 运行第一个mysql容器
[root@VM-8-9-centos home]# docker run -d -p 8688:3306 -v /root/data/mysql/conf:/etc/mysql/conf.d -v /root/data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 运行第二个mysql容器并同步mysql01的数据卷!实现数据共享!
[root@VM-8-9-centos home]# docker run -d -p 8687:3306 -v /root/data/mysql/conf:/etc/mysql/conf.d -v /root/data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
扩展
如何确定是具名挂载还是匿名挂载还是指定路径挂载呢?
-v (容器内路径)
匿名挂载-v (卷名:容器内路径)
具名挂载-v (/宿主机路径:容器内路径)
指定路径挂载
RO与RW
可以通过ro与rw变更读写权限(默认rw)
- ro readonly # 只读
- rw readwrite # 可读可写
一旦设置了容器权限,容器对挂载的内容就会有限制!
若权限为ro,说明这个路径只能通过宿主机来操作,容器内部是无法操作的!