Docker容器数据卷
简介
在实际的Docker使用中,启动一个容器往往在容器内都会产生各种数据,比如启动一个mysql容器,所有的数据都是在容器内部的,如果哪天不小心将这个mysql容器删掉了,这也就意味着所有数据都将丢失,如何解决这一问题,我们便可以用到Docker的容器卷功能。在启动一个容器的时候可以使用 -v 参数指定一个宿主机上的目录和一个容器内的目录进行一一映射,则容器内的数据就直接写到宿主机上,宿主机上的修改目录里的内容也可以同时作用于容器内部,由此解决数据存储的问题。
映射容器卷
命令语法:
docker run -it -v 宿主机目录:容器目录 [镜像名/镜像ID]
示例:
如下,在启动一个 ubuntu 容器时将宿主机上的 /data/mydata 目录挂载到容器里的 /data 目录,在宿主机修改 /data/mydata 目录下的内容,容器内 /data 同步生效。
docker run -it -v /data/mydata:/data ubuntu
注:无论宿主机还是容器内,当指定的目录不存在时会自动创建。
权限控制
在启动容器进行容器卷挂载的时候,可以对挂载的目录进行权限控制,默认未指定时为 rw 表示可读可写,如需指定权限如下:
指定权限为 ro ,表示read only
docker run -it -v 宿主机目录:容器目录:ro 镜像ID
示例:
docker run -it -v /data/mydata3:/data3:ro ubuntu
容器卷之间的继承和共享
容器卷之间是可以继承和共享的,多个容器可以指定使用另一个容器挂载的同一个宿主机目录,同一个宿主机目录可以共享给多个容器。
示例:
现有 宿主机目录:/mydocker/u
1. 首先用ubuntu镜像启动一个容器名叫u1(父容器),将宿主机的 /mydocker/u 挂载到 容器内的 /tmp 目录
docker run -it -v /mydocker/u:/tmp --name u1 ubuntu
2. 再启动一个容器u2,通过使用 --volumes-from 参数来指定要继承哪个容器(父容器)
这里指定 继承 --volumes-from u1
docker run -it --volumes-from u1 --name u2 ubuntu
测试:
在宿主机 /mydocker/u 目录下随便创建一个文件,都可以在 u1, u2 容器 /tmp 目录下看到;
在 u1, u2 容器 /tmp 目录下随便创建一个文件,也可以在 宿主机 /mydocker/u 目录下看到。
删除测试:将 u1 父容器停止或删除,u2 都依然正常
匿名和具名挂载
三种挂载方式:
-v 宿主机路径:容器内路径 # 指定路径挂载 -v 容器内路径 # 匿名挂载 -v 卷名:容器内路径 # 具名挂载
匿名挂载
-v 只写了一个容器内的路径,没有写宿主机的路径。如:-v /etc/nginx
# 启动nginx容器 docker run -d --name nginx-1 -v /etc/nginx nginx # 通过docker volume ls 看到的这些 VOLUME NAME 都是一些加密的名称,并非我们所能识别的卷名称 [root@localhost ~]# docker volume ls DRIVER VOLUME NAME local 2aef557e28f539a866ed01c48ab8df8db0a85ef268293d7554c5b82fe9696b54 local 7b44710a83e859c7964388eaaaaac4e97d5e201d3bfe278347f10fc133dd5341 local 19f999ef10be72f59a5d59c89aa3873765e2c89875c4e9fc145e066bc5d15c35 .....
具名挂载
-v 之后写了指定的具体名字的卷名,如:-v juming_nginx:/etc/nginx
# 启动nginx容器 docker run -d --name nginx-2 -v juming_nginx:/etc/nginx nginx # 通过docker volume ls 就可以看到 VOLUME NAME 部分我们起了具体卷名称的卷 juming_nginx [root@localhost ~]# docker volume ls DRIVER VOLUME NAME ..... local juming_nginx
# 查看这个 juming_nginx 卷在哪个目录 [root@localhost ~]# docker volume inspect juming_nginx [ { "CreatedAt": "2022-03-04T12:58:55+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/juming_nginx/_data", "Name": "juming_nginx", "Options": null, "Scope": "local" } ]
Dockerfile 中的容器卷使用
Dockerfile
FROM centos # 匿名挂载 VOLUME ["volume01", "volume02"] RUN echo "---- ok ----" CMD /bin/bash
构建镜像:
# 构建镜像 [root@localhost test_vol]# docker build -t alex/centos:v1.0 . # 查看镜像 [root@localhost test_vol]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE alex/centos v1.0 62d862b81f82 About a minute ago 231MB
运行容器:
# 启动容器 [root@localhost test_vol]# docker run -it alex/centos:v1.0 [root@08a596b46960 /]# ls -l total 0 lrwxrwxrwx. 1 root root 7 Nov 3 2020 bin -> usr/bin drwxr-xr-x. 5 root root 360 Mar 4 05:30 dev drwxr-xr-x. 1 root root 66 Mar 4 05:30 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. 150 root root 0 Mar 4 05:30 proc dr-xr-x---. 2 root root 162 Sep 15 14:17 root drwxr-xr-x. 11 root root 163 Sep 15 14:17 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 Mar 2 13:49 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 Mar 4 05:27 volume01 # volume01 目录,与宿主机相应目录绑定 drwxr-xr-x. 2 root root 6 Mar 4 05:27 volume02 # volume02 目录,与宿主机相应目录绑定
查看绑定的目录:
[root@localhost test_vol]# docker inspect 08a596b46960 ..... "Mounts": [ { "Type": "volume", "Name": "b9b2c0612281f7a5da13dc759860e8d5dd1dbac6a3bda02553f27c64061b0832", "Source": "/var/lib/docker/volumes/b9b2c0612281f7a5da13dc759860e8d5dd1dbac6a3bda02553f27c64061b0832/_data", "Destination": "volume01", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "7819940ccb699d1ca5ffdf44b67cb5ad7180c3e9f4e3d66de9ca744183c945a5", "Source": "/var/lib/docker/volumes/7819940ccb699d1ca5ffdf44b67cb5ad7180c3e9f4e3d66de9ca744183c945a5/_data", "Destination": "volume02", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], ......
容器卷的坑
容器卷记得加入: --privileged=true ,一般情况下不用加。
为什么?
Docker挂载主机目录访问如果出现 cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个--privileged=true 参数即可
如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为。在SELinux里面挂载目录被禁止掉了,如果要开启,我们一般使用--privileged=true 命令。扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则 container内的root只是外部的一个普通用户权限。
如:
docker run -it --privileged=true -v /data/mydata:/data ubuntu
共有 0 条评论