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 文件,将容器内的数据保存进宿主机的磁盘中。
卷的特点:
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接实时生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
实践
运行一个带有容器卷存储功能的容器实例:
$ 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
两个容器可以通过该目录来共享数据
(完)