K8s 容器启动失败 cgroup v1-v2 不匹配排查实战
K8s 容器启动失败:cgroup v1/v2 不匹配(cpu.cfs_quota_us 写入 EINVAL)
概述
容器创建时,运行时(runc)按 cgroup v1 接口去写 CPU 配额 cpu.cfs_quota_us,但节点底层 cgroup 实际是 v2(或 v2 接口)——v2 下文件名是 cpu.max,v1 的 cpu.cfs_quota_us 在 v2 层级里不存在/不可写,内核返回 EINVAL,容器一路 init 失败。这是 K8s 1.25→1.31 强制 cgroup v2 迁移期最经典的坑,根因几乎都是 containerd/kubelet 的 cgroup 驱动没统一到 v2 + systemd。
场景:容器反复 FailedCreateContainer
现象(kubectl describe pod 原文)
Warning Failed 39m (x4 over 41m) kubelet
Error: failed to create containerd task: failed to create shim task:
OCI runtime create failed: runc create failed: unable to start container process:
error during container init: error setting cgroup config for procHooks process:
failed to write "52000": write
/sys/fs/cgroup/cpu,cpuacct/kubepods.slice/kubepods-burstable.slice/
kubepods-burstable-pod473ff63b_482f_4b3b_a0db_4d1afa0f4211.slice/
cri-containerd-go-center-mis-gateway.scope/cpu.cfs_quota_us:
invalid argument: unknown
关键信息解码
| 线索 | 含义 |
|---|---|
cpu.cfs_quota_us: 52000 | 写入值 52000 µs = 0.52 核,对应容器 limits.cpu: 520m(值本身合法,排除值错) |
路径含 cpu,cpuacct/... | cgroup v1 的控制器挂载风格(v2 是统一层级,无逗号拼接名) |
kubepods-burstable.slice | Pod QoS = Burstable |
go-center-mis-gateway | 出问题的容器 / Pod 名 |
x4 over 41m | 重试 4 次全失败,kubelet 持续 BackOff,容器起不来 |
报错链路:kubelet → containerd task → shim task → OCI(runc) → container init → 设 cgroup → 写 v1 文件失败。失败在容器初始化最后一步:挂 cgroup 限制。
排查 SOP
# 1. 节点 cgroup 版本:cgroup2fs = v2,tmpfs = v1
stat -fc %T /sys/fs/cgroup/
# 2. containerd 是否开了 systemd cgroup(关键)
containerd config dump 2>/dev/null | grep -i systemdcgroup
# 或直接看配置文件
grep -i systemdcgroup /etc/containerd/config.toml
# 3. kubelet 的 cgroup 驱动
ps -o cmd= -p $(pidof kubelet) | tr ' ' '\n' | grep cgroup-driver
# 4. 看目标 cgroup 下实际有什么文件(验证接口版本)
# v2 应有 cpu.max;v1 才有 cpu.cfs_quota_us
# 对应 pod uid: 473ff63b_482f_4b3b_a0db_4d1afa0f4211
ls /sys/fs/cgroup/kubepods.slice/kubepods-burstable.slice/ 2>/dev/null
判定矩阵:
| 现象 | 结论 |
|---|---|
stat 返回 cgroup2fs + 仍写 cpu.cfs_quota_us 报错 | 节点 v2,但运行时按 v1 写 → 驱动不匹配 |
grep SystemdCgroup 返回 false | containerd 未启用 systemd cgroup → 根因命中 |
目标 cgroup 下只有 cpu.max 无 cpu.cfs_quota_us | 确认是 v2 层级,v1 文件名无效 |
根因分析 Checklist
- containerd
SystemdCgroup = false:运行时按 v1 路径规范建 cgroup,写cpu.cfs_quota_us到 v2 层级 → EINVAL - kubelet
--cgroup-driver与 containerd 不一致(一个是 systemd,一个是 cgroupfs) - 节点系统 cgroup 版本与集群期望不符:K8s 1.31+ 强制 v2,但节点可能残留 v1 配置或混合挂载(hybrid)
- 节点扩容 / 升级时未统一 cgroup 驱动:新节点用了默认 cgroupfs,老节点是 systemd
核心矛盾:K8s 1.25 起 cgroup v2 GA、1.31 起强制 v2。v2 下 CPU 配额写在
cpu.max(格式"$QUOTA $PERIOD"),不再是 v1 的cpu.cfs_quota_us+cpu.cfs_period_us两个文件。漏配 systemd cgroup 的运行时仍走 v1 接口,于是撞上 EINVAL。
解决方案
统一到 cgroup v2 + systemd 驱动:
# 1. 修改 /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
# 2. kubelet 驱动需一致(kubeadm 节点通常在 /var/lib/kubelet/config.yaml)
cgroupDriver: systemd
# 3. 重启使配置生效
systemctl restart containerd
systemctl restart kubelet
# 4. 验证:节点 cgroup 应是 cgroup2fs,且运行时走 v2
stat -fc %T /sys/fs/cgroup/
# -> cgroup2fs
crictl info | grep -i cgroupdriver
# -> "cgroupDriver": "systemd"
# 5. 该 Pod 会自动从 BackOff 恢复,无需手动删
kubectl get pod go-center-mis-gateway -n <ns> -w
反向方案(不推荐):内核加
systemd.unified_cgroup_hierarchy=0回退 v1 —— 已废弃,别走。正确做法是让运行时适配 v2。
预防措施
- 所有节点统一 cgroup v2 + systemd 驱动,纳入节点初始化 IaC(kubespray/kubeadm 已默认
SystemdCgroup = true) - 节点扩容 / 升级后,自动校验
stat -fc %T /sys/fs/cgroup/+ containerdSystemdCgroup - K8s 大版本升级(尤其跨 1.25 / 1.31)前,先确认集群 cgroup 版本策略
- 对
FailedCreateContainer/OCI runtime create failed类事件配置监控告警,避免 41 分钟才发现 - containerd 与 kubelet 配置纳管为 IaC,禁止手动漂移
关联知识
- ../../07-Knowledge/linux/cgroup v2 详解 — v1→v2 接口映射(
cpu.cfs_quota_us→cpu.max)、SystemdCgroup=true要求、迁移坑表(本故障的”教科书对应”) - ../../07-Knowledge/linux/ebpf/eBPF 排障实战 — eBPF 相关容器/网络排障方法
- ../../07-Knowledge/cilium/Cilium 架构与数据面组件 — Cilium 依赖 cgroup v2,v1 环境会连带异常
- Ingress_reload_失败_health_api-tpa — 同类 Kubernetes 故障(可对照排查思路)
复盘要点
- 集群所有节点的 cgroup 驱动是否统一为 systemd?
- 节点扩容 / 版本升级时,是否校验了 cgroup 版本与驱动一致?
- 对该类
FailedCreateContainer是否有监控告警?(本例 41 分钟才发现) - containerd / kubelet 配置是否纳管为 IaC,是否存在手动漂移?
- K8s 版本(尤其 1.25→1.31)升级是否评估过 cgroup v2 强制影响?
状态: 已解决 复盘日期: 2026-07-22