theboyaply
theboyaply
发布于 2020-03-11 / 513 阅读
0
0

Docker 数据管理

docker 容器运行时所产生的数据都会随 docker 容器删除而被删除,很多时候我们希望将容器中产生的数据保存下来,比如日志文件等。这时候可以通过捆绑挂载(bind-mount)与数据卷(volume)两种方式将容器内部数据挂载到容器的宿主机中。不管是数据卷还是捆绑挂载,都可以和本机共享目录。

docker 中可使用的指令有两种 -v--mount,这两种指令的演示下面都有。

捆绑挂载

捆绑挂载,我理解就是直接指定宿主机的 A 目录与容器的 B 目录进行捆绑。

demo-server 镜像可自己定制,参考 制作镜像示例

# 不进行宿主机目录挂载
docker run -d -p 80:8080 --name demo1 demo-server

# 使用 -v 将容器的 /var/lib 目录挂载到宿主机的 /dockerDir/demo2
docker run -d \
-p 81:8080 \
--name demo2 \
-v /dockerDir/demo2:/var/lib \
demo-server

# 使用 --mount 将容器的 /var/lib 目录挂载到宿主机的 /dockerDir/demo3
docker run -d \
-p 82:8080 \
--name demo3 \
--mount type=bind,source=/dockerDir/demo3,target=/var/lib \
demo-server

# --mount 还可以指定挂载目录的读写权限,默认为读写,使用 readonly 指定为只读
--mount type=bind,source=/dockerDir/demo3,target=/var/lib,readonly \

-v --mount的区别:

-v

  • 只能挂载目录
  • 挂载的宿主机目录不存在会自动创建

--mount

  • 可以挂载目录和文件
  • 挂载的宿主机目录必须存在,否则会报错
  • 可以指定读写权限,通过 readonly指定为只读

启动了上面三个容器之后,我们可以通过 docker inspect "容器ID或名称" 查看容器的详细信息,其中的 Mounts 属性就是挂载信息。

因为 demo1 没有挂载到宿主机目录,所以 Mounts 信息为空

# demo1
"Mounts": []

# demo2
"Mounts": [
            {
                "Type": "bind",
                "Source": "/dockerDir/demo2",
                "Destination": "/var/lib",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ]

# demo3
"Mounts": [
            {
                "Type": "bind",
                "Source": "/dockerDir/demo3",
                "Destination": "/var/lib",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ]

数据卷 (volume)

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 数据卷 的修改会立马生效
  • 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 数据卷

数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。

下面是 volume 常用命令:

# 查看所有volume
[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME

# 创建一个名为demo-volume的数据卷
[root@localhost ~]# docker volume create demo-volume
demo-volume

[root@localhost ~]# docker volume ls
DRIVER              VOLUME NAME
local               demo-volume

# 查看demo-volume详细信息
[root@localhost ~]# docker volume inspect demo-volume
[
    {
        "CreatedAt": "2020-03-11T10:33:22+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/demo-volume/_data",
        "Name": "demo-volume",
        "Options": {},
        "Scope": "local"
    }
]

# 删除volume
[root@localhost demo3]# docker volume rm demo-volume
demo-volume

# 删除所有无主volume,即没有被容器使用到的
docker volume prune

根据详细信息中 Mountpoint 属性得知,我们创建的数据卷在宿主机中的目录为 /var/lib/docker/volumes/demo-volume/_data ,所有创建的数据卷都会在 /var/lib/docker/volumes 这个目录下。也就是说,我们使用数据卷挂载容器目录,实际就是将容器的某个目录挂载到宿主机的这个目录中。

有了数据卷之后,我们可以使用下面的命令将容器目录挂载起来:

# 使用 -v 
docker run -d \
-p 81:8080 \
--name demo2 \
-v demo-volume:/var/lib \
demo-server

# 使用 --mount
docker run -d \
-p 81:8080 \
--name demo3 \
--mount source=demo-volume,target=/var/lib \
demo-server

-- end --


评论