使用阿里云ACK集群创建Pod卡在ENI IP分配冲突问题记录
K8S集群使用的ACK托管集群,网络插件使用Terway ENI模式,Pod 创建分配IP冲突问题排查
背景
K8S集群使用的ACK托管集群,网络插件使用Terway ENI模式
现象
业务发布后,部分机器的Pod状态一直是ContainerCreating, describe报错信息为:FailedCreatePodSandBox; address already in use; 导致业务发布失败。
问题分析
-
ENI IP分配冲突,首先想到的是网络组件terway CNI分配出现的bug,对ENI IP管理出现重复分配的情况;查看报错分配的IP并没有在集群中,联系阿里云确认terway当前版本并未出现过类似的bug;
-
ENI IP分配冲突是调度后的操作,已确认K8S集群中没有分配该IP的POD,POD已经分配制定宿主机,于是查看宿主机上是否有分配使用该IP的容器;
crictl pods | awk ‘{print $1}’ | xargs -nl -I {} bash -c ‘echo {};crictl inspectp {} |grep 冲突IP’
遍历机器所有容器,查看是否有容器占用了该IP,果然发现该宿主机有容器占用了冲突的ENI IP! -
查看容器发现,该容器进程已经处于D状态,导致容器占用的netns没有回收完成。
-
确认该容器是业务残留的POD长期处于Terminating状态后强制清理了POD信息,导致container仍残留在机器上占用IP导致的冲突
问题原因
- IP冲突是因为清理了Terminating状态的POD,但容器并未退出回收成功,netns并未释放,还是占用了ENI IP,导致IP冲突。
- 处于Terminating状态退出异常的业务继续排查原因,是因为内核bug导致退出异常。
附录
疑问一、 Terminating状态的POD被强制清理后为什么container还在运行?
POD由于在删除退出过程卡在与内核的交互过程,所以一直处于Terminating状态。
K8S api提供强制删除资源的接口,强制删除会清理K8S集群存储数据ETCD中对应资源的所有信息,但并不会进一步继续处理宿主机上kubelete与CRI的交互工作;K8S集群中已经完全清理了POD的信息,宿主机上container还没有完成退出。
kubectl delete pods --grace-period=0 --force
疑问二、container还属于Running状态为什么CNI会回收PodIP?
按CRI的交互逻辑,container 处于running状态,CNI并没有完成del network和netns的回收;那CNI怎么回收的该ENI IP?联想到contiv的逻辑是集群强制清理pod资源清理K8S的etcd数据时,同时会清理contiv etcd的数据释放POD对应的IP资源; 同样查找terway相关的资料,**terway的CNI插件为保证最后网络设备在pod删除时能够肯定被释放掉,CNI会GetPod获取apiserver的pod信息,对比GetLocalPod的数据,更新本地的storage存储的IP信息。**清理间隔时间是每5min调用一次,所有当强制清理POD信息后,CNI会调用apiserverde对比pod的信息,释放IP。
疑问三、没有正常回收的PodIP为什么只在原宿主机重新分配,而不会再次被分配到其他宿主机?
还是Terway组件,会给ENI IP进行热预留; 集群配置的是0-5个,可以exec对应机器的terway pod查看;
总结
对于Terminating状态的POD,强制清理需谨慎,要确认下是否在机器上有CRI CSI的残留。
参考文档
关于Terway组件的参考文档: https://www.cnblogs.com/gaorong/p/11710246.html
更多推荐
所有评论(0)