10、Docker 容器存储管理全解析
Docker 容器存储管理全解析
1. tmpfs 与 Secrets
tmpfs 类型将数据保存到内存中,不会写入主机文件系统。它适用于容器运行时使用的不需要持久化的应用程序或会话数据。tmpfs 挂载可以与容器共享敏感信息,如密钥和密码。Secrets 有两种类型:运行时和构建时。构建时的 Secrets 可通过 Buildah 在 Docker 中使用。
2. 卷与绑定挂载对比
Docker 官方推荐使用 Docker 卷来持久化数据,它相较于绑定挂载有诸多优势:
-
性能提升
:对于 Docker Desktop 用户,Docker 卷是 Docker 原生对象,性能优于绑定挂载。
-
远程主机和云集成
:Docker 卷可使用绑定挂载无法使用的专用、远程和云存储。
-
增强安全性
:插件和驱动程序支持卷加密和访问控制。
-
更好的所有权和权限管理
:Linux 系统(包括在 Windows Subsystem for Linux 下运行的系统)中的绑定挂载需要额外步骤来修复目录所有权,而卷则不需要。
-
备份和共享
:卷更易于备份和迁移,并且在多个容器之间共享更安全。
3. 容器与外部数据的关系
容器与外部数据存在关联,Docker 通过卷能更好地理解这种关系。在简单环境中,这种关系不太重要,但随着复杂度增加,了解数据的使用和存储位置就变得至关重要。例如,在运行 Oracle 数据库容器时,最初使用一个名为 oradata 的目录作为所有容器的根目录,每个容器绑定挂载到自己的子目录,手动管理一切。但随着挂载多个目录到一个容器或在多个容器之间共享目录,跟踪变得困难,删除目录的后果也更严重。
4. 挂载存储的方法
4.1 -v 或 –volume 选项
最终目的是将容器中的目标路径映射到主机上的源路径以写入数据。对于 -v 或 –volume 选项,它们以冒号分隔的有序对形式传递,源在前,目标在后。
-
绑定挂载
:源是一个目录,示例命令如下:
docker run ... \
-v /oradata/ORA19C:/opt/oracle/oradata \
...
docker run ... \
--volume /oradata/ORA19C:/opt/oracle/oradata \
...
- 卷挂载 :源是卷名,示例命令如下:
docker run ... \
-v oradata_ORA19C:/opt/oracle/oradata \
...
docker run ... \
--volume oradata_ORA19C:/opt/oracle/oradata \
...
4.2 –mount 选项
–mount 选项将元素分隔为命名的、逗号分隔的列表,元素顺序无关紧要。
-
绑定挂载目录
:
docker run ... \
--mount type=bind,source=/oradata/ORA19C,target=/opt/oracle/oradata \
...
- 挂载卷 :
docker run ... \
--mount type=volume,target=/opt/oracle/oradata,source=oradata_ORA19C \
...
–mount 语法中有一个额外的字段 type,用于告诉 Docker 使用的是卷还是绑定挂载。而在 -v 选项中,根据源是 Docker 卷还是目录来判断类型。
5. 未定义的卷
如果尝试将主机目录映射到容器中不存在的路径,Docker 会在容器中创建该目录。例如:
> docker run --rm -it \
> -v $HOME:/not/a/real/directory alpine
/ # ls -l /not/a/real/directory/
total 8302776
drwx------ 7 sean.scott staff 224 Mar 26 11:44 Applications
drwx------@ 88 sean.scott staff 2816 Apr 8 16:57 Desktop
drwx------+ 49 sean.scott staff 1568 Mar 16 08:31 Documents
...
也可以将目录挂载到容器中的现有路径。如果容器路径包含文件,Docker 会隐藏容器目标目录的内容,将源目录内容投影到上面。但需要注意的是,挂载现有非空目录到容器中,如果源目录缺少容器所需的文件,可能会产生意外和不良结果。
6. 入口点目录
镜像定义了启动命令,类似于物理或虚拟主机上的引导或初始化过程。启动命令在创建和启动容器时运行,指导它们执行预定义的工作。例如,Oracle 数据库容器启动时,会调用一个脚本检查数据库是否存在,如果存在则启动监听器和数据库,否则创建一个新数据库。
入口点目录是一种特殊的空目录,启动命令会扫描该目录中的额外脚本并以编程方式处理它们。目录位置和启动时如何评估内容完全取决于启动命令或脚本。
可以将卷或本地目录挂载到入口点目录,并使用自定义脚本填充它,从而更好地控制容器数据库。但由于该目录存在于容器外部,其内容的更改会影响未来的启动,可能导致意外结果。以下是挂载入口点目录的示例:
# 挂载单个目录
docker run ... \
--mount type=bind,source=$HOME/dbscripts,target=/docker-entrypoint-initdb.d \
...
# 挂载两个单独的目录
docker run ... \
--mount type=bind,source=$HOME/dbstartup,target=/opt/oracle/scripts/startup \
--mount type=bind,source=$HOME/dbsetup,target=/opt/oracle/scripts/setup \
...
当这些目录中有多个脚本时,Oracle 建议添加数字前缀以确保执行顺序,例如:
01_first_step.sql
02_second_step.sh
03_last_step.sql
7. 空间管理
7.1 查看 Docker 对象的空间使用情况
运行
docker system df
命令可以查看系统上 Docker 对象的空间使用情况,示例输出如下:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 29 2 157.3GB 143.7GB (91%)
Containers 2 2 540.6MB 0B (0%)
Local Volumes 8 0 15.42GB 15.42GB (100%)
Build Cache 138 0 41.05MB 41.05MB
该输出报告了 Docker 私有 /var/lib/docker 目录中使用空间的对象类型的摘要。
7.2 清理卷
通过
docker volume ls
命令查看卷列表时,可能会混淆本地卷和使用本地驱动的卷。可以通过
docker volume inspect
命令检查卷的元数据来确认。如果“ACTIVE”列下为零,则表示这些卷是孤立的,可以使用
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:
84c91dc6a3f0cb354243cb9ee2ca5a79933ca67
oradata_ORCL1_data
oradata_ORCL1_diag
4efabdab067033c973d00e73de9a05121e0cb70
9fc0fdc81eabd71a07f28a8d79fd2c1a5606747
oradata_ORCL1_audit
b26d713b83be8ac8f549f825d19cc2b6e6f19a6
2ac7d7486083a10a4ed313699e06eba017e63ba
运行清理命令后,再次使用
docker system df
命令检查空间使用情况,可以看到本地卷的数量和占用空间变为零。
7.3 清理镜像
docker image prune
命令用于删除“悬空”镜像,即未被任何容器使用且未标记名称的镜像。悬空镜像通常是在重建现有镜像并使用相同标签时产生的。示例如下:
> docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
如果有容器仍在使用悬空镜像,
docker image prune
不会删除它,只有在移除所有依赖后才会删除。
7.4 清理容器
docker container prune
命令用于删除系统中所有停止的容器,但需要谨慎使用,因为停止的容器不一定是无用的。示例如下:
> docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
7.5 清理系统
docker system prune
命令可以一次性清理系统中的停止容器、悬空镜像、未使用的网络和构建缓存。但同样需要谨慎使用,因为它会删除大量数据。示例如下:
> docker system prune
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all dangling images
- all dangling build cache
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
8. 哪种卷类型最佳
选择容器存储方式时,有几个标准会影响决策:
| 标准 | 说明 |
| ---- | ---- |
| 访问和导航 | 容器保存到卷的数据是否对本地操作系统用户可见? |
| Docker 管理 | Docker 是否将存储作为对象进行管理,将其与容器关联,并报告卷是否被使用? |
| 目录创建 | Docker 是否会自动在主机上创建不存在的目录路径? |
| 目录所有权 | 对于自动创建的目录,所有权是否设置正确? |
| 备份和保存数据 | 有哪些机制可用于复制和保存数据? |
| 跨平台一致性 | 该解决方案在所有平台(Windows、Mac 和 Linux)上的行为是否相同? |
需要根据这些标准,结合 Oracle 数据库和用户的具体需求,包括创建容器和支持对象所需的步骤以及备份或复制数据库 oradata 卷内容的难易程度,来选择最佳的存储选项。
综上所述,在 Docker 容器的使用过程中,合理选择和管理存储对于数据的持久化、安全性和性能至关重要。通过了解不同的挂载方式、卷类型以及空间管理方法,可以更好地应对各种复杂的应用场景。
Docker 容器存储管理全解析
9. 不同存储方式的操作与分析
9.1 tmpfs 存储操作
tmpfs 存储适用于临时数据,在容器运行时使用,且无需持久化。以下是一个简单的使用 tmpfs 挂载的示例:
docker run -it --tmpfs /tmp:size=100m ubuntu bash
上述命令创建了一个 Ubuntu 容器,并将一个大小为 100MB 的 tmpfs 挂载到容器的 /tmp 目录。在容器内,所有写入 /tmp 目录的数据都将存储在内存中,不会写入主机文件系统。
9.2 卷与绑定挂载的操作对比
我们通过具体操作来更深入地对比卷与绑定挂载。
创建绑定挂载 :
docker run -v /host/path:/container/path ubuntu ls /container/path
这个命令将主机的 /host/path 目录绑定挂载到容器的 /container/path 目录,并列出容器内该目录的内容。
创建卷挂载 :
docker volume create myvolume
docker run -v myvolume:/container/path ubuntu ls /container/path
首先创建一个名为 myvolume 的卷,然后将其挂载到容器的 /container/path 目录。
通过这些操作可以发现,绑定挂载直接使用主机上的目录,而卷挂载使用 Docker 管理的卷对象。
10. 存储管理的流程图分析
下面是一个简单的 Docker 存储管理流程图,展示了不同存储方式的选择和清理流程:
graph TD
A[选择存储方式] --> B{是否需要持久化}
B -->|是| C[选择卷或绑定挂载]
B -->|否| D[选择 tmpfs]
C --> E{是否需要云存储}
E -->|是| F[选择卷]
E -->|否| G{是否方便管理所有权}
G -->|是| H[选择卷]
G -->|否| I[选择绑定挂载]
J[空间管理] --> K{是否有未使用资源}
K -->|是| L{资源类型}
L -->|卷| M[docker volume prune]
L -->|镜像| N[docker image prune]
L -->|容器| O[docker container prune]
L -->|系统| P[docker system prune]
从这个流程图可以清晰地看到,在选择存储方式时,需要考虑数据是否需要持久化、是否需要云存储以及所有权管理的便利性等因素。在进行空间管理时,根据不同的资源类型选择相应的清理命令。
11. 不同存储方式对 Oracle 数据库的影响
当在容器中运行 Oracle 数据库时,不同的存储方式会产生不同的影响。
11.1 绑定挂载的使用与问题
最初使用绑定挂载时,将 oradata 目录作为根目录,每个容器绑定挂载到自己的子目录。但随着容器和挂载的复杂性增加,管理变得困难。例如,当多个目录挂载到一个容器或多个容器共享目录时,很难跟踪每个目录的使用情况,删除目录可能会导致严重后果。
11.2 卷的优势体现
使用卷可以更好地管理 Oracle 数据库的存储。卷可以与容器建立更清晰的关联,Docker 能够更好地理解容器与外部数据的关系。例如,一个 Oracle 数据库容器可能需要多个卷,分别用于诊断目录、配置文件、共享脚本和数据。使用卷可以更方便地管理这些关联,并且卷的备份和迁移也更加容易。
12. 存储管理的最佳实践总结
为了更好地管理 Docker 容器的存储,以下是一些最佳实践:
-
合理选择存储方式
:根据数据的特性和需求,选择合适的存储方式。对于需要持久化的数据,优先考虑卷;对于临时数据,选择 tmpfs。
-
定期进行空间清理
:定期运行
docker system df
命令检查空间使用情况,并使用相应的清理命令删除未使用的资源,如
docker volume prune
、
docker image prune
等。
-
使用卷管理复杂环境
:在复杂的容器环境中,使用卷来管理外部数据,让 Docker 更好地理解容器与数据的关系,便于跟踪和管理。
-
注意入口点目录的使用
:在使用入口点目录时,谨慎管理自定义脚本,避免因脚本问题导致容器启动异常。
13. 总结展望
通过对 Docker 容器存储管理的深入探讨,我们了解了不同的存储方式(如 tmpfs、卷和绑定挂载)的特点和使用方法,以及如何进行有效的空间管理。在实际应用中,需要根据具体的业务需求和环境特点,合理选择存储方式,并遵循最佳实践进行管理。
随着容器技术的不断发展,未来 Docker 可能会提供更多强大的存储管理功能,进一步简化存储管理的复杂性。对于开发者和运维人员来说,持续学习和掌握这些技术,将有助于更好地构建和管理容器化应用,提高系统的性能和可靠性。
希望本文能够帮助读者更好地理解 Docker 容器存储管理,在实际工作中更加得心应手地运用这些知识。
更多推荐



所有评论(0)