• docker的数据卷、docker数据持久化


    前言

    环境:centos7.9 docker version 20.10.14
    本篇我们来介绍docker的数据卷,数据卷是用于实现docker数据的持久化。

    docker数据持久化的2种方式

    使用docker过程中,我们需要持久化容器中产生的数据,以及容器与容器之间、容器与主机之前进行数据共享、备份等操作,这里就需要到容器的数据持久化管理。 docker的数据持久化管理目前提供如下两种方式:

    1、数据卷 data volumes
    2、数据卷容器 data volumes containers
    
    • 1
    • 2

    数据卷 bind mount ,即-v参数

    数据卷:数据卷其实就是一个目录或文件,类似linux下对目录或文件进行mount挂载操作,即在宿主机和容器之间建立一个或多个目录(文件亦可)来相互映射文件,其具有如下特点:
    (1) 数据卷可以在容器之间进行共享和重用,即多个容器可以挂载同一个目录
    (2)对数据卷的更改会立即生效,即对宿主机目录下的文件的修改会立即反应到容器的挂载点目录文件
    (3)对数据卷的更新不会影响到镜像 (镜像只读)
    (4)卷会一直存在,即使容器被删除,即宿主机目录不会因为容器的删除而删除宿主机目录

    注意:
    (1)删除容器的时候,数据卷不会删除。如果要删除容器的时候同时删除数据卷,需加上-v参数。比如: docker rm os456 -v /homedata
    (2)默认数据卷挂载以后文件的权限为rw,如需单独设置,可以容器数据卷后边设置:ro只读

    docker run -v参数语法:

     -v是--volume的缩写,表示绑定挂载卷,语法格式:
    -v <host_path>:<container_path>[:rw/ro]
    <host_path>是宿主机的目录或单个文件
    <container_path>是容器的目录或单个文件
    rw/ro 表示挂载后容器的数据读写权限,rw表示读写,ro表示数据只读,不写默认就是rw读写权限
    
    • 1
    • 2
    • 3
    • 4
    • 5

    演示示例:

    #使用数据卷挂载宿主机目录到容器中去
    mkdir /root/nginx/html -p
    docker run -d --name nginx -p 8081:80 -v /root/nginx/html:/usr/share/nginx/html nginx:latest
    
    #使用数据卷挂载但个文件到容器中去
    docker run -d --name nginx -p 8081:80 -v /root/nginx/html/index.html:/usr/share/nginx/html/index.html nginx:latest
    #综合案例
    mkdir -p /root/nginx/html && echo "good" >> /root/nginx/html/index.html
    mkdir -p /root/nginx/logs -p 
    docker run -d --name nginx2 -p 8081:80 -v /root/nginx/html/index.html:/usr/share/nginx/html/index.html nginx:latest
    
    docker inspect nginx
      "Mounts": [
                {
                    "Type": "bind",		#可以看到类型是bind,所以没有产生volume
                    "Source": "/root/nginx/html",
                    "Destination": "/usr/share/nginx/html",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    匿名数据卷 docker manager volume

    使用-v参数时可以不指定部分,只需指定容器的挂载点即可,如:-v ,container_path必须是一个容器目录,不能是单个文件了,数据权限不能设置,均为读写权限。这时docker会自动创建一个匿名的数据卷,这个匿名数据卷的名字是自动生成的一个很长串的字符。使用docker volume ls命令可以看到这个数据卷的名称,我们称这种卷为匿名数据卷。

    演示示例:

    使用-v挂载匿名卷,docker会默认给我们在宿主机上找一个目录进行挂载
    docker run -d --name nginx2 -p 8081:80 -v /usr/share/nginx/html -v /var/log/nginx  nginx:latest
    
    #查看容器的详细信息就可以发现docker将我们的卷挂载到哪里了
    [root@docker ~]# docker inspect  nginx2
    "Mounts": [
                {
                    "Type": "volume",	#类型是volume
                    "Name": "8d1d766c65d3b3cddafd20f25d",
                    "Source": "/var/lib/docker/volumes/8d1d766c65d3b3cddafd20f25d/_data", 
                    #上面一行,可见,docker将卷挂到了这里,这个很长串的ID其实就是数据卷的名称
                    "Destination": "/usr/share/nginx/html",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                },
                {
                    "Type": "volume", #类型是volume
                    "Name": "ef17aa81669f4ef7704182061164bce",
                    "Source": "/var/lib/docker/volumes/ef17aa81669f4ef7704182061164bce/_data",
                    "Destination": "/var/log/nginx",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
            ],
    [root@docker ~]# ls -l /var/lib/docker/volumes/8d1d766c65d3b3cddafd20f25d/_data/
    total 8
    -rw-r--r--. 1 root root 497 Dec 28  2021 50x.html
    -rw-r--r--. 1 root root 615 Dec 28  2021 index.html
    # 所以我们修改/var/lib/docker/volumes/8d1d766c65d3b3cddafd20f25d/_data/下的index.html文件就能实现容器的nginx页面的变更
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    -v参数和匿名卷的区别

    不同点bind mountdocker manager volume
    volume位置可挂载宿主机任意位置的目录或文件仅挂载宿主机固定位置的目录,目录一般为/var/lib/docker/volumes/xxx/_data/
    对容器挂载点影响挂载后容器内的挂载点目录会被覆盖,如果此时宿主机目录上没有文件,那么容器的挂载点也没有文件使用匿名数据卷时,如果volume是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到volume中,但是如果volume中已经有内容,则会将container中的目录覆盖
    是否支持单文件支持挂载目录或单文件仅支持挂载目录
    权限控制权限默认rw,可设置为ro只能默认rw
    移植性移植性弱,与宿主机路径绑定移植性强,无需指定宿主机目录

    匿名数据卷 docker manager volume
    使用-v参数时不指定部分,只需指定容器的挂载点即可,如:-v ,这是docker默认会创建目录,如/var/lib/docker/volumes/8d1d766c65d3b3cddafd20f25dcaf304a96b9c89d005d30226a7b815a6b5ecbf/_data/目录,这个目录就是容器持久化数据的目录,这一串很长的ID就是卷名,docker自动帮我们生成的,通过docker volume ls命令可以查看卷。

    注意:
    使用数据卷 bind mount ,即-v参数,挂载后容器内的挂载点目录会被覆盖,如果此时宿主机目录上没有文件,那么容器的挂载点也没有文件;
    使用匿名数据卷时,如果volume是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到volume中,但是如果volume中已经有内容,则会将container中的目录覆盖。

    docker volume 命令的使用

    [root@docker ~]#  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
    
    #列出全部的volume
    docker volume ls
    #查看指定名字的volume的详细信息
    docker volume inspect a0dc63aae530f4070bb34e1c5331319c93a97f3727e6cf60415b7847010dcaf8
    #移除全部未使用的本地volume
    docker volume  prune
    #删除指定的volume
    docker volume  rm a0dc63aae530f4070bb34e1c5331319c93a97f3727e6cf60415b7847010dcaf8
    
    示例:
    #创建一个数据卷,名称叫做nginx
    [root@docker ~]# docker volume create nginx
    nginx
    [root@docker ~]# docker volume ls | grep nginx
    local     nginx
    [root@docker ~]# docker volume inspect  nginx
    [
        {
            "CreatedAt": "2023-08-27T14:40:43+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/nginx/_data",
            "Name": "nginx",
            "Options": {},
            "Scope": "local"
        }
    ]
    
    #容器使用数据卷,-v参数时加上卷名即可
    [root@docker ~]# docker run -d --name nginx -p 8081:80 -v nginx:/usr/share/nginx/html  nginx:latest
    57022b423ec03bdb1a7a178544d422b262daa1b2861ba8a509a20962ed3051cf
    [root@docker ~]# docker inspect nginx 
      "Mounts": [
                {
                    "Type": "volume",
                    "Name": "nginx",
                    "Source": "/var/lib/docker/volumes/nginx/_data",
                    "Destination": "/usr/share/nginx/html",
                    "Driver": "local",
                    "Mode": "z",
                    "RW": true,
                    "Propagation": ""
                }
    #可以看到,nginx已经使用了nginx数据卷
    #注意
    #使用数据卷 bind mount ,-v参数,不会产生volume,如下:
    docker run -d --name nginx -p 8081:80 -v /root/nginx/html:/usr/share/nginx/html  nginx:latest
    docker inspect nginx
      "Mounts": [
                {
                    "Type": "bind",		#可以看到类型是bind,所以没有产生volume
                    "Source": "/root/nginx/html",
                    "Destination": "/usr/share/nginx/html",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    数据卷容器

    所谓数据卷容器,其实就是一个为其他容器提供volume的容器,即包含数据的容器,然后其他多个容器可以通过--volumes-from 数据卷容器名参数来挂载数据卷容器,从而实现多个容器共享同一份数据。

    1、不使用数据卷容器之前,多个容器共享相同的数据,只需使用-v参数挂载同一个宿主机目录即可,如下实现:

    docker run -d --name nginx1 -p 8081:80 -v /root/nginx/html/:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx2 -p 8082:80 -v /root/nginx/html/:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx3 -p 8083:80 -v /root/nginx/html/:/usr/share/nginx/html nginx:latest
    echo "good" >>/root/nginx/html/index.html
    curl  127.0.0.1:8081
    good
    curl  127.0.0.1:8082
    good
    curl  127.0.0.1:8083
    good
    
    #以上使用的是bind mount的形式挂载,当然也可以手动创建一个volume,如下:
    docker volume create nginx
    docker volume inspect  nginx
    [
        {
            "CreatedAt": "2023-08-27T14:40:43+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/nginx/_data",
            "Name": "nginx",
            "Options": {},
            "Scope": "local"
        }
    ]
    
    echo "good" >>/var/lib/docker/volumes/nginx/_data/index.html
    docker run -d --name nginx11 -p 8001:80 -v nginx:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx12 -p 8002:80 -v nginx:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx13 -p 8003:80 -v nginx:/usr/share/nginx/html nginx:latest
    curl  127.0.0.1:8001
    I am good
    curl  127.0.0.1:8002
    I am good
    curl  127.0.0.1:8003
    I am good
    
    #以上就说明多个容器共享了相同的数据
    #注意:不能使用匿名卷,匿名卷会自动创建volume,那么多个容器都各自创建自己的匿名卷这样做不到数据共享了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    2、使用数据卷容器之后,多个容器共享相同的数据,如下实现:

    #创建一个数据卷容器,名称叫做nginx-data,数据卷容器可以不用run,其只是提供数据而已
    echo "I am good man" >/root/nginx/html/index.html
    docker create   --name nginx-data   -v /root/nginx/html/:/usr/share/nginx/html  nginx:latest
    #使用volume亦可,docker create   --name nginx-data   -v nginx:/usr/share/nginx/html  nginx:latest
    #其他nginx容器共享数据卷容器数据
    #nginx容器的挂载和数据卷容器的挂载是一样的
    docker run -d --name nginx1 -p 8001:80 --volumes-from nginx-data nginx:latest
    docker run -d --name nginx2 -p 8002:80 --volumes-from nginx-data nginx:latest
    docker run -d --name nginx3 -p 8003:80 --volumes-from nginx-data nginx:latest
    curl  127.0.0.1:8001
    I am good man
    curl  127.0.0.1:8002
    I am good man
     curl  127.0.0.1:8003
    I am good man
    
    #删除数据卷容器
    docker rm  nginx-data 
    # nginx3 容器依然可以访问
    curl  127.0.0.1:8003
    I am good man
    #查看nginx3 的挂载目录
     "Mounts": [
                {
                    "Type": "bind",			#bind类型,因为nginx-data数据卷容器就是使用bind类型
                    "Source": "/root/nginx/html",		#宿主机目录
                    "Destination": "/usr/share/nginx/html",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
    #我们可以看到,即使数据卷容器被删除了,使用数据卷容器的其他nginx容器依然能正常持久化数据
    #这说明,其他nginx容器其实本质上还是挂载宿主机上的目录,这其实和多个容器使用相同的-v /root/nginx/html/:/usr/share/nginx/html 没说
    #明区别
    #以上只演示了使用bind mount 类型的卷,其实手动创建一个数据卷docker volume create nginx-data,然后,多个容器都使用该nginx-data数据
    # 卷亦可以共享数据,或者数据卷容器挂载的是nginx-data数据卷,然后多个容器都使用该nginx-data数据卷也是可以的.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    孤儿volume

    所谓孤儿volume是指没有被任何容器使用的volume。
    删除volume:
    1、对于直接使用-v /root/nginx/html/:/usr/share/nginx/html指定宿主机目录挂载的,当删除容器时,宿主机上的目录并不会被删除,这也是数据持久化的含义,所以如果需要永久删除宿主机目录,可以在确认数据不再需要后删除宿主机目录即可。
    2、对于使用docker manager volume管理的,如果是匿名卷,在删除容器的时候加上-v可以直接删除容器和匿名卷,docker rm命令如下:

    [root@docker ~]# docker rm --help
    Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]
    Remove one or more containers
    Options:
      -f, --force     Force the removal of a running container (uses SIGKILL)
      -l, --link      Remove the specified link
      -v, --volumes   Remove anonymous volumes associated with the container	#-v参数删除分配给容器的匿名卷
    #删除容器的同时删除容器的匿名卷
    docker rm  nginx1 -v -f
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3、对于不管是匿名卷还是有名卷,都可以使用docker volume rm 命令删除卷。
    4、孤儿volume是指没有被任何容器使用的volume。在确定volume不再使用后,可以使用docker volume rm 命令删除卷。

    –mount参数

    docker run --help | grep mount
    --mount mount                    Attach a filesystem mount to the container
    --mount参数其实也是挂载一个目录或卷到容器中,与-v其实是相同的功能。
    
    挂载bind mount命令格式:type=bind,source=/path/on/host,destination=/path/in/container[,...]
    挂载volume命令格式:[type=volume,]source=my-volume,destination=/path/in/container[,...]
    参数的顺序不重要。
    示例1:
    mkdir /tmp/test && echo "Test" >>/tmp/test/file1.txt
    docker run -itd --mount type=bind,source=/tmp/test,target=/tmp busybox1:v1
    docker exec -it 3a70c2c663b46 sh	#进入容器,可以正常查看文件,测试在宿主上再创建几个文件,在容器里面也能看到
    /data # cat /tmp/file.txt
    Test
    /data # exit
    docker inspect 3a70c2c663b468 | grep -A9 Mounts
        "Mounts": [
                  {
                    "Type": "bind",
                    "Source": "/tmp/test",
                    "Destination": "/tmp",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                  }
              ]
    
    示例2:            
    docker volume create nginx
    docker inspect  nginx --type volume  | grep Mountpoint
            "Mountpoint": "/var/lib/docker/volumes/nginx/_data",
    echo "AAAAAA" >> /var/lib/docker/volumes/nginx/_data/nginx.log
    docker run -itd --mount type=volume,source=nginx,target=/tmp busybox1:v1
    docker exec -it dac0565abccce7 cat /tmp/nginx.log
    AAAAAA
    echo "err" >> /var/lib/docker/volumes/nginx/_data/nginx.err
    docker exec -it dac0565abccce7 cat /tmp/nginx.err
    err
    [root@rancher city]# docker inspect dac0565abccce7  --type container  | grep -A9 -i Mounts
            "Mounts": [
                {
                    "Type": "volume",
                    "Name": "nginx",
                    "Source": "/var/lib/docker/volumes/nginx/_data",
                    "Destination": "/tmp",
                    "Driver": "local",
                    "Mode": "z",
                    "RW": true,
                    "Propagation": ""
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    总结

    docker容器实现数据持久化一般有以下几种方式:

    1、-v参数,以bind mount方式挂载宿主机目录或文件到容器
    docker run -v参数语法:
    -v <host_path>:<container_path>[:rw/ro]
    <host_path>是宿主机的目录或单个文件
    <container_path>是容器的目录或单个文件
    rw/ro 表示挂载后容器的数据读写权限,rw表示读写,ro表示数据只读,不写默认就是rw读写权限
    
    示例:
    mkdir /root/nginx/html -p
    docker run -d --name nginx1 -p 8081:80 -v /root/nginx/html:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx2 -p 8082:80 -v /root/nginx/html/index.html:/usr/share/nginx/html/index.html nginx:latest
    docker inspect nginx1 
     "Mounts": [
                {
                    "Type": "bind",		#类型是bind
                    "Source": "/root/nginx/html",
                    "Destination": "/usr/share/nginx/html",
                    "Mode": "",
                    "RW": true,
                    "Propagation": "rprivate"
                }
            ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    2、-v 不指定<host_path>部分时,docker默认使用匿名卷,docker manager volume
    使用-v参数时可以不指定<host_path>部分,只需指定容器的挂载点即可,如:-v  <container_path>,container_path必须是一个容器目录,不
    能是单个文件了,数据权限不能设置,均为读写权限。因为没写<host_path>部分,这时docker会自动创建一个数据卷,这个数据卷的名字是自动生成
    的一个很长串的字符,所以叫匿名卷。
    docker run -d --name nginx -p 8082:80 -v /usr/share/nginx/html  nginx:latest 
    docker inspect nginx
    "Mounts": [
                {
                    "Type": "volume",		#类型是volume
                    "Name": "58b3689c8256a8d33d9114c52b",
                    "Source": "/var/lib/docker/volumes/58b3689c8256a8d33d9114c52b/_data",
                    "Destination": "/usr/share/nginx/html",
                    "Driver": "local",
                    "Mode": "",
                    "RW": true,
                    "Propagation": ""
                }
            ],
    [root@docker ~]# docker volume list | grep   58b3689c8256a8d33d9114c52b
    local     58b3689c8256a8d33d9114c52b
    [root@docker ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    3、使用创建好的数据卷
    #docker volume命令用于管理数据卷
    #创建一个数据卷,名称叫做nginx
    [root@docker ~]# docker volume create nginx
    nginx
    [root@docker ~]# docker volume ls | grep nginx
    local     nginx
    [root@docker ~]# docker volume inspect  nginx
    [
        {
            "CreatedAt": "2023-08-27T14:40:43+08:00",
            "Driver": "local",
            "Labels": {},
            "Mountpoint": "/var/lib/docker/volumes/nginx/_data",
            "Name": "nginx",
            "Options": {},
            "Scope": "local"
        }
    ]
    #创建一个容器并使用名称叫做nginx的volume卷,使用-v参数时指定volume卷名即可
    [root@docker ~]# docker run -d --name nginx -p 8081:80 -v nginx:/usr/share/nginx/html  nginx:latest
    57022b423ec03bdb1a7a178544d422b262daa1b2861ba8a509a20962ed3051cf
    [root@docker ~]# docker inspect nginx 
      "Mounts": [
                {
                    "Type": "volume",		#类型是volume
                    "Name": "nginx",		#卷的名称
                    "Source": "/var/lib/docker/volumes/nginx/_data",
                    "Destination": "/usr/share/nginx/html",
                    "Driver": "local",
                    "Mode": "z",
                    "RW": true,
                    "Propagation": ""
                }
    #列出全部的volume
    docker volume ls
    #查看指定名字的volume的详细信息
    docker volume inspect a0dc63aae530f4070bb34e1c5331319c93a97f3727e6cf60415b7847010dcaf8
    #移除全部未使用的本地volume
    docker volume  prune
    #删除指定的volume
    docker volume  rm a0dc63aae530f4070bb34e1c5331319c93a97f3727e6cf60415b7847010dcaf8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    4、数据卷容器

    1、不使用数据卷容器之前,多个容器共享相同的数据,只需使用-v参数挂载同一个宿主机目录即可,如下实现:
    docker run -d --name nginx1 -p 8081:80 -v /root/nginx/html/:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx2 -p 8082:80 -v /root/nginx/html/:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx3 -p 8083:80 -v /root/nginx/html/:/usr/share/nginx/html nginx:latest
    echo "good" >>/root/nginx/html/index.html
    #以上使用的是bind mount的形式挂载,当然也可以手动创建一个volume,如下:
    docker volume create nginx
    docker volume inspect  nginx
    [    {
    		.......
            "Mountpoint": "/var/lib/docker/volumes/nginx/_data",
            "Name": "nginx",
    	    ......
        }
    ]
    echo "good" >>/var/lib/docker/volumes/nginx/_data/index.html
    docker run -d --name nginx11 -p 8001:80 -v nginx:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx12 -p 8002:80 -v nginx:/usr/share/nginx/html nginx:latest
    docker run -d --name nginx13 -p 8003:80 -v nginx:/usr/share/nginx/html nginx:latest
     
    #以上就说明多个容器共享了相同的数据
    #注意:不能使用匿名卷,匿名卷会自动创建volume,那么多个容器都各自创建自己的匿名卷这样做不到数据共享了
    
    2、使用数据卷容器之后,多个容器共享相同的数据,如下实现:
    #创建一个数据卷容器,名称叫做nginx-data,数据卷容器可以不用run,其只是提供数据而已
    echo "I am good man" >/root/nginx/html/index.html
    docker create   --name nginx-data   -v /root/nginx/html/:/usr/share/nginx/html  nginx:latest
    #使用volume亦可,docker create   --name nginx-data   -v nginx:/usr/share/nginx/html  nginx:latest
    #其他nginx容器共享数据卷容器数据,使用--volumes-from指定数据卷容器
    #nginx容器的挂载和数据卷容器的挂载是一样的
    docker run -d --name nginx1 -p 8001:80 --volumes-from nginx-data nginx:latest
    docker run -d --name nginx2 -p 8002:80 --volumes-from nginx-data nginx:latest
    docker run -d --name nginx3 -p 8003:80 --volumes-from nginx-data nginx:latest
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    5、孤儿卷

    所谓孤儿volume是指没有被任何容器使用的volume。
    删除volume:
    1、对于直接使用`-v /root/nginx/html/:/usr/share/nginx/html`指定宿主机目录挂载的,当删除容器时,宿主机上的目录并不会被删除,这也是
    数据持久化的含义,所以如果需要永久删除宿主机目录,可以在确认数据不再需要后删除宿主机目录即可。
    2、对于使用docker manager volume管理的,如果是匿名卷,在删除容器的时候加上-v可以直接删除容器和匿名卷,docker rm命令如下:
    [root@docker ~]# docker rm --help
    Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]
    Remove one or more containers
    Options:
      -f, --force     Force the removal of a running container (uses SIGKILL)
      -l, --link      Remove the specified link
      -v, --volumes   Remove anonymous volumes associated with the container	#-v参数删除分配给容器的匿名卷
    #删除容器的同时删除容器的匿名卷
    docker rm  nginx1 -v -f
    3、对于不管是匿名卷还是有名卷,都可以使用`docker volume rm` 命令删除卷。
    4、docker volume prune   #移除全部未使用的本地volume 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    6、--mount 参数也可挂载目录或卷到容器

    docker run --help | grep mount
    --mount mount                    Attach a filesystem mount to the container
    --mount参数其实也是挂载一个目录或卷到容器中,与-v其实是相同的功能。
    
    挂载bind mount命令格式:type=bind,source=/path/on/host,destination=/path/in/container[,...]
    挂载volume命令格式:[type=volume,]source=my-volume,destination=/path/in/container[,...]
    参数的顺序不重要。
    示例1:
    mkdir /tmp/test && echo "Test" >>/tmp/test/file1.txt
    docker run -itd --mount type=bind,source=/tmp/test,target=/tmp busybox1:v1
    这样在容器/tmp目录和宿主机/tmp/test目录里面的文件就是相同的,在任一侧创建的文件,另一侧都可以读取。
    
    示例2:
    docker volume create nginx
    docker inspect  nginx --type volume  | grep Mountpoint
            "Mountpoint": "/var/lib/docker/volumes/nginx/_data",
    echo "AAAAAA" >> /var/lib/docker/volumes/nginx/_data/nginx.log
    docker run -itd --mount type=volume,source=nginx,target=/tmp busybox1:v1
    docker exec -it dac0565abccce7 cat /tmp/nginx.log
    AAAAAA
    这样在容器/tmp目录和宿主机/var/lib/docker/volumes/nginx/_data目录里面的文件就是相同的,在任一侧创建的文件,另一侧都可以读取。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    7、最喜欢使用哪个参数
    在实际生产中,一般最常用-v参数直接挂载宿主机目录即可,volume也是很常用的,–mount参数了解即可。

  • 相关阅读:
    Redis哨兵模式
    原生实现C#和Lua相互调用-Unity3D可用
    Vue的学习补充
    UE4 WebUI插件使用指南
    【LeetCode刷题日志】225.用队列实现栈
    C++:多态与虚函数,纯虚函数
    echarts vue里画一个简单的环状饼图
    POJ1007:DNA排序
    【老生谈算法】matlab实现高斯白噪声仿真算法源码——高斯白噪声
    本地连接服务器使用GPU训练模型
  • 原文地址:https://blog.csdn.net/MssGuo/article/details/126526344