# 20.3 Podman 容器管理

Podman 是由红帽（Red Hat）主导开发的开源容器运行时，是 Docker 的替代方案，命令行接口与 Docker 高度兼容。Podman 采用无守护进程（daemonless）架构，每个容器作为独立进程运行，无需始终运行后台守护进程，提高了系统安全性，降低了单点故障风险。

在 FreeBSD 平台上，Podman 基于原生的 Jail 机制隔离容器，可使用命令 `jls` 查看当前运行的容器。通过 `sysctl -d security.jail.param` 可列出所有可供查询的 Jail 内核参数，这些参数反映了每个容器对应的底层 Jail 属性。

## 安装 Podman

安装 sysutils/podman-suite 元包时，会同时安装 sysutils/buildah（用于构建容器镜像）、sysutils/podman（容器运行时）、sysutils/skopeo（用于操作容器镜像）和 sysutils/catatonit（容器初始化进程）。

1. **使用 pkg 安装**：

   ```sh
   # pkg install podman-suite
   ```
2. **使用 Ports 安装**：

   ```sh
   # cd /usr/ports/sysutils/podman-suite/
   # make install clean
   ```
3. **查看安装后的配置信息**：

   ```sh
   # pkg info -D podman
   ```

## 配置 fstab 文件

在 FreeBSD 上使用 Podman，需要配置文件系统挂载点。fdescfs 是 FreeBSD 提供的文件描述符文件系统，可将进程的文件描述符映射为文件系统节点，Podman 依赖该文件系统在容器内部传递文件描述符。

将下列行写入 **/etc/fstab** 文件：

```ini
fdesc   /dev/fd         fdescfs         rw      0       0
```

然后执行下列命令使之立即生效：

```sh
# mount -t fdescfs fdesc /dev/fd
```

## 配置网络

Podman 借助 PF（Packet Filter）防火墙完成容器网络的地址转换与流量控制，容器可以通过宿主机网络接口访问外部网络。

首先复制 PF 配置文件示例：

```sh
# cp /usr/local/etc/containers/pf.conf.sample /etc/pf.conf
```

编辑 **/etc/pf.conf** 文件，将 `ix0` 替换为当前使用的网卡，可使用命令 `ifconfig` 查看：

```ini
# 设置 IPv4 出口网络接口
v4egress_if = "ix0"

# 设置 IPv6 出口网络接口
v6egress_if = "ix0"
```

接下来启动 PF 防火墙。`net.pf.filter_local=1` 参数的作用是将容器发往宿主机本地地址的连接重定向到容器内部，确保容器可以正常访问宿主机服务。

```sh
# kldload pf # 加载内核模块，仅需执行一次，以后会自动加载
# echo 'net.pf.filter_local=1' >> /etc/sysctl.conf.local # 将容器主机的连接重定向到容器内部
# sysctl net.pf.filter_local=1 # 立即生效
# service pf enable # 启用 pf 防火墙服务
# service pf start # 启动 pf 防火墙
```

## 创建 ZFS 存储池

管理容器的存储资源，建议创建专用的 ZFS 文件系统，具体操作如下：

创建 ZFS 文件系统 `zroot/containers`，并将挂载点设置为 **/var/db/containers**：

```sh
# zfs create -o mountpoint=/var/db/containers zroot/containers
```

## 启动服务

启动相关服务：

```sh
# service linux enable       # 设置 Linux 兼容服务开机自启
# service linux start        # 启动 Linux 兼容服务
# service podman enable      # 设置 Podman 服务开机自启
# service podman start       # 启动 Podman 服务
```

项目结构：

```sh
/
├── etc/
│   ├── fstab # 文件系统挂载配置
│   ├── pf.conf # PF 防火墙配置
│   └── sysctl.conf.local # 本地 sysctl 配置
├── dev/
│   └── fd/ # 文件描述符设备
├── run/
│   └── containers/
│       └── 0/
│           └── auth.json # 旧版认证凭据位置
├── root/
│   └── .config/
│       └── containers/
│           └── auth.json # 新版认证凭据位置
├── var/
│   └── db/
│       └── containers/ # 容器数据库目录
└── usr/
    ├── local/
    │   └── etc/
    │       └── containers/
    │           └── pf.conf.sample # PF 防火墙配置示例
    └── ports/
        └── sysutils/
            └── podman-suite/ # Podman Ports 目录
```

## 测试 Ubuntu 镜像

服务启动完成后，可测试拉取 Ubuntu 镜像验证 Podman 是否正常工作：

