一、在Docker中管理数据
1.1、Docker 保存容器数据的方法
-
Docker 卷(
Docker Volumes
):可以将数据保存在 Docker 卷中,这样可以在容器和宿主机之间共享数据,并保证容器中的数据不会因为容器被删除而丢失。Docker 卷可以用来保存应用程序的配置、日志、数据库等数据,还可以用于多个容器之间共享数据。 -
Docker 挂载点(
Docker Mounts
):可以将主机文件系统中的目录或文件挂载到容器中,通过挂载点可以将主机文件系统中的数据共享到容器中,并进行持久化保存。 -
Docker 数据卷容器(
Docker Data Container
):可以创建一个特殊的容器,专门用来存储数据卷。在其他容器中挂载这个数据卷容器,可以实现数据在不同容器之间的共享。 -
Docker 备份和恢复(
Docker Backup and Restore
):可以使用 Docker 的备份和恢复功能来保存容器数据。使用 Docker 的命令可以将容器的数据备份到一个 tar 包中,然后将这个 tar 包恢复到另一个容器中。
以上这些方法都可以用来保存 Docker 容器中的数据,并进行持久化保存。具体使用哪种方法,需要根据应用场景和需求进行选择。
1.2、Docker 三种不同的挂载方式
-
bind mount
:将主机的文件或目录直接挂载到容器中。这种挂载方式可以让容器访问主机上的文件系统,也可以让主机访问容器中的文件系统。bind mount 挂载是针对文件或目录进行的,支持读写模式。 -
volumes
:是 Docker 容器中持久化数据的一种方法,可以将数据保存在 Docker 卷中,并在容器和宿主机之间共享数据。volumes 挂载是针对卷进行的,支持读写模式。 -
tmpfs mount
:将主机的 tmpfs 文件系统挂载到容器中。tmpfs 文件系统是一个基于内存的文件系统,使用 tmpfs mount 挂载可以在容器中创建一个临时文件系统,这个文件系统的数据将保存在内存中,不会写入主机磁盘。tmpfs mount 挂载也是针对目录进行的,支持读写模式。
总的来说,bind mount 挂载是针对主机文件系统的,而 volumes 和 tmpfs mount 挂载是针对 Docker 卷和内存文件系统的。bind mount 挂载适合用于开发环境和持续集成环境,volumes 和 tmpfs mount 挂载适合用于生产环境和分布式环境。
二、卷(Volume)
2.1、卷概述
Docker 卷 (Docker Volumes) 是 Docker 容器中持久化数据的一种方法。它允许在容器和宿主机之间共享数据,并保证容器中的数据不会因为容器被删除而丢失。Docker 卷可以用来保存应用程序的配置、日志、数据库等数据,还可以用于多个容器之间共享数据。
卷(volume)提供了将容器的特定文件系统路径连接回主机的能力,简单来说就是将容器的目录映射到主机上。如果容器中的目录已挂载,则该目录中的更改也会在主机上看到。如果我们在容器重启时挂载相同的目录,我们会看到相同的文件,这就是容器的持久化和同步操作。
- Docker Volume 命令能让容器从宿主机中读取文件,或从容器中持久化数据到宿主机中,让容器与容器产生的数据分离开来,一个容器可以挂载多个不同的目录。
- Volume的生命周期是独立于容器的生命周期之外的,即使容器删除了,Volume也会被保留下来,Docker不会因为这个Volume没有被容器使用而自动回收。
- 在容器中,添加或修改这个文件夹里的文件也不会影响到容器的联合文件系统。
数据卷映射
在容器运行时,容器内有一个数据存储空间,但是当容器关闭后,这个存储空间内容将被丢失。因此,数据无法长期保存!那么,数据如何长期保存需要什么策略?答案是保存在宿主机,并且不妨碍容器的读写。
通过在容器建立虚拟文件路径,此路径指向的物理地址是宿主机的文件系统,此时,当容器突然关闭,而所在宿主机上的文件系统依然无恙。这样就起到数据永久性保护的目的。
容器数据卷特征
数据卷是一个可供一个或多个容器使用的特殊目录,它将主机操作系统目录直接映射进容器 (也就是数据卷可以把数据可以直接映射到容器中)
数据卷的特性:
- 数据卷 可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 数据卷 默认会一直存在,即使容器被删除
2.2、卷的优点
相比普通的数据挂载方式,Docker Volume 具有以下优点:
- 支持数据卷的备份和恢复:Docker Volume 支持数据卷的备份和恢复,可以将数据卷中的数据备份到本地或远程存储中,以便进行灾备恢复或数据迁移。
- 卷可以直接使用Docker CLI 命令或 Docker API 管理。
- 卷可以在 Linux 和 Windows 容器上运行。
- 卷可以在多个容器之间更安全的共享。
- 支持多种类型的数据卷:Docker Volume 支持多种数据卷类型,如本地存储卷、远程存储卷、云存储卷等。这使得数据卷的管理更加灵活,可以根据具体需求选择不同类型的数据卷。
- 新卷的内容可以由容器预先填充。
- Docker Desktop 上的卷比 来自Mac 和 Windows 主机的绑定挂载具有更高的性能。
- 数据卷的生命周期独立于容器:Docker Volume 可以独立于容器存在,即使容器被删除,Volume 中的数据仍然存在。这使得数据卷的管理更加灵活,可以在容器之间共享数据。
- 支持数据卷的加密:Docker Volume 支持数据卷的加密,可以对敏感数据进行保护,确保数据的安全性。
- 支持数据卷的扩容和缩容:Docker Volume 支持数据卷的扩容和缩容,可以根据实际需求动态调整数据卷的大小。
2.3、卷的使用
2.3.1、卷的创建
默认创建本地数据卷
docker volume create test_volume
还可以创建其他类型的数据卷,如下:
远程数据卷:
docker volume create --driver=remote --opt=remote-host=my-remote-host --opt=remote-path=/my-volume my-remote-volume
该命令将创建一个名为 my-remote-volume 的远程存储数据卷。该数据卷将存储在远程主机上的 /my-volume 目录中。需要通过 --opt 参数指定远程主机的地址和远程路径。需要安装相应的远程存储驱动程序才能够使用该命令。
安装docker volume remote驱动
在 Docker 主机上安装并启用名为 “remote” 的 Docker Volume 驱动程序。可以通过以下步骤来安装 “remote” 驱动程序:
1、打开 Docker 主机终端,并使用 root 或其他有管理员权限的账户登录。
2、运行以下命令来安装 “remote” 驱动程序:
$ docker plugin install ssh://<remote-host>/path/to/remote-volume-plugin.tar.gz
这里需要将 替换为远程主机的 IP 地址或域名,并将 /path/to/remote-volume-plugin.tar.gz
替换为远程主机上存放 “remote” 驱动程序的路径。如果 “remote” 驱动程序是通过 Docker Registry 分发的,则可以使用以下命令来安装:
$ docker plugin install <registry>/<repo>/<image>:<tag>
这里需要将 <registry>/<repo>/<image>:<tag>
替换为正确的镜像名称和标签。
3、安装完成后,运行 docker plugin ls
命令来检查 “remote” 驱动程序是否已成功安装。
4、运行 docker volume create --driver=remote
命令来创建远程存储数据卷。
云数据卷:
docker volume create --driver=cloud --opt=cloud-provider=aws --opt=cloud-region=us-west-2 my-aws-volume
该命令将创建一个名为 my-aws-volume 的云存储数据卷。该数据卷将存储在 AWS 的 us-west-2 区域中。需要通过 --opt 参数指定云存储服务的提供商和区域。需要安装相应的云存储驱动程序才能够使用该命令。
创建标签
$ docker volume create test_volume_01 --label=app=test --label=use=test_function
元信息如下:
$ docker volume inspect test_volume_01
[
{
"CreatedAt": "2023-06-02T17:26:13+08:00",
"Driver": "local",
"Labels": {
"app": "test",
"use": "test_function"
},
"Mountpoint": "/var/lib/docker/volumes/test_volume_01/_data",
"Name": "test_volume_01",
"Options": {},
"Scope": "local"
}
]
2.3.2、卷的查看
docker volume ls
查看卷清单
$ docker volume ls
DRIVER VOLUME NAME
local 0ff4f6d947508d887de39e67f5e9ff24be875473756106aed4c7312ce9bffc8e
...
local test_volume
local test_volume_01
docker volume ls -q
仅展示volume name
$ docker volume ls -q
0ff4f6d947508d887de39e67f5e9ff24be875473756106aed4c7312ce9bffc8e
...
test_volume
test_volume_01
docker volume ls -f
匹配查询:
docker volume ls -f name=test*
DRIVER VOLUME NAME
local test_volume
local test_volume_01
docker volume inspect
查看卷元信息
$ docker volume inspect test_volume
[
{
"CreatedAt": "2023-06-02T16:59:00+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/test_volume/_data",
"Name": "test_volume",
"Options": {},
"Scope": "local"
}
]
docker volume inspect -f
同样支持go语言模板:
$ docker volume inspect -f {{."Mountpoint"}} test_volume
/var/lib/docker/volumes/test_volume/_data
2.3.3、卷的使用
-v
使用-v 启动容器,并查看容器信息中Mounts
部分内容
docker run -d --name=con-test -v test_volume:/home nginx:latest /bin/bash
docker inspect con-test | grep -A 10 Mounts
"Mounts": [
{
"Type": "volume",
"Name": "test_volume",
"Source": "/var/lib/docker/volumes/test_volume/_data",
"Destination": "/home",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
--mount
使用–mount 启动容器,并查看容器信息中Mounts
部分内容
docker run -d --name=con-test-01 --mount source=test_volume_01,target=/home nginx:latest /bin/bash
docker inspect con-test-01 | grep -A 10 Mounts
"HostConfig": {
...
"Mounts": [
{
"Type": "volume",
"Source": "test_volume_01",
"Target": "/home"
}
],
...
}
"Mounts": [
{
"Type": "volume",
"Name": "test_volume_01",
"Source": "/var/lib/docker/volumes/test_volume_01/_data",
"Destination": "/home",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
-v
和 --mount
区别
-v 只能创建bind mount
–mount默认情况下用来挂载volume,但也可以用来创建bind mount和tmpfs
创建bind mount和挂载volume的比较
对比项 | bind mount | volume |
---|---|---|
Source位置 | 用户指定 | /var/lib/docker/volumes/ |
Source为空 | 覆盖dest为空 | 保留dest内容 |
Source非空 | 覆盖dest内容 | 覆盖dest内容 |
Source种类 | 文件或目录 | 只能是目录 |
可移植性 | 一般(自行维护) | 强(docker托管) |
宿主直接访问 | 容易(仅需chown) | 受限(需登陆root用户)* |
详细区别请参考:https://blog.csdn.net/inrgihc/article/details/109001886
2.3.4、卷的删除
docker volume prune
删除未使用的卷
$ 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:
e6555d73c125e424f8fa71f8434933a9bd0c7668553fee5ae93f031db000c0c7
Total reclaimed space: 56.32kB
docker volume rm
直接删除正在使用的卷会报错:
$ docker volume rm test_volume_02
Error response from daemon: remove test_volume_02: volume is in use - [1b4f1ef946411b16fa6ea46c29099839ebfd6fd8d5210ea68be90975792bc635]
需要删除对应容器,然后再删除卷
$ docker stop 1b4f1ef946411b16fa6ea46c2
1b4f1ef946411b16fa6ea46c2
$ docker rm 1b4f1ef946411b16fa6ea46c2
1b4f1ef946411b16fa6ea46c2
$ docker volume rm test_volume_02
test_volume_02
2.4、匿名挂载和具名挂载
在 Docker 中,可以使用匿名挂载和具名挂载两种方式将主机文件系统或 Docker Volume 挂载到容器中。
2.4.1、匿名挂载
匿名挂载是指在创建容器时,不指定挂载卷的名称,直接将主机文件系统或 Docker Volume 挂载到容器中。匿名挂载的语法格式如下:
docker run -v <host-path>:<container-path> image-name
或
docker run --mount type=<type>,source=<source>,destination=<destination> image-name
这种方式会在容器内创建临时挂载点,其名称是由 Docker 自动生成的。一旦容器被删除,挂载点也会随之被删除。
例如,以下命令将主机上的 /data 目录匿名挂载到容器中的 /mydata 目录:
docker run -v /data:/mydata nginx
或
docker run --mount type=bind,source=/data,target=/mydata nginx
2.4.2、具名挂载
具名挂载是指在创建容器时,为挂载卷指定一个名称。具名挂载的语法格式如下:
docker run -v <volume-name>:<container-path> image-name
或
docker run --mount type=<type>,source=<volume-name>,destination=<destination> image-name
该方式将主机文件系统或 Docker Volume 挂载到容器中,并在容器内创建一个指定名称的挂载点。一旦容器被删除,挂载点和数据不会被删除,可以在其他容器中继续使用。
例如,以下命令将名为 my-volume 的 Docker Volume 挂载到容器中的 /mydata 目录:
docker run -v my-volume:/mydata nginx
或
docker run --mount type=volume,source=my-volume,target=/mydata nginx
综上所述,匿名挂载和具名挂载是将主机文件系统或 Docker Volume 挂载到容器中的两种方式。匿名挂载是一种快捷简单的方式,但不方便数据的管理和共享;具名挂载可以方便地对数据进行管理和共享,但需要手动创建和管理 Docker Volume。
2.5、卷的备份和还原
在 Docker 中,可以使用 docker volume 命令对数据卷进行备份和还原,以便在需要的时候恢复数据卷中的数据
2.5.1、备份数据卷
使用 docker run 命令创建一个带有 --rm 参数的容器,将要备份的数据卷挂载到容器中,并使用 tar 命令将数据卷中的数据打包成一个 tar 文件(容器挂载目录下)例如,以下命令将名为 my-volume 的数据卷备份到 /backup 目录下:
docker run --rm -v my-volume:/data -v /backup:/backup busybox tar czvf /backup/my-volume.tar.gz /data
该命令将创建一个临时容器,在容器中将 my-volume 数据卷挂载到 /data 目录,并将数据卷中的数据打包成一个 tar 文件,保存到主机上的 /backup 目录下。完成备份后,临时容器会被删除。
2.5.2、还原数据卷
如果需要恢复数据卷中的数据,可以使用 docker run 命令创建一个带有 --rm 参数的容器,将备份文件挂载到容器中,并使用 tar 命令解压备份文件到数据卷中。例如,以下命令从 /backup 目录中的 my-volume.tar.gz 文件还原 my-volume 数据卷:
docker run --rm -v my-volume:/data -v /backup:/backup busybox tar xzvf /backup/my-volume.tar.gz -C /data
该命令将创建一个临时容器,在容器中将备份文件 /backup/my-volume.tar.gz 挂载到 /backup 目录,并将备份文件中的数据解压到 my-volume 数据卷中。完成数据还原后,临时容器会被删除。
2.6、容器间卷的共享
使用 docker run --volumes-from
命令来在创建容器时,将一个或多个数据卷从已有的容器中挂载到新容器中,实现容器之间数据的共享和传递。以下是 docker run --volumes-from 命令的使用示例:
首先,假设已经有一个名为 my-container 的容器,该容器使用了一个名为 my-volume 的 Docker Volume,存储了一些数据。现在需要创建一个新的容器,使用 my-volume 数据卷中的数据,可以使用以下命令:
docker run --volumes-from my-container --name my-new-container image-name
该命令将创建一个名为 my-new-container 的新容器,并将 my-container 容器中使用的所有数据卷都挂载到 my-new-container 中。这样,在 my-new-container 中就可以使用 my-volume 数据卷中的数据,无需重新创建和初始化数据卷。
除了使用容器名称进行挂载,docker run --volumes-from 命令还支持使用容器 ID、容器名称前缀等方式进行挂载。例如,以下命令将使用 ID 为 123456 的容器中的所有数据卷挂载到新容器中:
docker run --volumes-from 123456 --name my-new-container image-name
需要注意的是,使用 docker run --volumes-from 命令挂载数据卷时,应该确保被挂载的容器和新建的容器都在同一个 Docker 主机上,否则将无法实现数据的共享和传递。
通过使用 docker run --volumes-from 命令,可以方便地将一个或多个数据卷从已有的容器中挂载到新容器中,实现容器之间数据的共享和传递。这个命令可以避免重复创建数据卷,提高容器的可复用性和可扩展性。
参考文档
1、https://blog.csdn.net/inrgihc/article/details/109001886
2、https://www.cnblogs.com/wwchihiro/p/9316504.html
3、https://blog.csdn.net/weixin_46618592/article/details/126591142
4、https://blog.csdn.net/qq_35745940/article/details/119336510
5、https://blog.frognew.com/2021/07/relearning-container-23.html
6、https://blog.csdn.net/gongdiwudu/article/details/128756465