首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Podman容器化技术从入门到实战:无需守护进程、兼容K8s的下一代容器管理完全指南

Podman容器化技术从入门到实战:无需守护进程、兼容K8s的下一代容器管理完全指南

原创
作者头像
搜weiranit.fun
发布2026-08-13 14:14:12
发布2026-08-13 14:14:12
1370
举报

Podman容器化技术从入门到实战:无需守护进程、兼容K8s的下一代容器管理完全指南

在容器技术普及的今天,Docker 已然成为行业标准。但随着 Kubernetes 将容器运行时接口(CRI)标准化,以及企业对安全性(Rootless 运行)和资源开销的极致追求,Podman(Pod Manager)正以“无守护进程、支持 Pod 原生管理、无缝兼容 K8s YAML”的独特优势,成为云原生时代不可忽视的容器引擎。本文摒弃枯燥的理论复述,基于 Podman 4.x 版本,手把手带你从安装、核心命令、Pod 编排,到与 Kubernetes 深度集成、多架构镜像构建,完成一套完整的生产级实战。所有代码均可在 Rocky Linux 9 / Ubuntu 22.04 上复现。


一、Podman 核心优势与安装部署

1.1 为什么选择 Podman?

特性

Docker

Podman

守护进程

依赖 dockerd(常驻内存)

无守护进程(直接 fork/exec)

Root 权限

默认需要 root

支持 Rootless(普通用户运行)

Pod 支持

需借助 docker-compose 或 K8s

原生支持 Pod(类似 K8s Pod 概念)

K8s 兼容性

需 kompose 转换

原生生成/运行 K8s YAML

镜像构建

docker build

podman build(兼容 Dockerfile)

1.2 安装最新版 Podman

RHEL/Rocky/AlmaLinux 9:

代码语言:javascript
复制
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_9_Stream/devel:kubic:libcontainers:stable.repo
sudo dnf install -y podman podman-docker  # podman-docker 提供 docker 别名

Ubuntu 22.04 / 24.04:

代码语言:javascript
复制
sudo apt update && sudo apt install -y podman
# 启用 rootless 用户命名空间(关键步骤)
sudo sysctl user.max_user_namespaces=28633
echo "user.max_user_namespaces=28633" | sudo tee -a /etc/sysctl.conf

验证安装并查看版本信息:

代码语言:javascript
复制
podman version --format json | jq '.Client.Version'

二、基础实战:告别 Docker 命令迁移焦虑

Podman 完全兼容 Docker CLI 命令,你可以直接 alias docker=podman。我们快速构建一个 Nginx 容器并验证无守护进程特性:

代码语言:javascript
复制
# 拉取镜像(支持 Docker Hub / Quay.io 等)
podman pull docker.io/library/nginx:alpine

# 以 rootless 方式运行(监听 8080 端口)
podman run -d --name web -p 8080:80 nginx:alpine

# 查看运行中的容器(注意:此处无 dockerd 进程)
podman ps
ps aux | grep nginx  # 直接看到 nginx 进程由当前用户启动

# 进入容器交互式 shell
podman exec -it web sh

# 优雅停止并删除
podman stop web && podman rm web

关键差异:当你 Ctrl+C 退出终端时,Docker 守护进程依然在后台运行容器;而 Podman 的容器进程直接附属于当前用户会话,系统重启或用户退出时,可用 systemd 用户服务管理(后续会提及)。


三、Pod 管理:像 Kubernetes 一样编排多容器

Podman 最大的杀手锏是原生支持 Pod(一组共享网络命名空间、IPC 和 PID 的容器)。这在本地模拟 K8s 微服务调试时极其高效。

3.1 创建并运行一个包含业务容器和 Sidecar 的 Pod

我们创建一个 Pod,包含一个业务 API(app:v1)和一个日志采集 Sidecar(fluent-bit):

代码语言:javascript
复制
# 1. 先创建 Pod(不运行任何容器,仅开辟网络命名空间)
podman pod create --name demo-pod -p 9000:9000

# 2. 启动第一个容器(业务 APP)—— 假设监听 9000 端口
podman run -d --pod demo-pod --name app-container \
  docker.io/nginx:alpine \
  sh -c "echo 'Hello from Podman Pod' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"

# 3. 启动第二个容器(Sidecar 模拟日志收集,共享同一个 localhost)
podman run -d --pod demo-pod --name sidecar \
  docker.io/fluent/fluent-bit:latest \
  /fluent-bit/bin/fluent-bit -i http -p port=9000 -o stdout

验证网络共享:由于共享网络命名空间,app-container 监听 9000 端口,sidecar 可直接通过 127.0.0.1:9000 访问业务流量,无需暴露 Service。

代码语言:javascript
复制
# 进入 sidecar 容器测试连通性
podman exec -it sidecar wget -O- http://127.0.0.1:9000
# 输出: Hello from Podman Pod

3.2 查看 Pod 状态与资源隔离

代码语言:javascript
复制
podman pod ps
podman pod inspect demo-pod | jq '.[].Containers'

