1.问题描述
客户侧在变更容器安全组之后出现网络不通。
2.问题排查
1)接到客户反馈 Kubernetes 托管版集群出现网络问题,电话沟通后授权进行查看:Pod 网络通畅,域名解析出现异常;(ping IP 可通,但ping域名不通)
2)结合客户操作,怀疑与安全组配置有关,尝试进一步排查安全组问题。详细排查无问题后,决定重启 coredns POD。重启后 coredns POD 漂移到其它 ECS上,集群中大部分主机恢复正常;
3)确认coredns原宿主机存在网络连接问题,将该主机踢出集群后,集群恢复正常;
4)经过环境测试后最终定位原因在于客户侧误解 Kubernetes 集群安全组页面“解绑实例”功能为解绑安全组,导致误操作解绑和绑定ENI 网卡,同时产品健康检查机制存在缺陷,无法探测到辅助网卡的链路问题,导致问题无法快速发现并解决,最终导致客户集群网络无法联通。
3.优化改进
1)优化安全组页面存在“解绑实例”功能文案,同时增加由 Kubernetes 集群创建的网卡在用户解绑时的风险提示,避免客户误操作引发业务中断;
2)优化健康检查机制,确保辅助网卡链路异常场景能够被快速发现。
4.问题复现
4.1 环境准备
1)kubernetes托管版集群,网络模式为Terway,kube-proxy代理模式为IPVS,四节点,需要创建测试的应用pod;
图1:初始环境
2)查看coredns所在的宿主机,目前该pod存在于201、200机器上;
图2:coredns pod
4.2 具体操作
1)模拟客户侧的操作在安全组界面“解绑coredns所在主机的辅助网卡”;
登录ECS控制台--实例--选择机器--本实例弹性网卡界面查看
图3:实例弹性网卡
跳转至安全组界面---选择集群的安全组实例id---安全组内弹性网卡--搜索刚刚查找的弹性网卡--解绑实例
图4:安全组内弹性网卡
2)解绑完成之后再次将辅助网卡绑定至原有实例;
图5:查看原有实例网卡
3)登录任意一个应用pod内,利用dig http://baidu.com测试解析是否正常
kubectl exec -it centos-deployment-75765fbb54-x5f6v -- /bin/bash,进入pod内:
图6:pod内测试
上图就是一开始客户侧遇到的现象:ping域名不通,ping IP可以通。
4)为什么解绑之后重新绑定至原有实例还是不可以呢?原因就在于解绑后重新绑定网卡后该网卡的state仍然是DOWN状态,需要重新up网卡;
up网卡:ip link set eth1 up
图7:up网卡
网卡在被up后,再次进入pod进行测试,会发现解析就可以正常运行了。
图8:up网卡后测试
其实kube-dns后有两个coredns POD,那么这两个coredns是采取什么策略去提供解析服务呢?
5.问题分析
利用ipvsadm可以看到coredns是按照rr的方式去提供服务的,并且设置了session的超时保持时间是10800(超时时间可以通过查看kube-dns的yaml文件):
图9:kube-dns的session时间
正是因为上述kube-dns的session的保持时间设置了10800,导致域名解析的请求一直都是寻找坏的coredns POD(如coredns也就是被解绑后重新绑定辅助网卡的那台机器上的coredns),所以客户侧在解绑操作后续一直没有无法进行正常解析,类似于下面的现象:
图10:长ping失败现象
测试下去掉该session设置,再次进行域名解析测试(修改kube-dns svc的yaml中的sessionAffinity为None):
图11:svc yaml
图12:dig图
图13:tcpdump抓包
所以修改sessionAffinity为None后,第一次的解析会走好的coredns,第二次请求就会走坏的coredns,这也就是证明coredns以rr策略提供服务的。
图14:长ping正常现象
本文为阿里云原创内容,未经允许不得转载。
来源:oschina
链接:https://my.oschina.net/u/1464083/blog/4711499