docker data volume, docker data persistence

Preface

Environment: centos7.9 docker version 20.10.14
In this article, we will introduce docker's data volume. Data volume is used to achieve the persistence of docker data.

2 ways to persist data in docker

In the process of using docker, we need to persist the data generated in the container, as well as perform data sharing, backup and other operations between containers and between containers and the host. Here we need the data persistence management of the container. Docker's data persistence management currently provides the following two methods:

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

Data volume bind mount, that is, the -v parameter

Data volume: A data volume is actually a directory or file. It is similar to the mount operation of a directory or file under Linux, that is, one or more directories (files can also be used) are established between the host and the container to map files to each other. It has the following characteristics:
(1) Data volumes can be shared and reused between containers, that is, multiple containers can mount the same directory
(2) Changes to the data volume will take effect immediately, that is, changes to the files in the host directory Modifications will be immediately reflected in the container's mount point directory file
(3) Updates to the data volume will not affect the image (the image is read-only)
(4) The volume will always exist, even if the container is deleted, that is, the host directory will not change due to Deletion of the container deletes the host directory

Note:
(1) When the container is deleted, the data volume will not be deleted. If you want to delete the data volume when deleting the container, you need to add the -v parameter. For example: docker rm os456 -v /homedata
(2) After the default data volume is mounted, the file permissions are. rwIf you need to set them separately, you can set them after the container data volume: ro只读.

docker run -vParameter syntax:

-v <host_path>:<container_path>[:rw/ro]
<host_path>是宿主机的目录或单个文件
<container_path>是容器的目录或单个文件
rw/ro 表示挂载后容器的数据读写权限,rw表示读写,ro表示数据只读,不写默认就是rw读写权限

Demo example:

#使用数据卷挂载宿主机目录到容器中去
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"
            }
        ],

Anonymous data volume docker manager volume

When using -vparameters, you do not need to specify <host_path>any part. You only need to specify the mount point of the container, such as: -v <container_path>, container_path must be a container directory, not a single file, and data permissions cannot be set. They are all read and write permissions. At this time, docker will automatically create an anonymous data volume. The name of this anonymous data volume is a long string of characters that is automatically generated. You can use docker volume lsthe command to see the name of this data volume. We call this volume an anonymous data volume.

Demo example:

使用-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页面的变更

The difference between the -v parameter and anonymous volumes

difference bind mount docker manager volume
volume position Can mount directories or files anywhere on the host Only mount the directory at a fixed location on the host, which is generally /var/lib/docker/volumes/xxx/_data/
Impact on container mount points After mounting, the mount point directory in the container will be overwritten. If there are no files in the host directory at this time, then there will be no files in the container's mount point. When using an anonymous data volume, if the volume is empty and the directory in the container has content, docker will copy the content in the container directory to the volume. However, if there is already content in the volume, the directory in the container will be overwritten.
Whether to support single file Supports mounting directories or single files Only supports mounting directories
Permission control The default permission is rw, which can be set to ro Can only default to rw
Portability Weak portability, bound to the host path Strong portability, no need to specify the host directory


When using the -v parameter of the anonymous data volume docker manager volume, do not specify <host_path>the part. You only need to specify the mount point of the container, such as: -v <container_path>This is the directory that docker will create by default, such as /var/lib/docker/volumes/8d1d766c65d3b3cddafd20f25dcaf304a96b9c89d005d30226a7b815a6b5ecbf/_data/directory. This directory is the directory for the container's persistent data. This long string of IDs is the volume name, which is automatically generated by docker for us. The volume can be viewed through the docker volume ls command.

Note: After
using 数据卷 bind mount ,即-v参数, the mount point directory in the container will be overwritten. If there are no files in the host directory at this time, then there will be no files in the container's mount point; when
using anonymous data volumes, if the volume is empty and If the directory in the container has content, docker will copy the content in the container directory to the volume. However, if there is already content in the volume, the directory in the container will be overwritten.

Use of docker volume command

[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"
            }
        ],

data volume container

The so-called data volume container is actually a container that provides a volume for other containers, that is, a container that contains data. Then other containers can --volumes-from 数据卷容器名mount the data volume container through parameters, so that multiple containers can share the same data.

1. Before using data volume containers, multiple containers share the same data. You only need to use the -v parameter to mount the same host directory, as follows:

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,那么多个容器都各自创建自己的匿名卷这样做不到数据共享了

2. After using the data volume container, multiple containers share the same data, as follows:

#创建一个数据卷容器,名称叫做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数据卷也是可以的.

orphanvolume

The so-called orphan volume refers to a volume that is not used by any container.
Delete volume:
1. For those directly -v /root/nginx/html/:/usr/share/nginx/htmlmounted using the specified host directory, when the container is deleted, the directory on the host will not be deleted. This is also the meaning of data persistence, so if you need to permanently delete the host directory, you can Just delete the host directory after confirming that the data is no longer needed.
2. For those managed using docker manager volume, if it is an anonymous volume, adding -v when deleting the container can directly delete the container and anonymous volume. The docker rm command is as follows:

[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. Whether it is an anonymous volume or a named volume, you can use docker volume rmthe command to delete the volume.
4. An orphan volume refers to a volume that is not used by any container. After determining that the volume is no longer in use, you can use docker volume rmthe command to delete the volume.

Summarize

Docker containers generally implement data persistence in the following ways:

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"
            }
        ],
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 ~]# 
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

4. Data volume container

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

5. Orphan 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
3、对于不管是匿名卷还是有名卷,都可以使用`docker volume rm` 命令删除卷。
4、docker volume prune   #移除全部未使用的本地volume 

Guess you like

Origin blog.csdn.net/MssGuo/article/details/126526344
Recommended