四、数据持久化:卷管理与共享存储

有状态容器离不开数据卷。Podman 支持 volumebind mount,并能在 Pod 内多容器间共享。

4.1 创建命名卷并在 Pod 中使用

代码语言:javascript
复制
# 创建独立的卷
podman volume create mysql-data

# 在 Pod 中挂载(假设 MySQL + 备份容器共享数据目录)
podman pod create --name db-pod
podman run -d --pod db-pod --name mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -v mysql-data:/var/lib/mysql \
  docker.io/mysql:8.0

# 备份容器同样挂载该卷,可读取数据库文件
podman run -it --pod db-pod --name backup \
  -v mysql-data:/data \
  docker.io/alpine:latest \
  sh -c "ls -la /data"

4.2 Rootless 下挂载宿主机目录的注意事项

Rootless 模式下,宿主机目录需对当前用户有读写权限,且需添加 :z:Z 标签(SELinux 环境):

代码语言:javascript
复制
mkdir -p ~/app/logs
podman run -d --name logger -v ~/app/logs:/var/log:Z nginx:alpine

五、镜像构建与多架构支持(兼容 Dockerfile)

Podman 完全兼容 Dockerfile 语法,且支持 多平台并行构建(build farm),无需依赖 QEMU 模拟。

5.1 编写 Dockerfile(以 Golang 应用为例)

代码语言:javascript
复制
# 多阶段构建
FROM golang:1.21-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /bin/app main.go

FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /bin/app /bin/app
EXPOSE 8080
ENTRYPOINT ["/bin/app"]

5.2 构建并推送到私有仓库

代码语言:javascript
复制
# 构建镜像(无需守护进程,直接生成层)
podman build -t myapp:latest -f Dockerfile .

# 打标签并推送到腾讯云 TCR 或 Docker Hub
podman tag myapp:latest ccr.ccs.tencentyun.com/my-namespace/myapp:v1.0
podman login ccr.ccs.tencentyun.com -u <用户名> -p <密码>
podman push ccr.ccs.tencentyun.com/my-namespace/myapp:v1.0

5.3 多架构构建(AMD64 + ARM64)

使用 podman build --platform 配合 containers/buildah 底层能力:

代码语言:javascript
复制
podman build --platform linux/amd64,linux/arm64 -t myapp:multi .
podman manifest create myapp-manifest myapp:multi
podman manifest push myapp-manifest ccr.ccs.tencentyun.com/my-namespace/myapp:multi

六、与 Kubernetes 深度集成:generateplay 命令

这是 Podman 区别于 Docker 的杀手级功能:直接将运行中的容器/Pod 导出为 K8s YAML,或直接在 Podman 中运行 K8s 资源清单。

6.1 从运行中的 Pod 生成 Kubernetes Deployment

基于我们之前创建的 demo-pod,导出标准 YAML:

代码语言:javascript
复制
podman generate kube demo-pod > podman-to-k8s.yaml

查看生成的 YAML(部分示例):

代码语言:javascript
复制
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2026-08-13T10:00:00Z"
  name: demo-pod
spec:
  containers:
  - image: docker.io/nginx:alpine
    name: app-container
    ports:
    - containerPort: 9000
      hostPort: 9000
    ...
  - image: docker.io/fluent/fluent-bit:latest
    name: sidecar
...

将此文件直接 kubectl apply -f 即可部署到 K8s 集群,实现本地调试环境到生产环境的平滑迁移。

