容器数据存储实现全解析
立即解锁
发布时间: 2025-08-26 00:06:46 阅读量: 4 订阅数: 13 


Podman for DevOps: 从理论到实践的容器化指南
### 容器数据存储实现全解析
#### 1. 容器运行根目录(runroot)概述
容器存储程序会将容器产生的所有临时可写内容存于 runroot 目录。若查看运行容器所在主机上的该文件夹,会发现有个以容器 ID 命名的文件夹,其中包含各种已挂载到容器以替换原始文件的文件。例如:
```bash
# ls -l /run/containers/storage/overlay-containers/
bd0eef7cd50760dd52c24550be51535bc11559e52eea7d782a1fa69765
24fa76/userdata
total 20
-rw-r--r--. 1 root root 6 16 oct 00.38 conmon.pid
-rw-r--r--. 1 root root 12 16 oct 00.38 hostname
-rw-r--r--. 1 root root 230 16 oct 00.38 hosts
-rw-r--r--. 1 root root 0 16 oct 00.38 oci-log
-rwx------. 1 root root 6 16 oct 00.38 pidfile
-rw-r--r--. 1 root root 34 16 oct 00.38 resolv.conf
drwxr-xr-x. 3 root root 60 16 oct 00.38 run
```
从上述输出可知,runroot 路径下的容器文件夹包含直接挂载到容器以进行定制的各种文件。
#### 2. 在容器内外复制文件
Podman 允许用户在运行的容器内外移动文件,通过 `podman cp` 命令实现。
- **将文件从容器复制到主机**
1. 启动一个新的 Alpine 容器:
```bash
$ podman run -d --name alpine_cp_test alpine sleep 1000
```
2. 从容器中获取文件(如 `/etc/os-release`)并复制到主机的 `/tmp` 文件夹:
```bash
$ podman cp alpine_cp_test:/etc/os-release /tmp
```
3. 查看复制到主机的文件内容:
```bash
$ cat /tmp/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.14.2
PRETTY_NAME="Alpine Linux v3.14"
HOME_URL=https://alpinelinux.org/
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
```
- **将文件从主机复制到容器**
```bash
$ podman cp /tmp/build_folder alpine_cp_test:/
```
此命令将 `/tmp/build_folder` 文件夹及其所有内容复制到 Alpine 容器的根文件系统下。可以使用 `podman exec` 和 `ls` 实用命令检查复制命令的结果。
#### 3. 与 overlayfs 交互
还可通过 `podman mount` 命令直接与合并的覆盖层交互,将文件从容器复制到主机。
- 对于无特权容器,首先运行 `podman unshare` 命令,允许用户在修改后的用户命名空间内运行命令:
```bash
$ podman unshare
```
此命令会在配置了 UID 0 和 GID 0 的新用户命名空间中启动一个根 shell。
- 运行 `podman mount` 命令并获取挂载点的绝对路径:
```bash
# cd $(podman mount alpine_cp_test)
```
上述命令使用 shell 扩展切换到 MergedDir 的路径,该路径合并了 LowerDir 和 UpperDir 的内容,提供不同层的统一视图。此后,就可以在容器根文件系统内外复制文件。
对于有特权容器,操作类似,但需在命令前加上 `sudo`。例如,启动一个有特权的 Nginx 容器并复制文件:
```bash
$ sudo podman run -d \
--name rootful_nginx docker.io/library/nginx
$ sudo podman cp \
rootful_nginx:/usr/share/nginx/html/index.html /tmp
```
#### 4. 使用 podman commit 持久化更改
前面的操作并非永久定制运行中容器的方法,因为容器的不可变性质意味着持久修改应通过重建镜像来实现。但如果需要在不启动新构建的情况下保留更改并生成新镜像,`podman commit` 命令可将容器的更改持久化到新镜像中。
- 示例:更新 Nginx 容器的默认 `index.html` 页面并持久化更改
1. 创建一个新的 `index.html` 文件:
```bash
$ echo "Hello World!" > /tmp/index.html
```
2. 启动一个 Nginx 容器:
```bash
$ podman run --name custom_nginx -d -p \
8080:80 docker.io/library/nginx
```
3. 将新的 `index.html` 文件复制到容器中:
```bash
$ podman cp /tmp/index.html \
custom_nginx:/usr/share/nginx/html/
```
4. 测试更改:
```bash
$ curl localhost:8080
Hello World!
```
5. 使用 `podman commit` 命令将更改持久化到新镜像:
```bash
$ podman commit -p custom_nginx hello-world-nginx
```
6. 停止并移除原容器:
```bash
$ podman stop custom_nginx && podman rm custom_nginx
```
7. 测试新的自定义镜像:
```bash
$ podman run -d -p 8080:80 --name hello_world \
localhost/hello-world-nginx
$ curl localhost:8080
Hello World!
```
#### 5. 容器存储挂载方式总结
| 操作类型 | 方法 | 说明 |
| ---- | ---- | ---- |
| 容器内外文件复制 | podman cp | 简单直接,可在容器与主机间复制文件和文件夹 |
| 与 overlayfs 交互复制文件 | podman mount | 适用于通过与合并的覆盖层交互复制文件 |
| 持久化容器更改 | podman commit | 将容器更改持久化到新镜像 |
#### 6. 容器存储挂载操作流程图
```mermaid
graph LR
A[启动容器] --> B[容器内外复制文件]
B --> C{复制方式}
C -->|podman cp| D[普通复制]
C -->|podman mount| E[与 overlayfs 交互复制]
B --> F[持久化更改]
F --> G[podman commit]
```
0
0
复制全文
相关推荐










