Container Data Volume Technology for Getting Started with docker

Preface

When we start a container, all kinds of data are stored in the container. Once the docker rm command is executed accidentally, the container will be deleted and the data will be lost. The data generated by the docker container must be persisted in the production environment, and the problem of data sharing among multiple containers will also be involved. To solve these problems, we can use docker's data volume technology.

What is a data volume

Data Volume (Data Volumes) is a special directory that can be used by containers to map the data inside the container directly to the host machine. Even if the container is accidentally deleted, the data generated by the container is stored on the host machine. For example, I can map the container path **/usr/local/data** to the host/soft/docker/data path, as shown in the following figure:

Data volume technology enables us to persist container data and share data between containers.

Create Data Volume

docker provides volume commands for managing data volumes, and we can use help to see how the command works:

[root@VM-0-10-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.

Using the create command, you can create a container volume as follows:

[root@VM-0-10-centos ~]# docker volume create my-volume
my-volume

Use the ls command to view all volumes that exist in the current container:

[root@VM-0-10-centos ~]# docker volume ls
DRIVER    VOLUME NAME
local     my-volume

The volume created by the create command defaults to the host **/var/lib/docker/volumes** path and can be viewed using the **tree** command:

[root@VM-0-10-centos volumes]# tree /var/lib/docker/volumes/
/var/lib/docker/volumes/
|-- backingFsBlockDev
|-- metadata.db
`-- my-volume
    `-- _data

2 directories, 2 files

Use the inspect command to view data volume details:

[root@VM-0-10-centos volumes]# docker volume inspect my-volume
[
    {
        "CreatedAt": "2021-12-25T21:22:14+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
        "Name": "my-volume",
        "Options": {},
        "Scope": "local"
    }
]

Use the prune command to clean up unused containers:

[root@VM-0-10-centos volumes]# docker volume prune 
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
my-volume

Total reclaimed space: 0B

Use the rm command to delete container volumes:

  • Create Container
## Create Container Volume
[root@VM-0-10-centos volumes]# docker volume create my-volume
my-volume
## List all container volumes
[root@VM-0-10-centos volumes]# docker volume ls
DRIVER    VOLUME NAME
local     my-volume

Use -q to list only container volume names:

[root@VM-0-10-centos volumes]# docker volume ls -q
my-volume

Delete a single container volume:

[root@VM-0-10-centos volumes]# docker volume rm my-volume
 my-volume

Bulk Delete All Container Volumes

[root@VM-0-10-centos volumes]# docker volume create my-volume
my-volume
## Delete all container volumes
[root@VM-0-10-centos volumes]# docker volume ls -q | xargs docker volume rm
my-volume

Bind data volume

In addition to using the volume command to manage data volumes, we can also create container volumes and map them to host paths when creating containers. First, we download a mirror of nginx to demonstrate the binding of container volumes:

  1. Download nginx image
[root@VM-0-10-centos volumes]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
a2abf6c4d29d: Pull complete 
f3409a9a9e73: Pull complete 
9919a6cbae9c: Pull complete 
fc1ce43285d7: Pull complete 
1f01ab499216: Pull complete 
13cfaf79ff6d: Pull complete 
Digest: sha256:366e9f1ddebdb844044c2fafd13b75271a9f620819370f8971220c2b330a9254
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
  1. Run the mirror and mount the data volume

You can map host paths to container contents when creating containers, such as HTML directories mapping nginx containers, such as mapping host paths/soft/data/docker/html and/soft/nginx/html

[root@VM-0-10-centos html]# docker run -d --name nginx -P -v /soft/data/docker/html:/soft/nginx/html nginx
e0c7ed8c9999b4121c3c3a62eb23f7579a145ecbbc3885ecfe461fad1a8842cc

Create test.html:

vim test.html
## Add the following:
<<html>
<head>
<script type="text/javascript">
function alertIndex()
{
var x=document.getElementById("mySelect").selectedIndex;
var y=document.getElementsByTagName("option");
alert(y[x].text + " has the index of: " + y[x].index);
}
</script>
</head>
<body>

<form>
Select your favorite fruit:
<select id="mySelect">
  <option>Apple</option>
  <option>Orange</option>
  <option>Pineapple</option>
  <option>Banana</option>
</select>
<br />
<br />
<input type="button" onclick="alertIndex()"
value="Show index of the chosen fruit">
</form>

</body>
</html>

You can see that there is a test under the current path. Html:

[root@VM-0-10-centos html]# ll
total 4
-rw-r--r-- 1 root root 555 Dec 26 20:03 test.html
[root@VM-0-10-centos html]# pwd
/soft/data/docker/html

Enter the container to view:

[root@VM-0-10-centos html]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                     NAMES
e0c7ed8c9999   nginx     "/docker-entrypoint...."   46 minutes ago   Up 46 minutes   0.0.0.0:49160->80/tcp, :::49160->80/tcp   nginx

When you enter the container, you can see the html file you just created on the host, and it also exists on the appropriate path to the container.

[root@VM-0-10-centos html]# docker exec -it nginx /bin/bash
## You can see / soft/nginx/html
root@e0c7ed8c9999:/# cd /soft/nginx/html
root@e0c7ed8c9999:/soft/nginx/html# ls -lsa
total 12
4 drwxr-xr-x 2 root root 4096 Dec 26 12:03 .
4 drwxr-xr-x 3 root root 4096 Dec 26 11:19 ..
4 -rw-r--r-- 1 root root  555 Dec 26 12:03 test.html

The test you just created. Copy HTML to ****

root@e0c7ed8c9999:/soft/nginx/html# cp test.html /usr/share/nginx/html/

Then access it in the browser as follows:

The command to mount a container volume on top is -v, or you can use the -mount command:

[root@VM-0-10-centos ~]# docker run -d --name my-nginx -P --mount type=bind,source=/soft/data/docker/my-nginx,destination=/soft/container/nginx nginx
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /soft/data/docker/my-nginx.
See 'docker run --help'.

It is important to note that host mount paths must exist or errors will occur as shown above:

[root@VM-0-10-centos ~]# mkdir -p /soft/data/docker/my-nginx
[root@VM-0-10-centos ~]# docker run -d --name my-nginx -P --mount type=bind,source=/soft/data/docker/my-nginx,destination=/soft/container/nginx nginx
bdf701f0a0835089e408d750381684f74ab8393f708cfc0678c4b6b3e21e5254

Log in to the nginx container to see if the path mapping exists.

[root@VM-0-10-centos ~]# docker exec -it my-nginx /bin/bash
root@bdf701f0a083:/# cd /soft/container/nginx/
root@bdf701f0a083:/soft/container/nginx# ls -lsa
total 8
4 drwxr-xr-x 2 root root 4096 Dec 26 14:23 .
4 drwxr-xr-x 3 root root 4096 Dec 26 14:23 ..

Create a document in a container:

root@bdf701f0a083:/soft/container/nginx# echo "test message" > haha.txt
root@bdf701f0a083:/soft/container/nginx# ls -lsa
total 12
4 drwxr-xr-x 2 root root 4096 Dec 26 14:29 .
4 drwxr-xr-x 3 root root 4096 Dec 26 14:23 ..
4 -rw-r--r-- 1 root root   13 Dec 26 14:29 haha.txt

Host view text content:

[root@VM-0-10-centos ~]# cat /soft/data/docker/my-nginx/haha.txt 
test message

It is important to note that the host path must be absolute. If you use --mount, you need to determine that the mounted path exists or you will encounter errors. Docker can also specify read and write permissions for the host directory when mounting it. The default permission is read and write (rw), or the user can specify read-only permissions, that is, ro:

docker run -d --name my-nginx -P --mount type=bind,source=/soft/data/docker/my-nginx:ro,destination=/soft/container/nginx nginx

With ro privileges added, the container can only read mounted paths and cannot modify data in the data volume.

Create a shared data volume container

Generally, in development, you will encounter multiple containers sharing the same batch of data directly. You can use data volume containers. Note that the data volume containers themselves are also containers. Here are three centos mirrors to illustrate the use of container data volumes:

  1. Download centos image:
[root@VM-0-10-centos ~]# docker pull centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete 
Digest: sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987
Status: Downloaded newer image for centos:7
docker.io/library/centos:7

Create a data volume container

[root@VM-0-10-centos ~]# docker run -it -v /dir --name dir centos:7


Create a new file in the dir directory and enter:

[root@8d3d2d3d6edf /]# echo "Hi I am GalenGao" > /dir/test.txt

Exit the container with crtl + p + q, and mount the container volume with two new containers centos1 and centos2.

Create container centos1 to see if there is a corresponding container volume directory:

[root@VM-0-10-centos volumes]# docker run -it --name centos1 --volumes-from dir centos:7


You can clearly see that the corresponding dir directory exists and test. The TXT document also exists, at this time we append some text:

[root@6cc32c0aeb05 dir]# echo "it's a message from centos1"  >> test.txt 

Create the container centos2 to view the corresponding text:

[root@VM-0-10-centos volumes]# docker run -it --name centos2 --volumes-from dir centos:7
[root@a1db0373c9c8 /]# cat /dir/test.txt 
Hi I am GalenGao
it's a message from centos1

From the above demonstration, you can see that the centos1 and centos2 containers output files in the same directory, which can be viewed in their respective directories, for data sharing purposes.

Delete shared data volume

Running containers are deleted without affecting their true host content. If you want to delete containers at the same time you need to delete their data volumes, you need to specify the corresponding container data volumes in the last container where the real host is mounted. For example, by deleting the container data volume you just created, you can use the docker rm-v command to specify that the associated container is also deleted.

[root@VM-0-10-centos volumes]# docker rm -f dir -v /dir
/dir
Error response from daemon: removal of container dir is already in progress
[root@VM-0-10-centos volumes]# docker ps

Keywords: Operation & Maintenance Docker Container

Added by russian_god on Mon, 27 Dec 2021 10:28:32 +0200