Podman 无守护进程容器引擎
bash sudo apt update sudo apt install -y podman
**Fedora**
```bash
sudo dnf install -y podman
CentOS/RHEL 8 及以上
sudo dnf install -y podman
Arch Linux
sudo pacman -S podman
安装完成后,验证版本:
podman --version
macOS 与 Windows
在非 Linux 平台上,Podman 通过一个虚拟机(通常由 podman machine 管理)来运行 Linux 容器。
macOS
brew install podman
podman machine init # 初始化虚拟机
podman machine start # 启动虚拟机
Windows
可以从 Podman GitHub Releases 下载 Windows 安装程序,或使用 winget:
winget install RedHat.Podman
podman machine init
podman machine start
提示:在 macOS/Windows 上使用 Podman 时,Docker API 兼容的套接字默认不启动。如果希望用 Docker CLI 直接连接 Podman,可以执行
podman machine start后设置DOCKER_HOST环境变量,或使用podman system connection管理连接。
基础命令完全兼容 Docker
Podman 的命令设计原则是:如果你会使用 Docker,那么你已经会使用 Podman。下面列出几个最常见的操作。
运行容器
podman run -d --name web -p 8080:80 nginx:alpine
参数 -d 表示后台运行,-p 映射主机端口,--name 指定容器名称。
查看容器
podman ps # 运行中的容器
podman ps -a # 所有容器(包括已停止)
停止与删除容器
podman stop web
podman rm web
镜像管理
podman images # 列出本地镜像
podman pull docker.io/alpine:latest # 拉取镜像
podman rmi alpine:latest # 删除镜像
执行命令与日志
podman exec -it web sh # 进入容器
podman logs web # 查看日志
清理不再使用的资源
podman container prune # 删除所有已停止的容器
podman image prune # 删除未被使用的镜像
podman system prune -a # 清理所有未使用的容器、镜像、网络
小技巧:如果你想让现有脚本无缝切换,可以在
~/.bashrc或~/.zshrc中添加:alias docker=podman
Rootless 容器深入
Podman 默认以当前用户身份运行容器(Rootless 模式),无需 sudo。这背后依赖于 Linux 的 用户命名空间 (User Namespaces)。
用户命名空间的工作原理
在 Rootless 模式下,容器内的 root 用户被映射为主机上的一个普通用户。这带来了两个直接好处:
- 即使容器进程获得
root权限,它们在主机上也仅拥有当前用户的权限。 - 容器无法直接访问主机上的特权资源(如绑定低端口号
<1024需要额外的配置)。
然而,Rootless 容器也有一些限制,例如默认不能直接绑定到低于 1024 的端口。解决办法是使用 podman unshare 调整命名空间或给 podman 可执行文件添加 net_bind_service 能力(较少推荐)。通常你可以通过将主机高端口映射到容器的低端口来绕开限制,例如:
podman run -p 8080:80 nginx:alpine # 主机8080 -> 容器80
数据卷与文件权限
在 Rootless 环境下,卷中的数据所有权可能显得混乱。容器内的 root 创建的文件在主机上会显示为你的用户 ID。如果你需要在主机和容器之间共享文件且保持正确的权限,可以使用 :Z 或 :z 标志来重新标记 SELinux 上下文(如果启用了 SELinux),或使用 --userns=keep-id 等选项精细控制映射。
示例:
podman run -v $(pwd)/data:/data:Z nginx
Pod:原生 Kubernetes 风格的容器组
Podman 的一个独特优势是原生支持 Pod。Pod 是一组共享网络命名空间和 IPC 命名空间的容器,这与 Kubernetes 中的 Pod 概念完全相同。在本地开发微服务时非常有用。
创建 Pod
podman pod create --name myapp -p 8080:80
上述命令创建了一个名为 myapp 的 Pod,并将主机的 8080 端口映射到 Pod 的 80 端口(所有 Pod 内的容器共享该端口绑定)。
向 Pod 中添加容器
podman run -d --pod myapp --name web nginx:alpine
podman run -d --pod myapp --name api my-api-image
现在 web 和 api 两个容器共享同一个网络命名空间,它们可以通过 localhost 互相通信。API 容器监听在某个端口,Nginx 可以直接 proxy_pass http://localhost:3000; 这样的地址。
管理 Pod
podman pod ps # 查看所有 Pod
podman pod stop myapp # 停止 Pod 中的所有容器
podman pod rm myapp # 删除 Pod 及其容器
podman pod top myapp # 查看 Pod 内进程
生成 Kubernetes YAML
你可以将本地 Pod 导出为 Kubernetes 兼容的 YAML 清单,然后直接部署到 Kubernetes 集群中:
podman generate kube myapp > myapp.yaml
# 在 Kubernetes 集群上应用
kubectl apply -f myapp.yaml
反过来,你也可以在 Podman 中运行 Kubernetes Pod 定义:
podman play kube myapp.yaml
这个双向转换让 Podman 成为本地开发与 CI/CD 流程中的得力助手。
使用 systemd 管理容器服务
Podman 与 systemd 的集成是其一大亮点。你可以将任何容器(或 Pod)转换为 systemd 服务,从而实现开机自启、自动重启、日志集成等。
为容器生成 systemd 单元文件
假设一个运行中的容器名为 web:
podman generate systemd --name web --new > ~/.config/systemd/user/container-web.service
参数 --new 表示每次启动服务时都会创建一个新的容器实例,这更符合无状态容器的理念。
然后重新加载用户级 systemd 并启动服务:
systemctl --user daemon-reload
systemctl --user enable --now container-web.service
注意:要使用户级 systemd 服务在用户未登录时依然运行,需要开启
linger:sudo loginctl enable-linger $USER
对于 Pod,生成服务的方法类似:
podman generate systemd --name myapp --new > ~/.config/systemd/user/pod-myapp.service
高级特性概览
构建镜像
Podman 使用 buildah 作为后端,你可以使用与原 Docker 几乎一致的 podman build 命令:
podman build -t myimage:v1 .
Podman 也支持多阶段构建和 BuildKit 风格的构建(通过 --format 参数指定)。
无守护进程的容器注册表
Podman 可以使用 podman run 运行一个分发容器,自己搭建简单的私有注册表,但更吸引人的是,你可以直接通过 skopeo 工具与注册表交互(如检查镜像、复制镜像),无需守护进程。
网络管理
Podman 使用 netavark 或 CNI 网络栈。你可以创建自定义网络:
podman network create mynet
podman run --network mynet ...
DNS 解析和网络隔离默认提供。在 Pod 内部,容器可通过名称相互访问。
使用 Docker Compose
Podman 支持 Docker Compose!安装 podman-docker 包(或者直接使用 podman-compose 工具)后,你可以像以往一样使用 docker-compose 命令。通常推荐使用独立的 podman-compose Python 包:
pip3 install podman-compose
podman-compose up -d