Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Podman 核心概念

一、Podman 是什么(本质)

Podman = 一个符合 OCI 标准的容器管理 CLI 工具

它做的事情本质只有三类:

  1. 镜像管理(pull / push / build)
  2. 容器生命周期管理(create / start / stop / rm)
  3. Pod 管理(一组共享 namespace 的容器)

👉 Podman 不是容器运行时,它只是调度者。

二、Podman 架构(非常重要)

1️⃣ Podman 本身不运行容器

Podman 调用的是一整套 OCI 组件链:

podman
  ├─ containers/image   ← 镜像拉取 / registry / auth
  ├─ containers/storage ← 本地镜像/容器存储
  ├─ conmon             ← 容器监控
  ├─ OCI runtime        ← runc / crun
  └─ Linux kernel       ← namespaces / cgroups / selinux

📌 关键结论

  • Podman ≠ Docker daemon
  • Podman = CLI + OCI 生态整合器

三、Podman 与 Docker 的根本区别

对比点 Podman Docker
守护进程 ❌ 无 daemon ✅ dockerd
权限模型 root / rootless 以 root 为主
安全模型 更严格 较宽松
Pod 概念 原生支持 不支持
systemd 集成 原生 较弱
容器标准 OCI OCI

👉 Podman 天生为 server / 安全场景设计

四、Rootless Podman(你踩坑最多的地方)

1️⃣ 什么是 rootless

rootless = 不用 root 权限运行容器

实现依赖:

  • user namespace
  • subuid / subgid
  • fuse-overlayfs
  • slirp4netns
容器内 UID 0
   ↓ 映射
宿主机 UID 100000+

2️⃣ subuid / subgid(你刚遇到的问题)

作用:给普通用户一段 “可虚拟使用的 UID/GID 范围”

/etc/subuid
admin:100000:65536

表示:

容器 UID 宿主 UID
0 100000
1 100001

如果没有它,就会出现:

potentially insufficient UIDs or GIDs
lchown: invalid argument

📌 结论

rootless Podman ≈ 没有 subuid = 必死

五、镜像(Image)底层原理

1️⃣ 镜像不是一个文件

镜像是 多层(Layer)叠加:

Image
 ├─ Layer 1 (base)
 ├─ Layer 2
 ├─ Layer 3
 └─ config.json

每一层是一个 tar.gz blob

2️⃣ Manifest / Manifest List

你遇到的错误里多次出现:

manifest list

含义

类型 说明
manifest 单架构镜像
manifest list 多架构镜像(amd64 / arm64)

Podman pull 时流程:

manifest list
   ↓ 选择平台
manifest
   ↓ 拉取 blobs
layers unpack

六、为什么会出现 “writing blob / unpacking failed”

错误:

writing blob
unpacking failed
requested 0:50

本质原因

  1. 镜像 layer 中有文件:

    /var/local
    uid=0
    gid=50
    
  2. rootless 用户 没有 gid=50 的映射

  3. kernel 拒绝 lchown

  • 📌 不是网络问题
  • 📌 不是 registry 问题
  • 📌 是 user namespace 映射问题

七、Registry / 仓库模型

1️⃣ Podman 默认策略(非常严格)

行为 默认
HTTPS ✅ 必须
HTTP ❌ 禁止
自签证书
匿名访问 看 registry

2️⃣ registries.conf(核心配置)

这是 Podman 唯一认可的方式:

[[registry]]
location = "my-registry.local:5000"
insecure = true

📌 Podman 不支持:

podman pull --insecure

八、认证模型(authentication required)

Podman 使用:

~/.config/containers/auth.json

与 Docker 的 ~/.docker/config.json 完全兼容

podman login my-registry.local:5000

九、代理模型(HTTP_PROXY)

Podman 不理解 SOCKS

✅ 支持:

  • HTTP_PROXY
  • HTTPS_PROXY

❌ 不支持:

  • socks5://

正确方式:

HTTP_PROXY=http://127.0.0.1:1087 \
podman pull ...

十、Pod(Podman 的灵魂)

Pod 的定义

Pod = 共享 namespace 的一组容器

共享:

  • network
  • ipc
  • uts
Pod
 ├─ container A
 ├─ container B
 └─ pause container(隐式)

📌 和 Kubernetes Pod 概念 100% 对齐

十一、systemd 集成(Podman 的杀手锏)

Podman 可以直接生成 systemd 单元:

podman generate systemd --new --name mycontainer

结果是:

  • 无 daemon
  • 容器 = systemd service
  • 开机自启

👉 这就是为什么 Podman 特别适合服务器

十二、总结

Podman 是一个“安全优先 + 强约束 + 偏生产环境”的容器工具

  • Docker:开发友好
  • Podman:运维友好

前面遇到的所有问题:

  • subuid
  • HTTP registry
  • manifest
  • authentication
  • proxy

全部都是 Podman“默认安全策略”在生效