本文档风哥主要介绍Podman的容器编排,包括容器编排的概念、工具、特性以及容器编排的设计、伸缩和监控等内容。风哥教程参考Podman官方文档Container Orchestration部分,适合容器管理员和开发人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 容器编排概念
容器编排是指管理容器的生命周期、部署、伸缩、网络和存储等操作的过程。随着容器数量的增加,手动管理容器变得越来越困难,因此需要使用容器编排工具来自动化这些操作。Podman支持多种容器编排方式,包括Podman Compose、Kubernetes集成和Systemd集成等。更多视频教程www.fgedu.net.cn
- 自动化容器部署和管理
- 实现容器的伸缩和负载均衡
- 确保容器的高可用性
- 简化容器的网络和存储管理
- 提供容器的监控和日志管理
1.2 容器编排工具
Podman支持的容器编排工具主要包括:
- Podman Compose:基于Docker Compose语法的容器编排工具,适合单主机的容器编排
- Kubernetes:容器编排的行业标准,适合多主机的容器编排
- Systemd:使用Systemd服务管理容器,适合简单的容器管理
1.3 容器编排特性
容器编排的主要特性包括:
- 服务发现:自动发现和注册容器服务
- 负载均衡:在多个容器实例之间分配流量
- 自动伸缩:根据负载自动调整容器数量
- 健康检查:监控容器的健康状态
- 滚动更新:无停机更新容器
- 故障恢复:自动重启失败的容器
Part02-生产环境规划与建议
2.1 容器编排设计
生产环境中Podman的容器编排设计:
## 编排工具选择
– Podman Compose:适合单主机的容器编排,配置简单,易于使用
– Kubernetes:适合多主机的容器编排,功能强大,适合大规模部署
– Systemd:适合简单的容器管理,与系统服务集成
## 服务架构设计
– 微服务架构:将应用拆分为多个微服务,每个服务独立部署
– 分层架构:将应用分为前端、后端和数据库等层次
– 模块化设计:将应用分为多个模块,便于管理和维护
## 网络设计
– 服务发现:使用DNS或服务注册表进行服务发现
– 网络隔离:为不同的服务创建不同的网络
– 负载均衡:在多个容器实例之间分配流量
## 存储设计
– 数据持久化:使用卷或绑定挂载进行数据持久化
– 存储分类:根据数据类型选择不同的存储方案
– 备份策略:定期备份容器数据
2.2 容器编排伸缩
生产环境中Podman的容器编排伸缩:
## 水平伸缩
– 根据负载自动调整容器数量
– 配置伸缩策略和阈值
– 监控容器的CPU和内存使用情况
## 垂直伸缩
– 调整容器的资源限制
– 升级容器的硬件配置
– 优化容器的应用性能
## 伸缩策略
– 基于CPU使用率的伸缩
– 基于内存使用率的伸缩
– 基于网络流量的伸缩
– 基于自定义指标的伸缩
## 伸缩监控
– 监控容器的资源使用情况
– 监控应用的响应时间
– 监控系统的整体性能
2.3 容器编排监控
生产环境中Podman的容器编排监控:
- 容器监控:监控容器的运行状态、资源使用情况和健康状态
- 服务监控:监控服务的可用性、响应时间和错误率
- 系统监控:监控主机的CPU、内存、磁盘和网络使用情况
- 日志管理:收集和分析容器和服务的日志
- 告警管理:设置告警规则,及时发现和处理问题
Part03-生产环境项目实施方案
3.1 Podman Compose
3.1.1 安装Podman Compose
$ sudo dnf install -y podman-compose
# 输出日志
Last metadata expiration check: 1:00:00 ago on Mon Apr 10 10:00:00 2026.
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
podman-compose noarch 1.0.6-1.el9 epel 65 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 65 k
Installed size: 240 k
Downloading Packages:
[SKIPPED] podman-compose-1.0.6-1.el9.noarch.rpm: Already downloaded
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : podman-compose-1.0.6-1.el9.noarch 1/1
Verifying : podman-compose-1.0.6-1.el9.noarch 1/1
Installed:
podman-compose-1.0.6-1.el9.noarch
Complete!
# 验证安装
$ podman-compose –version
# 输出日志
podman-compose version: 1.0.6
3.1.2 使用Podman Compose
# 创建docker-compose.yml文件
$ cat > docker-compose.yml << EOF
version: '3'
services:
web:
image: docker.io/library/httpd
ports:
- "80:80"
volumes:
- ./html:/usr/local/apache2/htdocs:z
db:
image: docker.io/library/mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: fgedu123
MYSQL_DATABASE: fgedudb
MYSQL_USER: fgedu
MYSQL_PASSWORD: fgedu123
volumes:
- db_data:/var/lib/mysql:z
volumes:
db_data:
EOF
# 创建html目录
$ mkdir -p html
$ echo "
Hello from Podman Compose!
” > html/index.html
# 启动服务
$ podman-compose up -d
# 输出日志
[+] Running 3/3
⠿ Network compose_default Created 0.1s
⠿ Volume “compose_db_data” Created 0.0s
⠿ Container compose-web-1 Started 0.5s
⠿ Container compose-db-1 Started 0.5s
# 查看服务状态
$ podman-compose ps
# 输出日志
NAME COMMAND SERVICE STATUS PORTS
compose-web-1 httpd-foreground web running 0.0.0.0:80->80/tcp
compose-db-1 mysqld db running 3306/tcp
# 停止服务
$ podman-compose down
# 输出日志
[+] Running 3/3
⠿ Container compose-web-1 Removed 0.5s
⠿ Container compose-db-1 Removed 0.5s
⠿ Volume “compose_db_data” Removed 0.0s
⠿ Network compose_default Removed 0.1s
3.2 Kubernetes集成
3.2.1 Podman与Kubernetes集成
# 安装Kubernetes工具
$ sudo dnf install -y kubectl
# 输出日志
Last metadata expiration check: 1:00:00 ago on Mon Apr 10 10:00:00 2026.
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
kubectl x86_64 1.25.0-0.el9 appstream 15 M
Transaction Summary
================================================================================
Install 1 Package
Total download size: 15 M
Installed size: 63 M
Downloading Packages:
[SKIPPED] kubectl-1.25.0-0.el9.x86_64.rpm: Already downloaded
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : kubectl-1.25.0-0.el9.x86_64 1/1
Verifying : kubectl-1.25.0-0.el9.x86_64 1/1
Installed:
kubectl-1.25.0-0.el9.x86_64
Complete!
# 创建Kubernetes部署文件
$ cat > deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: fgedu-web
spec:
replicas: 3
selector:
matchLabels:
app: fgedu-web
template:
metadata:
labels:
app: fgedu-web
spec:
containers:
- name: httpd
image: docker.io/library/httpd
ports:
- containerPort: 80
EOF
# 使用Podman部署到Kubernetes
$ podman kube play deployment.yaml
# 输出日志
Pod: fgedu-web-5678901234567890ab
Container: fgedu-web-5678901234567890ab-httpd
# 查看部署状态
$ podman ps
# 输出日志
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1234567890ab docker.io/library/httpd httpd-foreground 2 minutes ago Up 2 minutes ago 0.0.0.0:8080->80/tcp fgedu-web-5678901234567890ab-httpd
4567890123ab docker.io/library/httpd httpd-foreground 2 minutes ago Up 2 minutes ago 0.0.0.0:8081->80/tcp fgedu-web-6789012345678901ab-httpd
7890123456ab docker.io/library/httpd httpd-foreground 2 minutes ago Up 2 minutes ago 0.0.0.0:8082->80/tcp fgedu-web-7890123456789012ab-httpd
3.3 Systemd集成
3.3.1 使用Systemd管理容器
# 创建Systemd服务文件
$ sudo cat > /etc/systemd/system/fgedu-httpd.service << EOF
[Unit]
Description=Podman fgedu-httpd.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/var/lib/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run \
--cidfile=%t/%n.ctr-id \
--cgroups=no-conmon \
--rm \
--sdnotify=conmon \
-d \
-p 80:80/tcp \
--name fgedu-httpd \
docker.io/library/httpd
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target
EOF
# 重新加载Systemd配置
$ sudo systemctl daemon-reload
# 启动服务
$ sudo systemctl start fgedu-httpd.service
# 查看服务状态
$ sudo systemctl status fgedu-httpd.service
# 输出日志
● fgedu-httpd.service - Podman fgedu-httpd.service
Loaded: loaded (/etc/systemd/system/fgedu-httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Mon 2026-04-10 10:00:00 UTC; 2min ago
Docs: man:podman-generate-systemd(1)
Main PID: 12345 (conmon)
Tasks: 8 (limit: 12345)
Memory: 10.0M
CPU: 100ms
CGroup: /system.slice/fgedu-httpd.service
└─12345 /usr/bin/conmon --api-version 1 -c 67890abcdef -u 67890abcdef -r /usr/bin/runc -b /var/lib/containers/storage/overlay-containers/67890abcdef/userdata -p /run/containers/storage/overlay-containers/67890abcdef/userdata/pidfile -n fgedu-httpd --exit-dir /run/libpod/exits --socket-dir-path /run/libpod/socket --log-level info --runtime-args --log-format json --log-path /var/lib/containers/storage/overlay-containers/67890abcdef/userdata/ctr.log --conmon-pidfile /run/libpod/conmon/67890abcdef.pid --exit-command /usr/libexec/podman/catatonit --exit-command-arg -- /usr/bin/podman --root /var/lib/containers/storage --runroot /run/containers/storage --log-level info --cgroup-manager systemd --tmpdir /run/libpod --runtime runc --storage-driver overlay --events-backend journald container cleanup 67890abcdef
Apr 10 10:00:00 fgedu.net.cn systemd[1]: Starting Podman fgedu-httpd.service...
Apr 10 10:00:00 fgedu.net.cn podman[12345]: 67890abcdef
Apr 10 10:00:00 fgedu.net.cn systemd[1]: Started Podman fgedu-httpd.service.
# 停止服务
$ sudo systemctl stop fgedu-httpd.service
Part04-生产案例与实战讲解
4.1 Web应用编排
4.1.1 使用Podman Compose部署Web应用
# 创建docker-compose.yml文件
$ cat > docker-compose.yml << EOF
version: '3'
services:
nginx:
image: docker.io/library/nginx
ports:
- "80:80"
volumes:
- ./nginx/conf:/etc/nginx/conf.d:z
- ./nginx/html:/usr/share/nginx/html:z
depends_on:
- php
php:
image: docker.io/library/php:7.4-fpm
volumes:
- ./php/www:/var/www/html:z
mysql:
image: docker.io/library/mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: fgedu123
MYSQL_DATABASE: fgedudb
MYSQL_USER: fgedu
MYSQL_PASSWORD: fgedu123
volumes:
- mysql_data:/var/lib/mysql:z
volumes:
mysql_data:
EOF
# 创建目录结构
$ mkdir -p nginx/conf nginx/html php/www
# 创建Nginx配置文件
$ cat > nginx/conf/default.conf << EOF
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
}
EOF
# 创建PHP文件
$ cat > php/www/index.php << EOF
connect_error) {
die(“连接失败: ” . conn->connect_error);
}
// 创建表
sql = “CREATE TABLE IF NOT EXISTS fgedu_users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), email VARCHAR(255))”;
if (conn->query(sql) === TRUE) {
echo “表 fgedu_users 创建成功
“;
} else {
echo “创建表时出错: ” . conn->error . “
“;
}
// 插入数据
sql = “INSERT INTO fgedu_users (name, email) VALUES (‘fgedu’, ‘fgedu@example.com’)”;
if (conn->query(sql) === TRUE) {
echo “数据插入成功
“;
} else {
echo “插入数据时出错: ” . conn->error . “
“;
}
// 查询数据
sql = “SELECT * FROM fgedu_users”;
result = conn->query(sql);
if (result->num_rows > 0) {
echo “
| ID | Name | |
|---|---|---|
| ” . row[“id”]. “ | ” . row[“name”]. “ | ” . row[“email”]. “ |
“;
} else {
echo “0 结果”;
}
conn->close();
?>
EOF
# 启动服务
$ podman-compose up -d
# 测试应用
$ curl http://localhost
# 输出日志
表 fgedu_users 创建成功
数据插入成功
| ID | Name | |
|---|---|---|
| 1 | fgedu | fgedu@example.com |
4.2 数据库编排
4.2.1 使用Podman Compose部署数据库集群
# 创建docker-compose.yml文件
$ cat > docker-compose.yml << EOF
version: '3'
services:
master:
image: docker.io/library/mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: fgedu123
MYSQL_DATABASE: fgedudb
MYSQL_USER: fgedu
MYSQL_PASSWORD: fgedu123
MYSQL_REPLICATION_MODE: master
MYSQL_REPLICATION_USER: repl
MYSQL_REPLICATION_PASSWORD: repl123
volumes:
- master_data:/var/lib/mysql:z
slave:
image: docker.io/library/mysql:8.0
ports:
- "3307:3306"
environment:
MYSQL_ROOT_PASSWORD: fgedu123
MYSQL_DATABASE: fgedudb
MYSQL_USER: fgedu
MYSQL_PASSWORD: fgedu123
MYSQL_REPLICATION_MODE: slave
MYSQL_REPLICATION_USER: repl
MYSQL_REPLICATION_PASSWORD: repl123
MYSQL_MASTER_HOST: master
MYSQL_MASTER_PORT: 3306
volumes:
- slave_data:/var/lib/mysql:z
depends_on:
- master
volumes:
master_data:
slave_data:
EOF
# 启动服务
$ podman-compose up -d
# 查看服务状态
$ podman-compose ps
# 输出日志
NAME COMMAND SERVICE STATUS PORTS
compose-master-1 mysqld master running 0.0.0.0:3306->3306/tcp
compose-slave-1 mysqld slave running 0.0.0.0:3307->3306/tcp
# 测试主从复制
$ podman exec compose-master-1 mysql -u root -p fgedudb -e “CREATE TABLE fgedu_users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255)); INSERT INTO fgedu_users (name) VALUES (‘fgedu’);”
$ podman exec compose-slave-1 mysql -u root -p fgedudb -e “SELECT * FROM fgedu_users;”
# 输出日志
Enter password:
+—-+——+
| id | name |
+—-+——+
| 1 | fgedu |
+—-+——+
4.3 微服务编排
4.3.1 使用Podman Compose部署微服务
# 创建docker-compose.yml文件
$ cat > docker-compose.yml << EOF
version: '3'
services:
gateway:
image: fgedu/gateway:latest
ports:
- "8080:8080"
depends_on:
- service-a
- service-b
service-a:
image: fgedu/service-a:latest
ports:
- "8081:8081"
service-b:
image: fgedu/service-b:latest
ports:
- "8082:8082"
redis:
image: docker.io/library/redis:6
ports:
- "6379:6379"
mysql:
image: docker.io/library/mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: fgedu123
MYSQL_DATABASE: fgedudb
MYSQL_USER: fgedu
MYSQL_PASSWORD: fgedu123
volumes:
- mysql_data:/var/lib/mysql:z
volumes:
mysql_data:
EOF
# 启动服务
$ podman-compose up -d
# 查看服务状态
$ podman-compose ps
# 输出日志
NAME COMMAND SERVICE STATUS PORTS
compose-gateway-1 /app/run.sh gateway running 0.0.0.0:8080->8080/tcp
compose-service-a-1 /app/run.sh service-a running 0.0.0.0:8081->8081/tcp
compose-service-b-1 /app/run.sh service-b running 0.0.0.0:8082->8082/tcp
compose-redis-1 redis-server redis running 0.0.0.0:6379->6379/tcp
compose-mysql-1 mysqld mysql running 3306/tcp
# 测试微服务
$ curl http://localhost:8080/service-a
$ curl http://localhost:8080/service-b
# 输出日志
Service A response
Service B response
Part05-风哥经验总结与分享
5.1 容器编排最佳实践
Podman容器编排的最佳实践:
- 选择合适的编排工具:根据应用的规模和需求选择合适的编排工具
- 合理设计服务架构:将应用拆分为合理的服务,便于管理和维护
- 使用健康检查:为容器配置健康检查,确保服务的可用性
- 实现自动伸缩:根据负载自动调整容器数量,提高资源利用率
- 配置监控和告警:监控容器的运行状态和资源使用情况,及时发现和处理问题
- 实现数据持久化:使用卷或绑定挂载进行数据持久化,避免数据丢失
- 使用版本控制:对编排配置文件进行版本控制,便于回滚和管理
- 定期备份:定期备份容器数据和编排配置,防止数据丢失
5.2 常见问题与解决方案
Podman容器编排中的常见问题与解决方案:
## 问题1:服务启动失败
# 解决方案:
– 检查服务依赖关系
– 查看容器日志:podman logs
– 检查网络配置
– 检查存储配置
## 问题2:服务间通信问题
# 解决方案:
– 检查网络配置
– 检查服务发现配置
– 测试服务间连接:podman exec
– 检查防火墙规则
## 问题3:资源使用过高
# 解决方案:
– 为容器设置资源限制
– 优化应用性能
– 实现自动伸缩
– 升级硬件配置
## 问题4:数据持久化问题
# 解决方案:
– 使用卷或绑定挂载进行数据持久化
– 定期备份数据
– 实现数据备份策略
## 问题5:编排配置错误
# 解决方案:
– 检查编排配置文件
– 使用版本控制管理配置文件
– 测试配置文件的有效性
– 风哥教程参考官方文档
5.3 故障排查
Podman容器编排的故障排查:
## 服务启动失败
– 查看容器日志:podman logs
– 检查服务依赖关系:podman-compose ps
– 检查网络配置:podman network inspect
– 检查存储配置:podman volume inspect
## 服务间通信问题
– 检查网络配置:podman network inspect
– 测试服务间连接:podman exec
– 检查服务发现配置:查看DNS或服务注册表
– 检查防火墙规则:sudo firewall-cmd –list-all
## 资源使用问题
– 查看资源使用:podman stats
– 检查容器资源限制:podman inspect
– 优化应用性能:分析应用代码和配置
– 实现自动伸缩:配置伸缩策略
## 数据持久化问题
– 检查卷状态:podman volume inspect
– 检查挂载情况:podman inspect
– 检查文件权限:ls -la
– 测试数据写入:podman exec
## 编排配置问题
– 检查编排配置文件:语法检查
– 测试配置文件:podman-compose config
– 风哥教程参考官方文档:查看配置示例
– 使用版本控制:回滚到之前的配置
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
