Skip to content

RKE1 + Kubernetes 1.16.3 CoreDNS Pod 卡在 ContainerCreating 排查文档

一、问题现象

数据来源:pod_failed_ContainerCreating.csv(苏州集群 / 云平台 SZB 集群)

NAMEREADYSTATUSRESTARTSAGEIPNODE
coredns-6d546f654-9tcbc0/1ContainerCreating08h<none>szb12032
coredns-6d546f654-lbzff0/1ContainerCreating08h<none>szb14012
coredns-6d546f654-pqfks0/1ContainerCreating07h57m<none>szb13036
coredns-6d546f654-svhp70/1ContainerCreating08h<none>szb13014
coredns-6d546f654-xg4f40/1ContainerCreating07h57m<none>szb13032

关键特征分析

  1. 全部是 CoreDNS Pod,分布在 5 个不同节点(szb12032 / szb14012 / szb13036 / szb13014 / szb13032);
  2. 持续 8 小时 未就绪,说明不是临时抖动,而是持续性故障;
  3. IP 均为 <none> —— 说明卡在 CNI 网络配置阶段,Pod 根本没有分配到 IP
  4. RESTARTS 为 0 —— 容器从未启动过,问题发生在容器创建前的沙箱(sandbox)/ 网络准备阶段。

结论预判:这是集群级 CNI 网络故障(非单节点、非镜像问题),最可能的原因是 IP 分配失败(IPAM 耗尽或泄漏)CNI 插件本身异常。CoreDNS 全部不可用会导致全集群 DNS 解析中断,影响面极大,需优先处理。


二、排查步骤(按优先级)

第 1 步:查看 Pod 事件,直接定位失败原因(最关键)

bash
# 查看任一故障 Pod 的事件,重点看 FailedCreatePodSandBox 的具体报错
kubectl -n kube-system describe pod coredns-6d546f654-9tcbc | tail -30

# 或批量看事件
kubectl get events -n kube-system --field-selector reason=FailedCreatePodSandBox --sort-by=.lastTimestamp | tail -20

根据事件中的报错信息对照下表:

事件报错关键词根因方向
no IP addresses available in range set / failed to allocate pod IPIP 耗尽或 IPAM 泄漏 → 走第 2 步
CNI request failed with status 400 / error getting ClusterInformation / connection is unauthorizedCalico 与 API Server 通信异常 → 走第 3 步
networkPlugin cni failed to set up pod ... network: ...CNI 插件二进制/配置损坏 → 走第 3 步
failed to create pod sandbox ... context deadline exceeded容器运行时(docker)响应超时 → 走第 4 步
failed to pull image / ImagePullBackOff镜像拉取失败(本例 8h 无 IP,可能性较低) → 走第 5 步

第 2 步:检查 IP 是否耗尽 / 泄漏(结合本集群此前已发现 IP 回收问题)

故障节点宿主机(如 szb12032)上执行:

bash
# 1. 查看 CNI IPAM 分配记录目录
ls /var/lib/cni/networks/

# 2. 统计已分配 IP 数量(/24 上限 253,接近即耗尽)
ls /var/lib/cni/networks/<网络>/ | grep -cE '^[0-9]+\.'

# 3. 检查泄漏:容器已不存在但 IP 记录未回收
for f in /var/lib/cni/networks/<网络名>/*; do
  ip=$(basename "$f")
  [[ "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] || continue
  cid=$(cat "$f")
  if ! docker ps -q --no-trunc | grep -q "$cid"; then
    echo "泄漏 IP: $ip  (容器 $cid 已不存在)"
  fi
done

在控制节点上检查集群级 IP 分配:

bash
# 各节点 PodCIDR 分配情况
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.podCIDR}{"\n"}{end}'

# controller-manager 日志中是否有 IPAM 报错
kubectl -n kube-system logs -l component=kube-controller-manager --tail=500 | grep -i "cidr\|ipam\|allocate"

若确认泄漏:删除容器已不存在的 IP 记录文件即可释放:

bash
rm /var/lib/cni/networks/<网络>/<泄漏的IP>   # 仅限确认容器已销毁的记录

若确认单节点 /24 真耗尽:需降低节点 Pod 密度或调整 PodCIDR 掩码(变更需评估)。

第 3 步:检查 CNI 插件状态(RKE1 默认 Canal = flannel + calico)

bash
# 检查各故障节点上的 calico-node / canal 组件状态
kubectl -n kube-system get pods -o wide | grep -E "canal|calico|flannel"

# 查看故障节点上 canal 组件日志
kubectl -n kube-system logs <canal-pod> -c calico-node --tail=100
kubectl -n kube-system logs <canal-pod> -c kube-flannel --tail=100

# 宿主机上检查 CNI 配置与二进制是否完整
ls /etc/cni/net.d/
cat /etc/cni/net.d/*.conf*
ls /opt/cni/bin/

若 Canal Pod 本身异常(CrashLoopBackOff / NotReady),先修复 CNI 组件。

第 4 步:检查故障节点 kubelet 与容器运行时

bash
# 在故障节点(如 szb12032)上执行
journalctl -u kubelet --since "9 hours ago" | grep -iE "cni|sandbox|network" | tail -30

# 检查 docker 健康状态
docker info | grep -E "Server Version|Storage Driver"
docker ps | head -5

# 检查磁盘是否写满(常见导致 sandbox 创建失败)
df -h / /var/lib/docker /var/lib/cni

第 5 步:检查镜像是否就绪(排除项)

bash
# 在故障节点上确认 coredns 镜像是否存在
docker images | grep coredns

# 手动测试拉取
docker pull <coredns镜像完整地>

三、临时恢复手段

⚠️ CoreDNS 全部不可用期间,集群内 DNS 解析完全中断,应尽快恢复。

bash
# 若确认是 IP 泄漏/分配卡住,清理泄漏 IP 后重启故障 Pod 触发重新调度
kubectl -n kube-system delete pod -l k8s-app=kube-dns

# 若怀疑单节点 CNI 状态损坏,可在该节点重启 kubelet(会重建该节点 Pod 网络)
systemctl restart kubelet      # 在故障宿主机上执行

删除 Pod 后 Deployment 会自动重建新副本,观察新 Pod 能否正常获取 IP:

bash
kubectl -n kube-system get pods -l k8s-app=kube-dns -o wide -w

四、根因假设排序(基于现有证据)

优先级假设依据
1IPAM 泄漏导致 IP 耗尽本集群此前已排查 IP 回收问题;Pod 8h 无 IP;多节点同时出现说明是共性问题
2CNI 插件(Canal/Calico)与 API Server 通信异常多节点同时故障,共性组件问题可能性大
3节点 kubelet / docker 异常导致 sandbox 创建失败5 节点同时出现概率较低,但需排除
4集群 PodCIDR 池整体耗尽节点数量多、长期运行的老集群存在此风险

五、后续建议

  1. 先执行第 1 步拿到 describe pod 的具体报错,即可锁定根因方向;
  2. 修复完成后,持续观察新 CoreDNS Pod 状态与 IP 分配情况;
  3. 建立 IP 泄漏定期巡检脚本(对比 /var/lib/cni/networks/ 记录与存活容器);
  4. CoreDNS 建议配置 PodDisruptionBudget 和多副本反亲和,避免全部副本同时不可用;
  5. 长期仍需规划集群升级(K8s 1.16.3 已停止维护多年)。

文档生成时间:2026-07-23数据来源:pod_failed_ContainerCreating.csv(苏州集群 / 云平台 SZB 集群)