故障现象描述
某生产环境 Kubernetes 集群中,新部署的 Pod 长期卡在 "ContainerCreating" 状态,通过 kubectl describe pod
命令查看事件日志,发现以下关键报错信息:
|
Warning FailedCreatePodSandBox 30s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "xxx" network for pod "xxx": networkPlugin cni failed to set up pod "xxx" network: plugin type="flannel" name="kube-flannel-ds" failed (added netns /proc/28456/ns/net to delay queue): no IP addresses available in network: cni0 |
该错误表明 CNI 插件在尝试为 Pod 配置网络时失败,具体原因是无法从 cni0
网桥获取可用 IP 位置。进一步检查发现,集群中所有节点均存在类似问题,且 Flannel 相关组件状态异常。
根因分析
1. Flannel 网络模型工作原理
Flannel 通过以下核心机制实现跨主机容器通信:
- Overlay 网络:在宿主机上创建
flanneld
守护进程,负责分配子网并维护节点间路由表 - CNI 集成:提供符合 Kubernetes 标准的 CNI 插件,在 Pod 启动时配置虚拟网络设备
- 后端驱动:支持 VXLAN、UDP、Host-GW 等多种数据封装方式,默认使用 VXLAN 模式
当 Flannel 正常工作时,其工作流程为:
kube-flannel-ds
DaemonSet 在每个节点部署flanneld
服务- 服务启动时从 etcd 或 API Server 获取预设的子网范围(如
10.244.0.0/16
) - 为当前节点分配子网(如
10.244.1.0/24
)并创建cni0
网桥 - 通过 CNI 插件将 Pod 网卡(
veth
对)挂载到cni0
,并配置 IP 路由
2. 故障触发条件
通过系统化排查,发现本次故障的直接原因是 Flannel 组件未正确部署,具体表现为:
- DaemonSet 未运行:
kubectl get pods -n kube-system
显示kube-flannel-ds
不存在 - CNI 配置缺失:
/etc/cni/net.d/
目录下缺少 Flannel 配置文件 - 网络设备异常:
ip link show
命令未发现cni0
和flannel.1
设备
进一步分析组件缺失的可能原因:
- 初始化脚本遗漏:集群安装时未执行 Flannel 的部署 YAML 文件
- 资源清理误操作:运维人员可能误删了 Flannel 相关资源
- 版本兼容性问题:CNI 插件版本与 Kubernetes 主版本不匹配
- 存储卷异常:Flannel 使用的 ConfigMap 数据损坏
3. 网络初始化失败路径
当 Flannel 组件缺失时,Pod 创建过程中的网络配置阶段会按以下路径失败:
- Kubelet 调用 CNI 接口执行
ADD
操作 - CNI 执行链中缺少 Flannel 插件处理,直接使用默认网桥模式
- 由于未配置 overlay 网络,
cni0
网桥无可用 IP 池 - 最终触发
no IP addresses available
错误,Pod 沙箱创建失败
修复方案
1. 组件恢复部署
操作步骤:
- 从官方仓库获取与 Kubernetes 版本匹配的 Flannel YAML 文件
- 验证文件完整性:
- 确认包含
kube-flannel.yml
主配置文件 - 检查
rbac
权限配置和DaemonSet
定义
- 确认包含
验证标准:
- 所有节点
kube-flannel-ds
状态显示Running
ip addr show
命令能看到cni0
和flannel.1
设备docker network inspect
显示正确的子网分配
2. 网络状态修复
对于已存在的异常 Pod,需执行以下清理和重建操作:
- 删除卡在创建中的 Pod:
kubectl delete pod <pod-name> --grace-period=0 --force - 清理残留网络命名空间(需在节点执行):
# 查找残留命名空间 ls /var/run/netns/ | grep -v "^$" # 强制删除(谨慎操作) rm -f /var/run/netns/<namespace-name> - 重启 Kubelet 服务使配置重新加载:
systemctl restart kubelet
3. 预防性维护措施
为避免同类问题再次发生,建议实施以下改进:
- 部署校验机制:在集群初始化脚本中添加 Flannel 组件存在性检查
- 监控告警:配置 Prometheus 规则监控
flanneld
进程存活状态 - 变更管理:严格执行资源修改的审批流程,记录所有网络组件变更
- 备份策略:定期备份
kube-system
命名空间下的 ConfigMap 和 Secret 资源
扩展思考
1. 多网络插件共存场景
在复杂环境中,可能存在多个 CNI 插件同时部署的情况(如 Flannel + Calico)。此时需注意:
- 配置 CNI 插件执行顺序(通过
/etc/cni/net.d/
文件命名排序) - 使用
Multus
等元插件实现多网络接口支持
2. 不同后端驱动选型
Flannel 提供多种后端实现,选择时应考虑:
- VXLAN:通用性强,但有 50 byte 封装开销
- Host-GW:性能最优,但要求节点二层互通
- UDP:兼容性最好,但性能较差(已逐渐淘汰)
生产环境推荐使用 VXLAN 模式,其平衡了性能与部署复杂度,且支持跨主机子网通信。
3. 故障排查工具链
构建系统化的网络故障排查工具集:
- 连接测试:
cnitool
、nsenter
- 流量捕获:
tcpdump
、tshark
- 路由分析:
ip route
、bridge fdb
- 日志聚合:ELK 或 Loki 集中管理组件日志
总结
本次故障清晰地展示了 CNI 插件在容器网络中的核心地位,Flannel 的缺失直接导致网络命名空间初始化失败。通过组件恢复、状态清理和预防措施的三阶段修复方案,系统恢复了正常的网络功能。该案例强调了:
- 容器网络组件的完整性对集群稳定性的关键影响
- 系统化排查方法在复杂故障定位中的重要性
- 预防性维护措施对降低重复故障率的价值
建议运维团队将此类网络故障的排查流程纳入标准化操作手册,并定期进行故障演练,以提升集群的健壮性。