pbsbc01h3-podmanstats报错笔记
Podman Stats 错误问题完整解决方案
一、问题描述
错误信息
Error: unable to obtain cgroup stats: strconv.ParseUint: parsing "7038456085": value out of range错误原因
- cgroup v2 数值溢出:cgroup v2 返回的数值超出了
uint64类型范围 - 版本兼容性问题:Podman 3.0.1 对 cgroup v2 的支持不完善
- ARM 架构特定问题:在 ARMv7 架构上更为常见
- 内核版本较旧:5.4.65 内核与新版 cgroup v2 的兼容性问题
环境信息
系统:Armbian (定制系统)
架构:armv7l (ARM 32位)
内核:5.4.65-sunxi
Podman:3.0.1
Cgroup:cgroup v2二、Cgroup 基础知识
什么是 Cgroup
Cgroup (Control Groups) 是 Linux 内核的核心功能,用于限制、记录和隔离进程组使用的资源。
主要功能
| 功能 | 说明 |
|---|---|
| 资源限制 | 限制 CPU、内存、磁盘 I/O、网络带宽等 |
| 资源统计 | 监控和记录资源使用情况 |
| 优先级控制 | 设置资源分配优先级 |
| 进程隔离 | 容器之间、服务之间的资源隔离 |
Cgroup v1 vs Cgroup v2
| 特性 | Cgroup v1 | Cgroup v2 |
|---|---|---|
| 树结构 | 多个独立树(cpu、memory 分开) | 统一单树结构 |
| 管理复杂度 | 较复杂 | 更简单统一 |
| 资源控制 | 分散控制 | 统一控制 |
| Podman 支持 | 成熟稳定 | 3.0+ 开始支持(早期版本有 bug) |
查看 Cgroup 信息
# 查看 cgroup 版本
mount | grep cgroup
# 查看 cgroup 文件系统
ls -la /sys/fs/cgroup/
# 查看容器 cgroup 路径
find /sys/fs/cgroup -name "*container*" -type d三、解决方案汇总
方案一:配置 Podman 使用 Cgroupfs(推荐)
原理:绕过 systemd cgroup 管理器,直接使用 cgroupfs
# 1. 创建配置文件
mkdir -p /etc/containers
cat > /etc/containers/containers.conf << 'EOF'
[engine]
cgroup_manager = "cgroupfs"
[containers]
cgroupns = "host"
EOF
# 2. 设置环境变量
export CONTAINERS_CGROUP_MANAGER=cgroupfs
echo 'export CONTAINERS_CGROUP_MANAGER=cgroupfs' >> /root/.bashrc
# 3. 重启服务
systemctl restart podman
# 4. 测试
podman stats --no-stream方案二:降级到 Cgroup v1
原理:系统级切换到 cgroup v1,获得更好的兼容性
# 1. 编辑启动参数(Armbian)
echo "extraargs=systemd.unified_cgroup_hierarchy=0" >> /boot/armbianEnv.txt
# 2. 或者修改 extlinux 配置
vi /boot/extlinux/extlinux.conf
# 在 APPEND 行添加: systemd.unified_cgroup_hierarchy=0
# 3. 重启
reboot
# 4. 验证
mount | grep cgroup
# 应该显示多个 cgroup 挂载点方案三:升级 Podman 版本
方法 A:使用 APT 源
# 添加官方源
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/ /" > /etc/apt/sources.list.d/podman.list
# 添加 GPG 密钥
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/Release.key | apt-key add -
# 更新并安装
apt update
apt install podman方法 B:使用国内镜像(解决网络问题)
# 清华镜像
deb https://mirrors.tuna.tsinghua.edu.cn/opensuse/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/ /
# 阿里云镜像
deb https://mirrors.aliyun.com/opensuse/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/ /方法 C:静态编译版本(最可靠)
# 下载
cd /tmp
wget https://github.com/containers/podman/releases/download/v4.9.0/podman-remote-static-linux_arm.tar.gz
# 安装
tar -xzf podman-remote-static-linux_arm.tar.gz
mv /usr/bin/podman /usr/bin/podman.backup
cp podman-remote-static-linux_arm/podman-remote-static-linux_arm /usr/bin/podman
chmod 755 /usr/bin/podman
# 验证
podman version方案四:替代脚本方案
原理:直接从 cgroup 文件系统读取数据,绕过 Podman stats 的解析问题
#!/bin/bash
# 保存为 /usr/local/bin/podman-stats-fix
cat > /usr/local/bin/podman-stats-fix << 'EOF'
#!/bin/bash
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${GREEN}=== Container Stats Viewer ===${NC}"
printf "%-12s %-20s %-8s %-15s %-10s\n" "CONTAINER" "NAME" "CPU%" "MEM USAGE" "MEM%"
echo "--------------------------------------------------------------------------"
for container in $(podman ps -q); do
name=$(podman inspect $container --format '{{.Name}}' 2>/dev/null | sed 's/^\///')
# 查找 cgroup 路径
cgpath=$(find /sys/fs/cgroup -name "*$container*" -type d 2>/dev/null | head -1)
if [ -n "$cgpath" ]; then
# 读取 CPU 使用率
if [ -f "$cgpath/cpu.stat" ]; then
cpu_usec=$(grep "usage_usec" $cgpath/cpu.stat 2>/dev/null | awk '{print $2}' | head -1)
cpu_percent=$((cpu_usec / 1000000 / 10))
[ $cpu_percent -gt 100 ] && cpu_percent=100
else
cpu_percent="N/A"
fi
# 读取内存使用
if [ -f "$cgpath/memory.current" ]; then
mem_bytes=$(cat $cgpath/memory.current 2>/dev/null)
mem_mb=$((mem_bytes / 1024 / 1024))
elif [ -f "$cgpath/memory.usage_in_bytes" ]; then
mem_bytes=$(cat $cgpath/memory.usage_in_bytes 2>/dev/null)
mem_mb=$((mem_bytes / 1024 / 1024))
else
mem_mb="N/A"
fi
# 读取内存限制
if [ -f "$cgpath/memory.max" ]; then
mem_limit=$(cat $cgpath/memory.max 2>/dev/null)
if [ "$mem_limit" = "max" ]; then
mem_limit_mb="unlimited"
mem_percent="N/A"
else
mem_limit_mb=$((mem_limit / 1024 / 1024))
mem_percent=$((mem_bytes * 100 / mem_limit))
fi
else
mem_limit_mb="?"
mem_percent="?"
fi
printf "%-12s %-20s %-8s %-15s %-10s\n" \
"${container:0:12}" \
"${name:0:20}" \
"${cpu_percent}%" \
"${mem_mb}MiB/${mem_limit_mb}" \
"${mem_percent}%"
else
printf "%-12s %-20s %-8s %-15s %-10s\n" \
"${container:0:12}" "${name:0:20}" "N/A" "N/A" "N/A"
fi
done
EOF
chmod +x /usr/local/bin/podman-stats-fix
# 创建别名
echo "alias stats='/usr/local/bin/podman-stats-fix'" >> /root/.bashrc
source /root/.bashrc
# 使用
podman-stats-fix方案五:使用系统命令替代
# 使用 podman top 查看进程
podman top <container_id> -eo pid,comm,pcpu,pmem
# 使用系统命令
ps aux | grep conmon
top -b -n 1 | grep container
# 查看容器详细信息
podman inspect <container_id> | jq '.[].State'
# 直接查看 cgroup 文件
cat /sys/fs/cgroup/system.slice/container-*/cpu.stat
cat /sys/fs/cgroup/system.slice/container-*/memory.current四、网络问题解决方案
APT 下载超时问题
E: Failed to fetch ... Connection timed out解决方法
- 更换国内镜像源
- 配置 APT 代理
- 手动下载 deb 包
- 使用静态编译版本
手动下载 DEB 包
# 在其他机器下载
mkdir podman-debs && cd podman-debs
wget https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/armhf/podman_3.4.2-4_armhf.deb
wget https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/armhf/conmon_2.0.25-2_armhf.deb
wget https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/Debian_11/armhf/runc_1.1.4-2_armhf.deb
# 打包传输
tar -czf podman-update.tar.gz *.deb
scp podman-update.tar.gz root@target:/tmp/
# 在目标机器安装
cd /tmp
tar -xzf podman-update.tar.gz
dpkg -i *.deb
apt --fix-broken install -y五、诊断工具
完整诊断脚本
#!/bin/bash
# 保存为 diagnose-podman.sh
echo "=== Podman Stats 诊断报告 ==="
echo ""
echo "1. 系统信息"
echo "-------------------"
uname -a
echo ""
echo "2. Podman 版本"
echo "-------------------"
podman version 2>&1 | head -5
echo ""
echo "3. Cgroup 信息"
echo "-------------------"
mount | grep cgroup
echo ""
echo "4. Podman 配置"
echo "-------------------"
cat /etc/containers/containers.conf 2>/dev/null || echo "配置文件不存在"
echo ""
echo "5. 环境变量"
echo "-------------------"
env | grep -i container
echo ""
echo "6. 运行中的容器"
echo "-------------------"
podman ps -a
echo ""
echo "7. Cgroup 路径"
echo "-------------------"
find /sys/fs/cgroup -name "*container*" -type d 2>/dev/null | head -10
echo ""
echo "8. 测试 stats 命令"
echo "-------------------"
timeout 2 podman stats --no-stream 2>&1 || echo "命令执行失败"
echo ""
echo "9. 系统日志"
echo "-------------------"
journalctl -u podman --no-pager | tail -20
echo ""
echo "=== 诊断完成 ==="六、最佳实践建议
推荐操作顺序
- ✅ 首选:方案一(配置 cgroupfs)- 最简单,无风险
- ✅ 备选:方案四(替代脚本)- 绕开问题
- ⚠️ 谨慎:方案二(降级 cgroup v1)- 需要重启
- ⚠️ 谨慎:方案三(升级 Podman)- 可能影响现有容器
环境特定建议
ARMv7 + Podman 3.0.1
- 优先使用:方案一 + 方案四组合
- 避免:升级到 4.x 版本(可能不兼容)
- 长期:考虑迁移到 Docker
生产环境
- 先在测试环境验证
- 备份重要容器配置
- 保留旧内核作为回退选项
监控替代方案
# 使用 Docker 兼容命令
podman stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
# 使用 Prometheus 监控
# 部署 node_exporter + cadvisor七、常见问题 FAQ
Q1: 为什么会出现数值溢出?
A: cgroup v2 返回的数值(如 7038456085)超出了 32 位系统的处理范围,Podman 3.0.1 的解析代码存在缺陷。
Q2: 升级内核能解决问题吗?
A: 能部分解决,但主要问题在 Podman 版本。升级到 6.1+ 内核配合 Podman 4.x 效果最好。
Q3: 配置 cgroupfs 有风险吗?
A: 没有风险,只是改变资源管理方式,不影响容器运行。
Q4: 替代脚本的 CPU 百分比准确吗?
A: 是简化计算,仅供参考。精确监控建议使用 Prometheus 等专业工具。
Q5: 如何永久生效配置?
A: 配置文件 /etc/containers/containers.conf 和环境变量 /root/.bashrc 都会永久生效。
八、总结
核心要点
- 根本原因:Podman 3.0.1 + cgroup v2 + ARM 架构的兼容性问题
- 最快解决:配置 cgroupfs 或使用替代脚本
- 根本解决:升级 Podman 到 4.x 或使用 Docker
- 临时方案:替代脚本绕过 stats 解析问题
关键命令速查
# 配置 cgroupfs
mkdir -p /etc/containers
echo '[engine]
cgroup_manager = "cgroupfs"' > /etc/containers/containers.conf
# 测试
podman stats --no-stream
# 重启服务
systemctl restart podman
# 查看配置
cat /etc/containers/containers.conf