视频加载失败

podman安装使用

3038 字
15 分钟
podman安装使用
podman安装使用

一、podman简介#

Podman 是一个开源的容器引擎,由 Red Hat 主导开发,遵循 OCI(开放容器倡议)标准,用于管理容器、镜像和 Pod。 简单说,它就是一个可以替代 Docker 的容器管理工具,命令行几乎一模一样,但架构设计上有本质区别。

1.1 核心特点#

  • 无守护进程(Daemonless) Podman 不依赖常驻后台的守护进程(如 Docker 的 dockerd),而是直接通过 fork/exec 调用 OCI 运行时(runc/crun)启动容器。每个容器都是独立的子进程,由 systemd 或用户会话直接管理,消除了单点故障风险,空闲时几乎不占用系统资源。
  • 原生 Rootless 模式 默认以普通用户权限运行容器,容器内的 root 用户通过 Linux 用户命名空间映射为宿主机上的非特权用户。即使容器逃逸,攻击面也被限制在当前用户范围内,符合最小权限原则。

  • 原生 Pod 支持 内置 Kubernetes Pod 概念,可以将多个容器组合为一个逻辑单元,共享网络和 IPC 命名空间。支持通过 podman generate kube 导出 K8s YAML,或通过 podman play kube 直接运行 K8s 配置,方便本地开发与生产环境衔接。

  • 高度兼容 Docker 命令行与 Docker 90% 以上兼容,支持 alias docker=podman 直接替换。兼容 Docker 镜像格式、Dockerfile 语法以及 Docker Hub 等镜像仓库。

  • 深度集成 systemd 可通过 podman generate systemd 生成 systemd 服务单元文件,将容器作为系统服务管理,实现开机自启、故障自动重启和日志接入 journald。

1.2 与Docker的主要区别#

维度DockerPodman
架构C/S 架构,依赖 dockerd 守护进程无守护进程,直接 fork/exec
权限默认需 root,Rootless 需额外配置原生 Rootless,默认普通用户运行
Pod 支持需借助 Compose 或 Swarm原生支持
K8s 集成需额外工具原生支持生成/运行 K8s YAML
镜像构建内置 docker build内置 + Buildah 独立构建
跨平台成熟(Linux/Win/Mac)Linux 为主,Win/Mac 需虚拟机
许可桌面版对企业收费完全开源免费

1.3 适用场景#

  • 生产环境 / 安全敏感场景:Rootless 和无守护进程架构降低了攻击面,适合金融、政务等对安全要求高的环境。
  • Kubernetes 迁移准备:原生 Pod 支持和 K8s YAML 互转能力,让本地开发到 K8s 部署的过渡更顺畅。
  • 低配服务器 / 边缘计算:无守护进程意味着更低的内存占用和更少的资源消耗。
  • Red Hat 生态:RHEL/CentOS/Fedora 已将 Podman 作为默认容器引擎。

二、podman安装#

官方网址:Podman

中文网址:Podman 容器工具

中文文档:Podman 入门指南 | Podman 容器工具

2.1 下载二进制包#

Terminal window
cd /usr/local/src
# 这里下载6.1.4版本
curl -fL -o podman-static-v6.1.4-linux-amd64.tar.gz \
https://github.com/mgoltzsche/podman-static/releases/download/v6.1.4/podman-linux-amd64.tar.gz

2.2 配置文件目录#

