用户问题
Pod创建后访问对象存储OSS不通。
初步排查
初步排查,网络连通性是OK的。再次反馈创建Pod后2分钟内可能存在业务不通。
业务架构
该集群采用了节点自动弹缩功能,节点弹缩范围在13-28之间。
用户周期性创建大批量Pod,共300个,与对象存储OSS交互,Pod生命周期2分钟左右。
CoreDNS中配置了用户DNS。(可以通过CoreDNS的Configmap查看,此处略)
排障预案
1、瞬时大批量Pod能否顺利创建
2、Node autoscaler是否及时
3、集群组件是否正常提供服务
4、DNS域名解析是否能顶住压力
5、节点日志是否有异常:dmesg -T
6、节点上规则是否正常:iptables-save、ipvs list、ipvsadm -ln、ip rule/ip route
7、必要的抓包:tcpdump
问题排查
排查范围
因业务Pod不是一直不能访问OSS,先放弃抓包验证。重建镜像,dig检查DNS是否正常。
问题复现
分析复现后的问题Pod日志
关键信息:
1、用户侧DNS直接解析正常(前两项)。
通过SVC访问,第一次就超时退出。
dig oss.com @IP
connection timed out; no servers could be reached
为什么某些Pod访问集群DNS Service不通,某些Pod访问却正常?
分析原因
通盘分析这300个Pod,状态分为两类:Running,CrashLoopBackOff,其中后者对应上述日志。
CrashLoopBackOff集中在6个Node节点,且这6个节点上只有该状态的Pod,说明这几个节点肯定有问题。
进入其中一个Node,查看iptables规则、ipset规则、ipvs规则,没有任何与集群Service相关的配置,当然也找不到DNS Service与后端Pod对应规则,符合上述超时日志。
Service规则是谁创建的呢,是kube-proxy,每个节点都应该有一个kube-proxy Pod。
查看集群kube-proxy,有6个Pod处于Pending状态,正好与这6个节点对应。
为什么kube-proxy处于待调度状态(Pending),通过“kubectl describe”命令查看Event,显示CPU资源不足,真是这样吗?
手动删除1个CrashLoopBackOff业务Pod,其中一个Pending kube-proxy变为Running,说明确实是CPU资源不足。
优先级PriorityClass
经观察,集群中kube-proxy Damonset没有配置PriorityClass,与业务Pod竞争资源失败。
重新梳理整个流程:
1、同时创建300个业务Pod
2、大量Pod处于Pending状态
3、触发Node扩容
4、节点扩容过程中kube-proxy Damonset触发生成新kube-proxy Pod
5、Node部署完CNI,处于Ready状态,可以接受Pending状态业务Pod调度,与Pending状态kube-proxy Pod竞争节点资源(业务Pod先处于Pending状态可能优先调度成功)
6、业务Pod通过DNS SVC解析OSS域名,但节点未部署成功kube-proxy,未生成相关规则,造成域名解析超时。
尝试解决问题
编辑kube-proxy Damonset,spec添加priorityClassName: system-node-critical,保证关键Pod能正常调度(当资源不足时kill掉低优先级Pod强行创建)。
重复业务流程
先缩容Pod及Node,再扩容,重新验证,300个Pod均满足预期。
问题原因
集群关键组件kube-proxy等未配置合理的PriorityClassName。
解决方案
1、集群关键组件kube-proxy等配置合理的PriorityClassName。
2、集群节点需要等关键组件就绪后才能设置为Ready状态,等待业务Pod调度。
Reference
Pod 优先级与抢占:https://kubernetes.io/zh/docs/concepts/configuration/pod-priority-preemption/
关键插件 Pod 的调度保证:https://kubernetes.io/zh/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/