docker 是一个很好用的容器工具,但目前已经式微,而podman因为出厂设置就是rootless,深受安全专家喜爱,下面呢就简单介绍docker和podman的区别,并给出podman的安全实践。
两者最根本的区别在于是否依赖守护进程(Daemon)。
- Docker 采用 Client-Server 架构,核心是一个始终运行的后台守护进程
dockerd,所有容器操作都通过它中转。客户端 CLI 向 daemon 发送指令,daemon 再调用底层containerd执行。 - Podman 是 Daemonless(无守护进程)架构,每次执行命令时直接 fork/exec 子进程来管理容器,不依赖任何常驻后台服务。
Docker: CLI → dockerd (root daemon) → containerd → runc → container Podman: CLI → fork/exec → conmon → runc → container
这一架构差异,是后续几乎所有特性差异的根源。
安全性是 Podman 最大的竞争优势之一。
- Podman 原生支持以普通用户身份运行容器,无需任何 sudo 权限,容器进程在宿主机上以当前用户 UID 运行。
- Docker 的 daemon 默认以 root 权限运行,即使客户端是普通用户,实际操作仍经过特权进程。虽然后来也支持 rootless 模式,但配置复杂,并非默认行为。
- Docker daemon 长期以 root 运行,一旦被攻击或出现漏洞,整个宿主机都面临风险(经典的"docker 组等同于 root"问题)。
- Podman 无 daemon,攻击面大幅缩小,符合最小权限原则。
- Podman 由 Red Hat 主导开发,与 SELinux 集成更深,在 RHEL/Fedora/CentOS 系上开箱即用。
dockerd ❌ 无守护进程 Rootless 运行 ⚠️ 支持但非默认 ✅ 原生默认支持 CLI 兼容性 Docker CLI 完全兼容 Docker CLI(alias 即可替换) Pod 概念支持 ❌ 不支持(需 K8s) ✅ 原生支持 Pod(多容器组) Systemd 集成 ⚠️ 需额外配置 ✅
podman generate systemd 原生生成 Docker Compose ✅ 官方支持 ✅ 通过
podman-compose 或
docker-compose 兼容 镜像构建
docker build / BuildKit
podman build(基于 Buildah) 镜像仓库兼容 Docker Hub 优先 支持多仓库(Docker Hub / Quay / GHCR 等) Windows/macOS 支持 ✅ Docker Desktop 成熟 ⚠️ Podman Desktop 较新,体验稍弱 Swarm 集群 ✅ 内置 Docker Swarm ❌ 不支持(推荐直接用 K8s) 开源协议 Apache 2.0(部分商业化) 完全开源,Apache 2.0 商业支持 Docker Inc. 商业产品 Red Hat / 社区驱动
Podman 直接借鉴了 Kubernetes 的 Pod 概念,可以将多个容器组合为一个 Pod,共享网络命名空间:
podman pod create --name mypod podman run --pod mypod nginx podman run --pod mypod redis
这让本地开发与 K8s 部署的心智模型高度一致。
podman generate kube mypod > mypod.yaml
可直接将本地 Pod 导出为 K8s 兼容的 YAML,本地开发 → K8s 部署无缝衔接。
podman generate systemd --new mycontainer > /etc/systemd/system/mycontainer.service
容器即服务,天然融入 Linux 服务管理体系。
Docker 并非没有优势,在以下场景仍更具竞争力:
- 生态成熟度:Docker Hub、Docker Compose、Docker Desktop 生态极为完善。
- Windows/macOS 体验:Docker Desktop 在非 Linux 平台上体验更流畅。
- 企业工具链兼容:大量 CI/CD 工具(Jenkins、GitHub Actions 等)默认集成 Docker。
- 学习资源:文档、教程、社区问答资源远多于 Podman。
- BuildKit:Docker 的 BuildKit 构建引擎功能强大,缓存机制更成熟。
一句话: Podman 是"更安全、更 Linux 原生、更贴近 K8s"的现代化选择;Docker 是"生态最成熟、上手最快、跨平台最友好"的工业标准。两者 CLI 高度兼容,迁移成本极低,甚至可以 alias docker=podman 无缝切换。
Podman 的使用方式与 Docker 高度相似,但在安全配置上有更多原生能力可以利用。下面从安装到生产级安全加固,给出完整的实战指南
# Fedora(默认已预装) sudo dnf install -y podman # RHEL 8/9 / CentOS Stream sudo dnf install -y podman
sudo apt-get update sudo apt-get install -y podman
brew install podman podman machine init # 初始化虚拟机 podman machine start # 启动 Podman Machine
podman --version podman info # 查看运行时详细信息
Rootless 是 Podman 最重要的安全特性,强烈建议始终以普通用户身份运行。
# 检查用户命名空间支持 cat /proc/sys/kernel/unprivileged_userns_clone # 输出应为 1,若为 0 则需开启: echo 'kernel.unprivileged_userns_clone=1' | sudo tee /etc/sysctl.d/99-userns.conf sudo sysctl --system # 检查 /etc/subuid 和 /etc/subgid(必须存在当前用户条目) grep $(whoami) /etc/subuid /etc/subgid # 若无,手动添加: sudo usermod --add-subuids - --add-subgids - $(whoami)
# 以普通用户身份迁移命名空间 podman system migrate # 验证 rootless 状态 podman info | grep rootless # 应输出:rootless: true
# 拉取镜像(默认从 docker.io,可指定仓库) podman pull docker.io/library/nginx:alpine podman pull quay.io/fedora/fedora:latest # 运行容器(基本) podman run -d --name mynginx -p 8080:80 nginx:alpine # 运行并自动删除(临时容器) podman run --rm -it alpine sh # 指定用户运行(安全加固) podman run --user 1001:1001 nginx:alpine
podman ps # 查看运行中的容器 podman ps -a # 查看所有容器(含已停止) podman stop mynginx # 优雅停止 podman start mynginx # 启动 podman restart mynginx # 重启 podman rm mynginx # 删除容器 podman rm -f mynginx # 强制删除
podman images # 列出本地镜像 podman rmi nginx:alpine # 删除镜像 podman image prune # 清理悬空镜像 podman system prune -a # 清理所有未使用资源
Podman 内置 Buildah 引擎,podman build 完全兼容 Dockerfile 语法。
# ✅ 安全**实践示例 FROM node:20-alpine AS builder # 使用非 root 用户 RUN addgroup -S appgroup && adduser -S appuser -G appgroup WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN chown -R appuser:appgroup /app # 多阶段构建,最小化最终镜像 FROM node:20-alpine RUN addgroup -S appgroup && adduser -S appuser -G appgroup WORKDIR /app COPY --from=builder --chown=appuser:appgroup /app . USER appuser # ✅ 非 root 运行 EXPOSE 3000 CMD ["node", "server.js"]
# 基本构建 podman build -t myapp:1.0 . # 多平台构建 podman build --platform linux/amd64,linux/arm64 -t myapp:1.0 . # 不使用缓存(安全扫描前推荐) podman build --no-cache -t myapp:1.0 . # 查看镜像层(审计用) podman history myapp:1.0
这是 Podman 区别于 Docker 的核心价值所在,以下措施应作为生产环境标准配置。
# 删除所有能力,只保留必要的 podman run --cap-drop=ALL --cap-add=NET_BIND_SERVICE # 仅添加绑定低端口的能力 -d nginx:alpine # 查看容器当前能力 podman inspect mynginx | grep -A 10 CapAdd
podman run --read-only # 根文件系统只读 --tmpfs /tmp:rw,size=64m,mode=1777 # 临时目录可写 --tmpfs /var/run:rw -d nginx:alpine
podman run --memory=512m # 内存上限 --memory-swap=512m # 禁止使用 swap --cpus=1.0 # CPU 核心数限制 --pids-limit=100 # 进程数限制(防 fork bomb) --ulimit nofile=1024:1024 -d myapp:1.0
# 使用默认 seccomp 配置(已自动启用) podman run --security-opt seccomp=/usr/share/containers/seccomp.json nginx # 使用自定义严格配置 podman run --security-opt seccomp=/path/to/custom-seccomp.json myapp # 查看当前 seccomp 状态 podman inspect mynginx | grep -i seccomp
# 自动应用 SELinux 标签 podman run --security-opt label=type:container_t nginx # 挂载卷时添加 SELinux 标签(:z 共享,:Z 私有) podman run -v /host/data:/app/data:Z,ro nginx # ↑ ↑ # SELinux标签 只读挂载
# 创建隔离网络 podman network create --internal mynet # internal=无外网访问 # 容器加入指定网络 podman run --network mynet -d myapp # 完全禁用网络(适合纯计算任务) podman run --network none myapp # 查看网络 podman network ls podman network inspect mynet
podman run -d –name secure-app –user 1001:1001 # 非 root 用户 –cap-drop=ALL # 删除所有能力 –cap-add=NET_BIND_SERVICE # 按需添加 –read-only # 只读文件系统 –tmpfs /tmp:rw,size=32m # 临时目录 –memory=256m # 内存限制 –memory-swap=256m # 禁用 swap –cpus=0.5 # CPU 限制 –pids-limit=50 # 进程数限制 –security-opt no-new-privileges # 禁止提权 –security-opt seccomp=default # seccomp 过滤 –network mynet # 隔离网络 -v /host/config:/app/config:ro,Z # 只读挂载 + SELinux -p 127.0.0.1:8080:8080 # 仅绑定本地回环 myapp:1.0
🔑
–security-opt no-new-privileges是最重要的单条安全指令,可防止容器内进程通过 setuid/setgid 提升权限。
# 创建 Pod(共享网络命名空间) podman pod create –name webapp -p 8080:80 –network mynet
# 向 Pod 添加容器 podman run -d –pod webapp –name nginx nginx:alpine podman run -d –pod webapp –name redis redis:alpine
# 查看 Pod 状态 podman pod ps podman pod inspect webapp
# Pod 整体操作 podman pod stop webapp podman pod start webapp podman pod rm webapp –force
# 导出为 Kubernetes YAML(本地 → K8s 无缝迁移) podman generate kube webapp > webapp-k8s.yaml
将容器作为系统服务管理,实现开机自启、崩溃自恢复。
# 生成 systemd service 文件 podman generate systemd --new # 每次启动重新创建容器 --name # 使用容器名 --restart-policy=always mynginx > ~/.config/systemd/user/container-mynginx.service # 启用并启动服务(rootless 用户级) systemctl --user daemon-reload systemctl --user enable --now container-mynginx.service # 查看服务状态 systemctl --user status container-mynginx.service journalctl --user -u container-mynginx.service -f # 开机自启(需要 linger 支持) sudo loginctl enable-linger $(whoami)
# 查看容器日志 podman logs mynginx podman logs -f mynginx # 实时跟踪 podman logs --tail=100 mynginx # 最后 100 行 # 进入容器调试 podman exec -it mynginx sh # 查看容器资源使用 podman stats # 实时监控所有容器 podman stats mynginx --no-stream # 单次快照 # 查看容器详情 podman inspect mynginx # 查看容器进程 podman top mynginx # 检查容器文件系统变更 podman diff mynginx
在部署前,用这份清单做最终审查:
podman inspect
| grep User
非空,非 root 无新权限
podman inspect
| grep NoNewPrivileges
true 只读文件系统
podman inspect
| grep ReadonlyRootfs
true 内存限制已设
podman inspect
| grep Memory
非
0 进程数限制
podman inspect
| grep PidsLimit
合理数值 端口绑定检查
podman port
仅绑定必要端口 镜像漏洞扫描
podman image scan ![]()
或
trivy image 无高危漏洞
核心原则总结: Rootless 运行 + 最小权限能力 + 只读文件系统 + 资源限制 + 网络隔离,这五层防护叠加,可以构建出远超传统 Docker 部署的安全容器环境。Podman 将这些能力都做成了原生一等公民,无需复杂的外部工具链。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/259222.html