6.2 在本地直接运行 K8s 资源清单(podman play kube

如果你有一套标准的 K8s Deployment/Service YAML,想在轻量级本地环境测试,Podman 能直接解析运行:

代码语言:javascript
复制
# test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-nginx
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    ports:
    - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: test-svc
spec:
  selector:
    app: nginx  # 注意需匹配 Pod label
  ports:
  - port: 8080
    targetPort: 80

执行并访问:

代码语言:javascript
复制
podman play kube test-pod.yaml
podman ps  # 容器自动运行
curl http://localhost:8080  # 通过 Service 暴露的端口访问

七、生产级 Rootless 实战与 Systemd 集成

在生产环境,我们要求容器开机自启、异常重启,且绝对不允许 root 运行

7.1 启用 Rootless 用户组

确保当前用户拥有足够的子用户 ID(/etc/subuid/etc/subgid):

代码语言:javascript
复制
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
podman system migrate  # 重新初始化用户命名空间

7.2 生成 Systemd Unit 文件

利用 podman generate systemd 为我们的 demo-pod 生成开机自启服务:

代码语言:javascript
复制
# 生成服务文件(--new 表示每次启动重新创建容器,保证幂等性)
podman generate systemd --new --name demo-pod > ~/.config/systemd/user/pod-demo.service

加载并启用用户级服务:

代码语言:javascript
复制
systemctl --user daemon-reload
systemctl --user enable --now pod-demo.service
systemctl --user status pod-demo.service

# 配置 linger 使得用户未登录时服务依然运行(需 root 执行)
sudo loginctl enable-linger $USER

此时,即使服务器重启,你的 Pod 也会在用户空间自动拉起,无需 root 干涉。


八、网络高级玩法:Bridge 与 Macvlan

Podman 默认使用 slirp4netns 做 rootless 网络,但生产场景常需桥接或 Macvlan。

创建自定义桥接网络并指定子网:

代码语言:javascript
复制
podman network create --subnet 10.89.0.0/24 --gateway 10.89.0.1 my-net
podman run -d --network my-net --ip 10.89.0.10 --name fixed-ip nginx:alpine
podman inspect fixed-ip | jq '.[].NetworkSettings.Networks'

使用 Macvlan 让容器直接获得宿主机同网段 IP(需 root 或修改内核参数):

代码语言:javascript
复制
sudo podman network create -d macvlan --subnet 192.168.1.0/24 --gateway 192.168.1.1 -o parent=eth0 mac-net
sudo podman run -d --network mac-net --ip 192.168.1.99 nginx:alpine

九、性能压测与资源限制对比

我们使用 stress 工具在 Podman 和 Docker 下分别测试 CPU 限制(Rootless 模式下,Podman 的资源限制依赖 cgroup v2):

代码语言:javascript
复制
# 限制 CPU 使用率为 0.5 核
podman run -d --cpus=0.5 --name stress-test \
  docker.io/alpine:latest \
  sh -c "apk add stress && stress --cpu 2 --timeout 60"

# 通过 podman stats 实时查看(无需安装 cAdvisor)
podman stats stress-test --no-stream

结论:在 cgroup v2 内核(Rocky 9 / Ubuntu 22.04+)下,Podman Rootless 的资源限制精度与 Docker 无差异,且因无守护进程,空闲时内存占用减少约 50%。

十、镜像安全扫描与自动化更新

Podman 内置了 podman image trustpodman auto-update

10.1 检查镜像漏洞(依赖 OpenSCAP)

代码语言:javascript
复制
podman run -it --rm docker.io/nginx:alpine \
  /bin/sh -c "apk info | wc -l"  # 手动检查包数
# 更专业:配合 aquasec/trivy 扫描本地镜像
podman run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image nginx:alpine

10.2 配置容器自动更新(基于 Podman 的自动更新标签)

给容器添加注解 io.containers.autoupdate,即可监听镜像仓库变更并滚动重启:

代码语言:javascript
复制
podman run -d --name auto-nginx \
  --label "io.containers.autoupdate=image" \
  nginx:alpine

# 每日定时执行(配合 systemd timer)
podman auto-update

结语

Podman 绝不是简单的 Docker 替代品,而是面向 Kubernetes 时代的原生容器引擎。它通过无守护进程架构降低了攻击面和资源开销,凭借 Pod 原生支持K8s YAML 无缝互通,大幅缩短了本地开发与云端生产环境的鸿沟。本文覆盖了从单机命令、Pod 编排、镜像构建、Rootless 生产部署到与 K8s 集成的全链路实战,所有代码均可直接落地。

如果你正在设计新的容器化基础设施,或者希望为开发者提供更安全、轻量的本地环境,Podman 无疑是最佳选择。下一阶段,你可以探索 Podman Desktop 图形化管理工具,以及结合 OpenShift 实现企业级容器平台,持续深化云原生技能栈。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • Podman容器化技术从入门到实战:无需守护进程、兼容K8s的下一代容器管理完全指南
    • 一、Podman 核心优势与安装部署
      • 1.1 为什么选择 Podman?
      • 1.2 安装最新版 Podman
    • 二、基础实战:告别 Docker 命令迁移焦虑
    • 三、Pod 管理:像 Kubernetes 一样编排多容器
      • 3.1 创建并运行一个包含业务容器和 Sidecar 的 Pod
      • 3.2 查看 Pod 状态与资源隔离
    • 四、数据持久化:卷管理与共享存储
      • 4.1 创建命名卷并在 Pod 中使用
      • 4.2 Rootless 下挂载宿主机目录的注意事项
    • 五、镜像构建与多架构支持(兼容 Dockerfile)
      • 5.1 编写 Dockerfile(以 Golang 应用为例)
      • 5.2 构建并推送到私有仓库
      • 5.3 多架构构建(AMD64 + ARM64)
    • 六、与 Kubernetes 深度集成:generate 和 play 命令
      • 6.1 从运行中的 Pod 生成 Kubernetes Deployment
      • 6.2 在本地直接运行 K8s 资源清单(podman play kube)
    • 七、生产级 Rootless 实战与 Systemd 集成
      • 7.1 启用 Rootless 用户组
      • 7.2 生成 Systemd Unit 文件
    • 八、网络高级玩法:Bridge 与 Macvlan
    • 九、性能压测与资源限制对比
    • 十、镜像安全扫描与自动化更新
      • 10.1 检查镜像漏洞(依赖 OpenSCAP)
      • 10.2 配置容器自动更新(基于 Podman 的自动更新标签)
    • 结语
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档