Docker从零部署应用08:Docker之容器数据卷如何迁移共享管理

355 阅读5分钟

1、什么是数据卷

容器是基于镜像创建的,进入容器之后的,如果有文件和数据写入,都会保存在容器内。一旦容器删除,数据和文件都将不会存在。除非我们把这些数据事先拷贝下来或者基于当前容器制作新的镜像。那么如何持久化保存数据呢?

如果需要在宿主机频繁修改文件内容,并且再通过 docker cp 命令复制到容器内,也是很不方便;

如果多个容器需要共享数据文件,一个个复制到对应的容器内,也是很不方便。

如果容器被误删,文件数据被误删,也需要有容灾的方案。

所以数据卷是一个很好的选择,数据卷存在在宿主机上,然后挂载到各个容器,即使容器销毁,数据卷还是存在于宿主机器上。同一个数据卷可共享挂载到多个容器上。

查看数据卷

[root@ centos]# docker volume --help
Usage:	docker volume COMMAND
Manage volumes
Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes
Run 'docker volume COMMAND --help' for more information on a command.
# 列出当前机器上的所有数据卷
[root@ centos]# docker volume ls
DRIVER              VOLUME NAME
local               7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51
local               d2ec25d98838db66c333856a83dffba9e0d78b8f4da979432c9e8cc93f05f4c9
# 审查数据卷相关信息
[root@ centos]# docker volume inspect 7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51
[
    {
        "CreatedAt": "2020-12-04T10:40:47+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51/_data",
        "Name": "7319fd1f7df530f90925fea0b81308f03829e4b297390018e5b3b29aadd4ba51",
        "Options": null,
        "Scope": "local"
    }
]

2、挂载点

[root@ centos]# docker run -itd -v /docker/volumes/centos/project:/home/project centos /bin/bash
# docker run -v 宿主机目录:容器内目录 

其中的 -v 标记,在容器中设置了一个挂载点 /home/project(就是容器中的一个目录),并将主机上的 /docker/volumes/centos/project 目录中的内容关联到 /home/project下。

这样在容器中对 /home/project目录下的操作,还是在主机上对/docker/volumes/centos/project的操作,都是完全实时同步的,因为这两个目录实际都是指向主机目录。

假设没有绑定宿主机

[root@ centos]# docker run -itd --name centos-test -v /home/project centos /bin/bash
[root@ centos]# docker inspect centos-test | grep "Mounts" -A8
        "Mounts": [
            {
                "Type": "volume",
                "Name": "81571578dfd46b845752a476d2ea974a3c6f65530de0c12a09677d80c115464e",
                "Source": "/var/lib/docker/volumes/81571578dfd46b845752a476d2ea974a3c6f65530de0c12a09677d80c115464e/_data",
                "Destination": "/home/project",
                "Driver": "local",
                "Mode": "",
                "RW": true,

上面-v的标记只设置了容器的挂载点,并没有指定关联的主机目录。这时docker会自动绑定主机上的一个目录;

上面 Mounts下的每条信息记录了容器上一个挂载点的信息,Destination 值是容器的挂载点,Source值是对应的主机目录。

可以看出这种方式对应的主机目录是自动创建的,其目的不是让在主机上修改,而是让多个容器共享。

进入主机目录,新增文件,并测试容器内是否同步

[root@ centos]# cd /var/lib/docker/volumes/81571578dfd46b845752a476d2ea974a3c6f65530de0c12a09677d80c115464e/_data
[root@ _data]# ll
总用量 0
[root@ _data]# echo "test" > test.txt
[root@ _data]# ll
总用量 4
-rw-r--r-- 1 root root 5 12月 15 15:34 test.txt
# 进入容器
[root@ centos]# docker exec -it centos-test /bin/bash
[root@0d8c9d2904d8 /]# ls /home/project/
test.txt

由此看出同步依然正常。

3、Dockfile创建共享数据卷

基于ubuntu镜像创建。

Dockerfile

# volume container
from ubuntu
MAINTAINER Alex
VOLUME ["/volumes"]

生成镜像

[root@ /build]# docker build -t myvolume .
# 运行容器
[root@ /build]# docker run -itd --name volume-test -v /docker/volumes:/volumes  myvolume /bin/bash
# 进入容器
[root@ /build]# docker exec -it volume-test /bin/bash
root@42adea7beae7:/# ll volumes
total 0
drwxr-xr-x 6 root root 59 Dec 15 07:54 ./
drwxr-xr-x 1 root root 33 Dec 15 08:08 ../
drwxr-xr-x 2 root root 72 Dec 15 08:08 build/
drwxr-xr-x 4 root root 35 Dec 15 06:16 centos/
drwxr-xr-x 4 root root 30 Dec  4 08:49 mysql/
drwxr-xr-x 6 root root 53 Dec 15 06:16 nginx/

退出容器后

[root@ build]# docker inspect volume-test | grep "Mounts" -A8
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/docker/volumes",
                "Destination": "/volumes",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }

可以看到挂载点的信息

目前我们已经有了一个数据卷容器,在 docker run中使用 --volumes-from标记,可以让其他容器共享当前共享卷volume-test/volumes

[root@ build]# docker run --name nginx-test -d -p 9999:80 --volumes-from volume-test -v /docker/volumes/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /docker/volumes/nginx/html:/usr/share/nginx/html -v /docker/volumes/nginx/logs:/var/log/nginx nginx
# 进入容器
[root@ centos]# docker exec -it nginx-test /bin/bash
root@1168a85a4bf3:/# ll volumes/
total 0
drwxr-xr-x 2 root root 72 Dec 15 08:08 build
drwxr-xr-x 4 root root 35 Dec 15 06:16 centos
drwxr-xr-x 4 root root 30 Dec  4 08:49 mysql
drwxr-xr-x 6 root root 53 Dec 15 06:16 nginx

目录中内容是共享的,任何一个容器修改了内容,别的容器都能获取到。