Linux 容器化服务管理:Docker + Podman + Systemd 集成运维实战
一、Docker 与 Podman 对比及选型建议
Docker:
- 优点:生态成熟、镜像仓库丰富、工具链完整(Compose、Swarm)
- 缺点:Daemon 架构(单点风险)、默认 root 权限运行、安全隐患较大
Podman(推荐生产环境):
- 优点:无 Daemon(rootless 模式)、与 Docker 命令兼容、原生支持 Systemd、更好的安全性
生产选型建议:
- 新项目优先 Podman + Quadlet(Systemd 原生集成)
- 混合环境:Podman 兼容 Docker 镜像和 Dockerfile
安装命令:
# Docker
yum install docker-ce docker-ce-cli containerd.io -y
systemctl enable --now docker
# Podman(Rocky/AlmaLinux/Ubuntu)
yum install podman podman-docker -y # 提供 docker 命令兼容
apt install podman -y
验证:
podman --version
podman info
docker --version # Podman 兼容模式
二、容器基础操作与 Systemd 集成
1. 常用容器管理命令
podman run -d --name nginx -p 8080:80 nginx:alpine
podman ps
podman logs -f nginx
podman exec -it nginx sh
podman stop nginx && podman rm nginx
podman images
podman pull redis:7
2. Systemd 管理容器服务(推荐方式)
传统方式(生成单元文件):
podman generate systemd --name nginx --new > /etc/systemd/system/nginx-container.service
systemctl daemon-reload
systemctl enable --now nginx-container.service
Quadlet 方式(Podman 4.0+ 极致推荐): 在 /etc/containers/systemd/ 目录创建文件:
文件:/etc/containers/systemd/nginx.container
[Unit]
Description=NGINX Container
After=network-online.target
Wants=network-online.target
[Container]
Image=nginx:alpine
ContainerName=nginx-prod
Network=host
PublishPort=80:80
Volume=/data/nginx/html:/usr/share/nginx/html:Z
Environment=TZ=Asia/Shanghai
Restart=always
[Service]
Restart=always
[Install]
WantedBy=multi-user.target
执行:
systemctl daemon-reload
systemctl enable --now nginx.container
systemctl status nginx.service # Podman 会自动生成对应 service
优势:完全由 Systemd 管理,重启、日志、资源控制全部统一。
三、资源控制与安全加固
1. Systemd + cgroups 资源限制 在 .container 文件中添加:
[Container]
CPUQuota=200%
MemoryHigh=2G
MemoryMax=4G
IOWeight=600
2. Rootless 模式(安全核心)
# 以普通用户运行 Podman
loginctl enable-linger $USER
podman system migrate
3. SELinux 与安全选项
[Container]
SecurityLabelType=container_t
ReadOnly=true
NoNewPrivileges=true
DropCapability=ALL
AddCapability=NET_BIND_SERVICE
4. Secret 管理 使用 --secret 或 Podman secrets + Systemd Credential。
四、网络与存储管理
1. 网络模式对比
- pod:Podman 多容器共享网络(类似 Kubernetes Pod)
Podman 网络创建:
podman network create app-net --subnet=10.88.0.0/16
2. 持久化存储
[Container]
Volume=/data/mysql:/var/lib/mysql:Z # :Z 用于 SELinux
Volume=/etc/my.cnf:/etc/my.cnf:ro
推荐使用 podman volume 或 NFS/ Ceph 共享存储。
3. Quadlet 多容器示例(一个 Pod) 创建 app.pod 和多个 .container 文件实现类似 Kubernetes 的 Pod 管理。
五、生产级容器化服务部署实战
1. Nginx + PHP-FPM 多容器示例
- 使用 Quadlet 定义 nginx.container 和 php.container
2. 数据库容器化(MySQL 示例)
[Container]
Image=mysql:8.0
Env=MYSQL_ROOT_PASSWORD=StrongPass123!
Volume=mysql-data:/var/lib/mysql
HealthCmd=/usr/bin/mysqladmin ping -h localhost -u root --password=StrongPass123!
3. 滚动更新与零停机
# 使用 Ansible 或脚本实现
podman pull new-image:tag
systemctl stop old-container.service
systemctl start new-container.service
4. 监控集成
- Prometheus + cAdvisor 或 Podman 导出器
六、Docker 到 Podman 平滑迁移指南
1. 兼容模式
dnf install podman-docker
# Docker 命令自动调用 Podman
2. 镜像迁移
podman pull docker.io/library/xxx
podman save -o image.tar old-image
podman load -i image.tar
3. Compose 迁移 使用 podman-compose 或直接转换为 Quadlet 文件。
4. 完整迁移 Checklist
七、生产环境容器运维最佳实践
- 最小基础镜像(Alpine / Distroless)
journald 驱动:--log-driver=journalpodman logs + journalctl -u xxx.container
- Podman + Keepalived + 多节点
八、常见容器故障排查案例
案例1:容器无法启动(权限问题) 症状:Permission denied。 解决:
podman unshare chown -R 1000:1000 /data/volume
restorecon -Rv /data
案例2:端口绑定失败 解决:使用 CAP_NET_BIND_SERVICE 或 >1024 端口。
案例3:Systemd 重启后容器未启动 排查:
systemctl status xxx.container
podman ps -a
journalctl -u xxx.container -xe
案例4:镜像膨胀导致磁盘满 解决:
podman system prune -a --volumes
podman image rm <unused>
案例5:Rootless 下 volume 权限问题 解决:使用 :U 标签自动映射用户。