如何解决因 IP 地址耗尽导致的容器网络层创建失败故障实战

作者:袖梨 2026-07-14
先确认是否真为IP耗尽:查云平台子网“可用IP数”是否接近0,或用CLI命令验证;再检查K8s节点PodCIDR分配及CNI日志中是否有“exhaust”“no available”等提示,避免误判后盲目扩容。

确认是否真为IP耗尽

不要一看到“Failed to allocate IP”就直接扩容。先验证是不是真的没IP了。

查子网剩余地址:在云平台控制台找到对应子网,看“可用IP数”是否接近0;或用CLI命令,如AWS:aws ec2 describe-subnets --subnet-ids subnet-xxx --query 'Subnets[0].AvailableIpAddressCount';阿里云:aliyun vpc DescribeSubnetAttribute --SubnetId subnet-xxx --RegionId cn-shanghai --query AvailableIpAddressCount。

查容器网络插件状态:如果是K8s集群,运行kubectl get nodes -o wide看各节点分配的PodCIDR;再执行kubectl logs -l k8s-app=calico-node -n kube-system -c calico-node | grep -i "exhaust|no available",确认CNI日志里是否有明确的地址池枯竭提示。

快速缓解:释放僵尸IP与回收闲置资源

很多“IP不足”其实是假性耗尽——有IP被分配但未真正使用,或Pod已删而IP未归还。

  • 清理终止态Pod:运行kubectl get pods --all-namespaces --field-selector status.phase!=Running -o wide,删除所有Succeeded/Failed/Pending状态且长期无更新的Pod
  • 重启CNI组件:对Calico可删掉calico-node Pod(DaemonSet会自动重建),强制刷新节点本地IPAM缓存;Flannel则需重启flanneld服务并检查/run/flannel/subnet.env是否仍指向旧网段
  • 检查宿主机ARP表和邻居缓存:执行ip neigh show nud failed或arp -a | grep incomplete,清除大量失效条目,避免IP被错误标记为占用

中长期扩容:调整子网与地址池配置

临时救火之后,必须结构性扩容,否则一周内大概率复现。

  • 子网CIDR升级:若当前是/24(256个IP),至少扩到/22(1024个);注意云平台通常不支持直接修改已有子网CIDR,需新建子网+迁移节点,建议用Terraform做灰度切换
  • 重设CNI地址池:以Flannel为例,编辑ConfigMapkube-flannel-cfg,将Network字段从10.244.0.0/16改为10.244.0.0/14,再滚动重启flannel DaemonSet
  • 启用IPv6双栈:Docker和主流CNI(Calico/Cilium)均已支持。只需在daemon.json中添加{"ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"},重启Docker;K8s则开启IPv6DualStack特性门,并配置podSubnet含IPv6段

预防机制:建立IP使用监控与预警

靠人工盯日志太被动。把IP余量变成可观测指标,才能提前干预。

在Prometheus中采集以下数据源:

  • 子网可用IP数(通过云厂商Exporter或自定义脚本调OpenAPI)
  • CNI插件暴露的felix_ipam_pool_usage(Calico)、flannel_network_usage(Flannel)等指标
  • K8s节点上node_network_ipv4_cidr_addresses与实际分配Pod数的比值

设置告警规则:当任意子网或节点IP使用率 > 85% 持续5分钟,立即触发企业微信/钉钉通知;> 95% 时自动暂停新Deployment创建(可通过Admission Webhook拦截)。

相关文章

精彩推荐