Terminal window
# 创建安装目录
mkdir -p /usr/local/podman/bin \
/usr/local/podman/etc/containers \
/usr/local/podman/storage \
/usr/local/podman/run/containers/storage \
/usr/local/podman/run/tmp \
/usr/local/podman/docs
# 解压二进制包
cd /usr/local/src/ && tar -xzf podman-static-v6.1.4-linux-amd64.tar.gz
# 移动文件
mv /usr/lcoal/src/podman-linux-amd64/usr/local/bin/* /usr/local/podman/bin/
mv /usr/lcoal/src/podman-linux-amd64/usr/local/lib /usr/local/podman/lib
mv /usr/lcoal/src/podman-linux-amd64/usr/local/share /usr/local/podman/share
mv /usr/lcoal/src/podman-linux-amd64/etc/containers/* /usr/local/podman/etc/containers/
cp /usr/lcoal/src/podman-linux-amd64/README.md /usr/local/podman/docs/README.md
# 移动quadlet,与netavark/aardvark-dns 同一搜索路径
mv /usr/lcoal/src/podman-linux-amd64/usr/local/libexec/podman/quadlet /usr/local/podman/lib/podman/quadlet
# 上游自带的 storage.conf.d 把 mount_program 指向 /usr/local/bin/fuse-overlayfs(我们的目录外),
# 必须删掉,否则会引用包外路径
rm -rf /usr/local/podman/etc/containers/storage.conf.d

2.3 修改文件属性#

包里文件的 UID/GID 是构建机的 1001:1001,必须改回 root:

Terminal window
chown -R root:root /usr/local/podman
chmod 0755 /usr/local/podman/bin/* /usr/local/podman/lib/podman/*

2.4 修改二进制名并新建一个替代#

Terminal window
# 修改podman二进制文件名
mv /usr/local/podman/bin/podman /usr/local/podman/bin/podman.real
# 新建一个名为podman的脚本
cat > /usr/local/podman/bin/podman << 'EOF'
#!/bin/bash
PD_HOME=/usr/local/podman
C=$PD_HOME/etc/containers
export CONTAINERS_CONF=$C/containers.conf
export CONTAINERS_STORAGE_CONF=$C/storage.conf
export CONTAINERS_REGISTRIES_CONF=$C/registries.conf
export CONTAINERS_POLICY_JSON=$C/policy.json
export XDG_CONFIG_HOME=$PD_HOME/xdg/config
export XDG_DATA_HOME=$PD_HOME/xdg/data
export XDG_CACHE_HOME=$PD_HOME/xdg/cache
export XDG_RUNTIME_DIR=$PD_HOME/run
export TMPDIR=$PD_HOME/run/tmp
mkdir -p "$TMPDIR" "$XDG_CONFIG_HOME" "$XDG_DATA_HOME" 2>/dev/null || true
mkdir -p "$XDG_CACHE_HOME" 2>/dev/null || true
chmod 0700 "$XDG_RUNTIME_DIR" "$XDG_CONFIG_HOME" 2>/dev/null || true
exec -a podman "$PD_HOME/bin/podman.real" "$@"
EOF
# 修改文件权限
chmod 0755 /usr/local/podman/bin/podman

为什么要多这一层:podman 的配置、helper、临时目录都要靠 CONTAINERS_* 环境变量指向包内。如果用户从非登录 shell(cron、systemd、ssh host cmd、容器内 exec)调用,/etc/profile.d 不会被加载,podman 就会去 /etc/containers 和系统默认路径找依赖,直接失败。启动器把环境变量固化下来,保证任何调用方式结果一致。

文件参数说明:

  • exec -a podman:把 argv[0] 改成 podman,否则 podman --version 会显示成 podman.real version 6.1.4。
  • XDG_* 三个变量:防止在 ~/.config/containers、~/.cache/containers、/run/user/0/crun 生成文件。
  • TMPDIR:防止临时文件落到 /tmp。
环境变量作用不设会怎样
CONTAINERS_CONF指定主配置读 /etc/containers/containers.conf,配置全部失效
CONTAINERS_STORAGE_CONF指定存储配置镜像存到 /var/lib/containers/storage
CONTAINERS_REGISTRIES_CONF指定镜像源配置直连 docker.io,拉取超时
CONTAINERS_POLICY_JSON指定签名策略文件podman pull 直接报 no policy.json file found
XDG_CONFIG_HOME配置目录生成 ~/.config/containers
XDG_DATA_HOME数据目录生成 ~/.local/share/containers
XDG_CACHE_HOME缓存目录生成 ~/.cache/containers
XDG_RUNTIME_DIR运行时目录crun 状态落到 /run/user/0/crun
TMPDIR临时目录写 /var/tmp

最后一行 exec -a podman ... 中的 -a podman 是用来修正进程名的:二进制改名成 podman.real 后,podman --version 会显示成 podman.real version 6.1.4,加上这个参数后显示正常。

2.5 编写配置文件#

配置文件全部放在 /usr/local/podman/etc/containers/

2.5.1 containers.conf#

Terminal window
cat > /usr/local/podman/etc/containers/containers.conf << 'EOF'
[engine]
# OCI 运行时:使用包内自带的 crun
runtime = "crun"
# # 容器监控进程 conmon(必须在包内)
conmon_path = ["/usr/local/podman/lib/podman/conmon"]
# 辅助二进制目录:netavark / aardvark-dns / catatonit
helper_binaries_dir = ["/usr/local/podman/lib/podman"]
# # 锁文件写入存储目录,避免占用 /dev/shm
lock_type = "file"
# 无 systemd 环境使用 cgroupfs 直接管理 cgroup
cgroup_manager = "cgroupfs"
# 事件日志写文件,不依赖 journald
events_logger = "file"
# 临时目录收进包内,避免写 /var/tmp 与 /tmp
tmp_dir = "/usr/local/podman/run/tmp"
[engine.runtimes]
crun = ["/usr/local/podman/bin/crun"]
runc = ["/usr/local/podman/bin/runc"]
[network]
# podman 5 起默认使用 netavark 网络栈
network_backend = "netavark"
# netavark 2.x 只支持 nftables 防火墙后端
firewall_driver = "nftables"
# 容器网段(避开 docker 默认的 172.17.0.0/16)
default_subnet = "10.88.0.0/16"
[containers]
# seccomp 规则文件收进包内
seccomp_profile = "/usr/local/podman/etc/containers/seccomp.json"
EOF

关键项解释:

配置项作用
conmon_path必须显式指定。helper_binaries_dir 对 conmon 无效,conmon 有独立的搜索列表,不设就会去 /usr/libexec/podman/conmon 等系统路径找,报 conmon not found
helper_binaries_dirnetavark / aardvark-dns / catatonit / quadlet 的搜索目录
cgroup_manager = "cgroupfs"不依赖 systemd 的 cgroup 驱动
events_logger = "file"事件写入文件,不依赖 journald
default_subnet = 10.88.0.0/16避开Docker 默认的 172.17.0.0/16,防止docker容器网段冲突
firewall_driver = "nftables"netavark 2.x 只支持 nftables 后端

2.5.2 storage.conf#

podman 存储配置,镜像层、容器层、命名卷全部落在 /usr/local/podman 内

Terminal window
cat > /usr/local/podman/etc/containers/storage.conf << 'EOF'
[storage]
driver = "overlay"
# 镜像与容器层存储根目录
graphroot = "/usr/local/podman/storage"
# 运行时元数据目录(容器运行期状态)
runroot = "/usr/local/podman/run/containers/storage"
transient_store = false
[storage.options]
[storage.options.overlay]
mountopt = "nodev"
EOF

这里的 driver 必须显式写 overlay。如果沿用系统里已有旧存储库(其记录为空 driver ""),显式写 overlay 会报 database graph driver "" does not match our graph driver "overlay"。 本次是全新 graphroot,没有历史数据库,因此可以显式设置。

2.5.3 registries.conf#

配置镜像源

Terminal window
cat > /usr/local/podman/etc/containers/registries.conf << 'EOF'
unqualified-search-registries = ["docker.io", "quay.io", "ghcr.io"]
[[registry]]
prefix = "docker.io"
location = "docker.io"
[[registry.mirror]]
location = "docker.m.daocloud.io"
[[registry.mirror]]
location = "docker.1ms.run"
EOF

2.5.4 policy.json#

保留上游原值(内网镜像站不提供签名校验,需要放开):

Terminal window
cat > /usr/local/podman/etc/containers/policy.json << 'EOF'
{
"default": [{ "type": "insecureAcceptAnything" }],
"transports": {
"docker-daemon": { "": [{ "type": "insecureAcceptAnything" }] }
}
}
EOF

2.6 配置环境变量#

Terminal window
cat > /etc/profile.d/podman.sh <<'EOF'
if [ -d /usr/local/podman/bin ]; then
case ":${PATH}:" in
*:/usr/local/podman/bin:*) ;;
*) PATH="/usr/local/podman/bin:${PATH}" ;;
esac
export PATH
C=/usr/local/podman/etc/containers
export CONTAINERS_CONF=$C/containers.conf
export CONTAINERS_STORAGE_CONF=$C/storage.conf
export CONTAINERS_REGISTRIES_CONF=$C/registries.conf
export CONTAINERS_POLICY_JSON=$C/policy.json
fi
EOF
Terminal window
source /etc/profile

用 if [ -d ... ] 包住:目录被删后脚本即使残留也不会污染 PATH。

2.7 测试podman#

Terminal window
podman --version
# 首次执行 info 会创建 overlay 存储库
podman info
# 查看依赖路径
podman info 2>&1 | grep -iE 'graphRoot|graphDriverName|runRoot|networkBackend|ociRuntime|conmon'
# 拉取镜像测试
podman pull hello-world
podman run --rm hello-world

2.8 卸载podman#

Terminal window
# 删除目录
rm -rf /usr/local/podman
# 删除环境变量
rm -f /etc/profile.d/podman.sh
# 镜像 blob 校验缓存
/var/lib/containers/cache

三、podman使用#

Podman 的命令行和 Docker 几乎一样,大多数时候把 docker 直接换成 podman 就能用。 它最大的区别是无守护进程、默认支持 rootless,所以更适合在 Linux 上以普通用户管理容器。

3.1 常用命令速查#

功能命令说明
查看版本podman version确认安装是否成功
搜索镜像podman search nginx从仓库搜索镜像
拉取镜像podman pull nginx:1.27建议使用固定版本标签
查看镜像podman images列出本地镜像
运行容器podman run -d --name web -p 8080:80 nginx:1.27后台启动容器
查看容器podman ps -a列出所有容器
查看日志podman logs -f web实时查看日志
进入容器podman exec -it web bash在容器内执行命令
停止/启动podman stop web / podman start web生命周期管理
删除容器podman rm web删除已停止容器
删除镜像podman rmi nginx:1.27删除本地镜像
复制文件podman cp ./index.html web:/usr/share/nginx/html/主机和容器互传文件
监控资源podman stats web查看 CPU、内存等
清理资源podman system prune清理无用镜像、容器、网络
Terminal window
podman info # 环境详情
podman volume create data # 命名卷
podman run -d -v data:/usr/share/nginx/html nginx # 挂载卷
podman volume ls # 卷列表
podman system df # 空间占用
podman system prune -a # 清理未使用资源
podman system reset -f # 清空全部镜像/容器/卷(危险)
podman generate kube web > web.yaml # 导出为 K8s YAML
podman play kube web.yaml # 从 YAML 启动
podman pod create --name mypod -p 8080:80 # Pod

3.2 使用示例#

3.2.1 基础用法#

Terminal window
# 运行容器
podman run -d --name web -p 8080:80 --restart=always nginx:1.27
# 查看容器运行状态
podman ps -a
# 查看镜像
podman images
# 查看日志
podman logs -f web
#进入容器
podman exec -it web bash
# 停止容器并删除
podman stop web
podman rm web
# 删除镜像
podman rmi nginx:1.27

3.2.2 挂载目录#

Terminal window
mkdir -p data/www
echo "<h1>Hello Podman</h1>" > data/www/index.html
# :Z 独占标签。将该目录的标签设为仅此容器可访问,并递归修改宿主机上该目录及其内容的 SELinux 上下文
# :z 共享标签。标签允许多个容器访问,同样递归修改
# 系统没有启用 SELinux时,该标签可以省略
podman run -d --name web -p 8080:80 -v data/www:/usr/share/nginx/html:Z nginx:1.27

3.2.3 容器携带变量#

Terminal window
# 启动容器使用变量、同时使用命名卷pgdata,
podman run -d --name db \
-e POSTGRES_PASSWORD=example \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:16
# 查看容器状态
podman ps
podman logs -f db
# 进入数据库
podman exec -it db psql -U postgres

3.2.4 使用pod模拟容器#

Podman 的 Pod 类似 Kubernetes 的 Pod,多个容器可以共享网络。

Terminal window
# 创建一个pod
podman pod create --name app -p 8080:80
# 在pod中启动容器
podman run -d --pod app --name web nginx:1.27
podman run -d --pod app --name redis redis:alpine
# 查看pod
podman pod ps
# 停止pod
podman pod stop app
# 删除pod
podman pod rm app

3.2.4.1 Nginx 反向代理 + 后端 API#

后端不需要暴露给宿主机,只让 Nginx 对外服务。

Terminal window
podman pod create --name api-pod -p 8080:80
podman run -d --pod api-pod --name backend php:latest
podman run -d --pod api-pod --name nginx \
-v ./nginx.conf:/etc/nginx/nginx.conf:Z \
nginx:alpine

3.2.4.2 ELK / 日志栈本地调试#

把 Elasticsearch、Logstash、Kibana 放进一个 Pod,内部访问非常简单。

Terminal window
podman pod create --name elk -p 5601:5601
podman run -d --pod elk --name elasticsearch \
-e "discovery.type=single-node" \
-v es-data:/usr/share/elasticsearch/data \
elasticsearch:8.17.0
podman run -d --pod elk --name logstash \
logstash:8.17.0
podman run -d --pod elk --name kibana \
-e "ELASTICSEARCH_HOSTS=http://localhost:9200" \
kibana:8.17.0

Kibana 和 Logstash 访问 Elasticsearch 时都可以直接用 localhost:9200。

3.2.4.3 共享数据卷:构建产物 + 静态服务#

Terminal window
podman volume create build-data
podman pod create --name build-pod -p 8080:80
podman run -d --pod build-pod --name builder \
-v build-data:/app/dist \
node:20 \
sh -c "cd /app && npm run build"
podman run -d --pod build-pod --name web \
-v build-data:/usr/share/nginx/html:Z \
nginx:alpine

这样可以把构建输出和静态服务拆成两个容器,但通过同一个卷共享文件。

3.2.4.4 限制整个pod资源#

资源限制可以加在 Pod 上,Pod 内所有容器共享这些限制。

Terminal window
podman pod create \
--name limited-pod \
-p 8080:80 \
--memory=2g \
--cpus=2
podman run -d --pod limited-pod --name app myapp:latest
podman run -d --pod limited-pod --name worker worker:latest

3.2.4.5 用YAML管理 Pod#

Terminal window
# 本地 Pod 导出成 YAML
podman generate kube mypod > mypod.yaml
# 使用yaml启动
podman play kube mypod.yaml

3.2.4.6 用systemd管理 Pod#

Terminal window
podman pod create --name webapp -p 8080:80
podman run -d --pod webapp --name web nginx:alpine
podman generate systemd --name webapp --files --new

生成后把 service 文件放到:

  • 用户级:~/.config/systemd/user/
  • 系统级:/etc/systemd/system/

然后:

Terminal window
systemctl --user daemon-reload
systemctl --user enable --now pod-webapp.service

如果想让普通用户的服务开机也能运行,还需要执行:

Terminal window
loginctl enable-linger

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

podman安装使用
https://2233941.xyz/posts/podman安装使用/
作者
lumifly
发布于
2026-10-23
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
lumifly
不逐世间万丈星河,自守一隅细碎明光
统计
--
总浏览量
--
今日访问
--
本月访问
✨ 今日一言
"加载中..."
——
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
本年还剩 -- 天--%
本月还剩 -- 天--%
本周还剩 -- 天--%
距离--
--
--
天气预报
最新动态
站点统计
文章
31
分类
2
标签
23
总字数
218,787
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录