一波四折——记一次K8S集群应用故障排查
part1 初露端倪
一个周四的下午,客户的报障打破了微信群的平静。“我们部署在自建K8S集群上的应用突然无法正常访问了,现在业务受到了影响!”收到客户的报障,我们立刻响应,向客户了解了问题现象和具体报错信息。客户反馈K8S集群部署在云主机上,K8S的应用pod example-app通过访问外部域名example-api.com调用接口,同时访问云数据库做数据查询后将结果返回客户端。客户排查应用pod日志,日志中有如下报错
可以看到最关键的信息是Name or service not known。该报错一般为域名无法解析导致的。由于客户的应用pod只访问example-api.com这一个外部域名,因此判断应该是pod解析该域名时出现异常。为了进一步验证,我们执行kubectl exec -it example-app /bin/sh命令进入pod内执行ping example-api.com命令,果然出现了相同的报错。
因此可以确认应用日志中的报错是域名解析失败导致的。
执行kubectl get pod example-app -o yaml|grep dnsPolicy查看pod的dns策略,是ClusterFirst模式,也就是pod使用K8S集群的kube-dns服务做域名解析。
执行命令kubectl get svc kube-dns -n kube-system,确认kube-dns服务的clusterIP是192.168.0.10 查看pod内的/etc/resolv.conf文件,nameserver设置的正是该IP。
再执行kubectl describe svc kube-dns -n kube-system|grep Endpoints,可以看到dns服务关联了一个coredns pod作为后端。
执行kubectl get pods -n kube-system|grep coredns看到kube-dns关联的coredns pod处于running状态。
再执行kubectl logs coredns –n kube-system,看到pod日志中有大量和客户配置的外部dns服务器IP地址通讯超时的报错
10.16.16.16和172.16.16.16为客户自建DNS服务器的IP地址。为了确认是否是DNS服务器有问题,我们在example-app pod中分别执行nslookup example-api.com 10.16.16.16和nslookup example-api.com 172.16.16.16,均能解析出正确的IP地址。因此判断问题应该出在coredns pod上。此时我们发现,coredns pod的状态变成了crashloobbackoff,稍后又变成了running。观察一段时间后发现pod在这两个状态之间反复切换。
鉴于整个集群只有一个coredns pod,我们修改了coredns的deploy,将pod副本数调至2,