php报错为:php_network_getaddresses:getaddrinfo failed
这类问题对应的都是dns解析错误。这里我的错误是因为我连接阿里云数据库用的域名方式,同样的错误还可能出现在调用带域名的网络服务等情况。
首先我在阿里云上的k8s中有多个节点,使用的是同一个安全组策略(所以一开始没有考虑是网络安全组问题)。但是其中一个节点中的pod的dns出现问题。连接不到数据库,也ping不通其他的域名。而且如果你部署的pod数量大于1,那么你会发现某些时候访问不出现问题,某些时候访问出现了问题,要看你的请求被路由到的那个pod是否在出问题的节点上,问题定位困难。
这里的根本原因是pod跨节点通信问题,对于pod来说,他们需要通过一个dns的服务(kube-dns)来解析域名,这个dns服务对应的pod叫coredns,它是一个pod,所以也会被调度到某个节点。
一般这个pod阿里云已经为我们创建好的。他在kube-system命名空间下,我们查询一下
$ kubectl get pods -n kube-system -o wide|grep dns
coredns-6d5d8b96d5-6nbdc 1/1 Running 0 30d 172.20.0.3 cn-hangzhou.192.168.1.45
coredns-6d5d8b96d5-jknzf 1/1 Running 0 30d 172.20.0.2 cn-hangzhou.192.168.1.45
可以看到 我的集群中这两个coredns,两个都被布置到了192.168.1.45这个节点上。所以在其他节点上的pod,调用dns的时候,都是要跨节点调用,会出现网络问题。所以需要在安全组中放行k8s的pod网络CIDR实现每个节点上pod的dns解析。
这样就解释了,为什么两个节点在同样的安全组 ,有不同的现象。应该是表现正常的那些节点上有coredns 所以解析可以正常。 不正常的节点上没有coredns,而且这些不正常节点的pod和coredns的ip的53端口不通。
我去查询了我不能解析dns的pod所在的节点ip,果然就是没有coredns的节点。
在节点的安全组中放行k8s的pod网络CIDR。来解决pod跨节点调用coredns的问题,同样这样也解决了之后其他的pod跨节点通信的问题。
建议应该增加coredns应用的反亲和性,防止coredns调度到一台主机上,毕竟coredns是一个系统组件,我们应该尽量让coredns分散部署,增强其可用性。
亲和性反亲和性之后再出文章讲解。