1. **测试拉取 Ubuntu 镜像**：

   ```sh
   # podman pull --os=linux docker.io/library/ubuntu:latest
   Trying to pull docker.io/library/ubuntu:latest...
   Getting image source signatures
   Copying blob 0622fac788ed done   |
   Copying config a0e45e2ce6 done   |
   Writing manifest to image destination
   a0e45e2ce6e6e22e73185397d162a64fcf2f80a41c597015cab05d9a7b5913ce
   ```
2. **查看当前拉取的镜像**：

   ```sh
   # podman images
   REPOSITORY                TAG         IMAGE ID      CREATED      SIZE
   docker.io/library/ubuntu  latest      a0e45e2ce6e6  3 weeks ago  80.6 MB
   ```
3. **打印系统版本（仅打印前 5 行）**：

   ```sh
   # podman run --os=linux ubuntu /usr/bin/cat "/etc/os-release" | head -5
   PRETTY_NAME="Ubuntu 24.04.2 LTS"
   NAME="Ubuntu"
   VERSION_ID="24.04"
   VERSION="24.04.2 LTS (Noble Numbat)"
   VERSION_CODENAME=noble
   ```
4. **进入容器**：

   ```sh
   # podman run -it --os=linux ubuntu /bin/bash # 进入容器
   root@3b6d47dea81e:/# apt update # 当前已进入容器内部
   Get:1 http://archive.ubuntu.com/ubuntu noble InRelease [256 kB]
   Get:2 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]

   ……以下省略……

   root@3b6d47dea81e:/# exit # 退出容器
   exit
   # # 已返回宿主机
   ```

## 测试 FreeBSD 维护者打包的 Nginx 容器

除了 Linux 镜像外，Podman 也可以运行 FreeBSD 原生容器。本节测试 FreeBSD 维护者打包的 Nginx 容器：

```sh
# 从 quay.io 拉取 nginx 镜像
# podman pull quay.io/dougrabson/nginx

# 使用该镜像创建并后台运行容器 mynginx，将宿主机 8080 端口映射到容器 80 端口
# podman run -d --name mynginx -p 8080:80 quay.io/dougrabson/nginx
```

在浏览器中打开 `http://ip:8080` 即可访问 Nginx 测试页面。

## 更多用法

1. **查看日志**：

   ```sh
   # podman logs 容器名称
   ```
2. **查看容器运行状态**：

   ```sh
   # podman ps # 查看当前运行的容器
   CONTAINER ID  IMAGE                            COMMAND               CREATED STATUS        PORTS                 NAMES
   ca088c9c56fc  quay.io/dougrabson/nginx:latest  /usr/local/sbin/n...  3 minutes agoUp 3 minutes  0.0.0.0:8080->80/tcp  mynginx
   # podman ps -a # 查看所有状态，包括运行失败的容器
   CONTAINER ID  IMAGE                            COMMAND               CREATED STATUS                     PORTS                              NAMES
   e8ea65b7e6c9  docker.io/library/nginx:latest   nginx -g daemon o...  17 minutes ago Exited (0) 292 years ago   0.0.0.0:8080->80/tcp               nginx-test
   ca088c9c56fc  quay.io/dougrabson/nginx:latest  /usr/local/sbin/n...  3 minutes ago Up 3 minutes               0.0.0.0:8080->80/tcp               mynginx
   ```
3. **停止并删除容器**：

   ```sh
   # podman stop 容器名称 # 停止容器
   # podman rm 容器名称  # 删除容器
   ```
4. **删除镜像（必须先删除引用该镜像的容器）**：

   ```sh
   # podman rmi 镜像名称
   ```

## 使用 FreeBSD 容器

除了第三方维护者提供的容器外，也可以直接从 Docker Hub 拉取官方的 FreeBSD 镜像：

```sh
# podman pull docker://freebsd/freebsd-runtime:14.2
```

## 参考文献

* freebsd/freebsd-runtime\[EB/OL]. \[2026-03-26]. <https://hub.docker.com/r/freebsd/freebsd-runtime/tags>. Docker Hub 上 FreeBSD 官方运行时基础镜像的标签列表。
* Podman 项目. Podman Installation Instructions\[EB/OL]. \[2026-03-25]. <https://podman.io/docs/installation>. 官方安装教程，详述 Podman 部署步骤。
* Josphat Mutai. Install Podman and run Containers in FreeBSD 14\[EB/OL]. cloudspinx.com, \[2026-03-25]. <https://cloudspinx.com/install-podman-and-run-containers-in-freebsd/>. 提供 FreeBSD 14 上 Podman 实用配置指南。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/di-20-zhang-xu-ni-hua-yu-rong-qi-guan-li/di-20.3-jie-podman-rong-qi-guan-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
