Docker 容器与数据卷

上一篇启动 registry 的时候,用了 -v 和--privileged 参数,本文就讲解这两个参数的含义

privileged 参数

在 CentOS7 中,安全模块会比之前系统版本加强,不安全的行为会先禁止,而目录挂载的情况被默认为不安全的行为,因此我们在启动私服的时候,可能会被禁止,报错 cannot open directory .: Permission denied

在 SELinux 里挂载目录是的被禁止的,如果要开启,一般使用 --privileged=true 命令,扩大容器的权限解决挂载目录没有权限的问题。使用该参数,container 内的 root 拥有真正的 root 权限。否则,container 内的 root 只是外部的一个普通用户权限。

容器卷

Docker 容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自然也就没有了。

之前用的 -v 参数,就是配置容器卷的(volume,简写为 v)。

卷就是目录或文件,存在于一个或多个容器中,由 Docker 挂载到容器,但不属于联合文件系统,因此能够绕过 Union File System 提供一些用于持续存储或共享数据的特性:

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因为 Docker 不会在容器删除时删除其挂载的数据卷

有点类似 Redis 里面的 rdb 和 aof 文件,将容器内的数据保存进宿主机的磁盘中。

卷的特点:

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接实时生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止

实践

运行一个带有容器卷存储功能的容器实例:

$ docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名

默认情况,仓库被创建在容器的 /var/lib/registry​,建议自行用容器卷映射。

例如启动一个 Ubuntu,并创建一个 txt 文件:

$ docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu
$ cd /tmp/docker_data/
$ touch dockerin.txt

如果目录不存在,Docker 会自动创建

然后回到宿主机,可以看到也有文件:

$ ls /tmp/host_data/
dockerin.txt

即使容器 stop 了,宿主机修改文件,容器重启后也会同步数据。

除此之外,也可以用 inspect 命令,查看挂载是否成功:

$ docker ps
CONTAINER ID   IMAGE      COMMAND   CREATED       STATUS          PORTS     NAMES
9bd7aa9d30cd   ubuntu     "bash"    3 minutes ago  Up 3 minutes              u1

$ docker inspect 9bd7aa9d30cd
.............
"Mounts": [
            {
                "Type": "bind",
                "Source": "/tmp/host_data",
                "Destination": "/tmp/docker_data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
.................

随着后续深入的学习,-v 可以配置多个目录共享,例如一个是数据目录,一个是日志目录,一个是配置文件目录等。

读写规则映射

使用了-v 参数后,默认数据是共享的,也就是支持读写(read 和 write,简写为 rw),完整的命令是这样,在容器内目录后面有个 rw:

$ docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw    镜像名

而有时候需要配置只读或者只写,也是可以的。例如设置容器只能读取:

$ docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro   镜像名

这里设置了 ro,也就是 read only,只能读不能写

容器卷之间的继承和共享

有时候可能会有多个容器都使用一个宿主机的目录,此时就可以用继承的方式来完成共享。

在实践之前,可以先删掉所有的容器,方便观察。新建一个 Ubuntu:

$ docker run -it --privileged=true -v /mydocker/u:/tmp --name u1 ubuntu
$ cd /tmp
$ touch u1_data.txt

此时我们想要建立一个和 u1,同样读写规则的 ubuntu,就可以用继承了。命令格式:

docker run -it  --privileged=true --volumes-from 父类  --name u2 ubuntu

该容器和 u1 是共享目录的:

$ docker run -it --privileged=true --volumes-from u1 --name u2 ubuntu
$ cd /tmp
$ ls
u1_data.txt

两个容器可以通过该目录来共享数据

(完)

posted @ 2024-09-10 13:01  peterjxl  阅读(11)  评论(0编辑  收藏  举报