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

 

版权声明:
作者:admin
链接:https://www.chenxie.net/archives/2556.html
来源:蜀小陈
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录