排查Pod网络问题
排查Pod内DNS解析失败原因。
如果遇到Pod内服务报DNSError的错误,例如:
{"error":{"class": "DNSError", "code": 499, "details": "Post \"https://default-kevstone:30357/v3/auth/tokens\": dial tcp: lookup default-kevstone: i/o timeout"}}
这类错误一般意味着Pod之间的网络通信有问题。因为Pod之间通信一般最先要进行对端的DNS解析,由于到达coredns的Pod网络不通,导致DNS解析错误,因此最先暴露出来的是DNSError的错误。
基本原理
Pod内通过集群的coredns进行域名解析。CoreDNS配置了10.96.0.10的service IP。访问coredns时,首先由kubeproxy实现service IP到Pod IP的NAT转换,如果Pod在本节点,则直接访问Pod。否则通过tunl0以IP-in-IP或VXLAN隧道发送到对端Pod所在节点,进而解封装投递到目标Pod。
平台在每个节点采用IPVS作为Service IP到Pod IP的NAT转换。需确保节点的IPVS规则表有对应10.96.0.10的NAT规则。
平台采用calico作为容器网络的插件,采用IP-in-IP或VXLAN隧道作为Pod之间报文的封装协议。
如果采用IP-in-IP隧道,则在每个节点上都有一个 tunl0 的三层虚拟网络接口,该接口作为该节点IP-in-IP隧道的端点。
如果采用VXLAN隧道,则在每个节点上都有一个 vxlan.calico 的二层虚拟网络接口,该接口作为该节点 VXLAN 隧道的端点。
Pod的IP从10.40.0.0/16 (该网络前缀可以在ocboot初始化时配置) 随机分配。每个节点上都会为集群中其他节点的Pod所在的/26网段(含64个IP地址)配置通过tunl0且下一跳为该Pod所在节点IP的静态路由。如果缺少对应Pod的路由,则也会出现Pod之间网络不通。
Calico隧道协议的切换
平台默认采用IP-in-IP隧道协议,可以在Kubernetes控制节点执行以下命令将Calico隧道协议切换为 VXLAN。常见切换原因为底层网络不支持IP-in-IP协议。
export DATASTORE_TYPE=kubernetes
calicoctl patch felixconfig default -p '{"spec":{"vxlanEnabled":true}}'
calicoctl patch ippool default-ipv4-ippool -p '{"spec":{"ipipMode":"Never", "vxlanMode":"Always"}}' ## wait for the vxlan.calico interface to be created and traffic to be routed through it
calicoctl patch felixconfig default -p '{"spec":{"ipipEnabled":false}}'
如果需要调整MTU,请用如下命令:
calicoctl patch felixconfig default -p '{"spec":{"ipipMtu":1430}}'
calicoctl patch felixconfig default -p '{"spec":{"vxlanMtu":1430}}'
同时还需要修改veth网口的MTU,改配置在configmap的calico-config中:
kubectl -n kube-system edit configmaps calico-config
修改 "veth_mtu" 为指定值(注意该值是字符串)
...
typha_service_name: none
veth_mtu: "1430"
kind: ConfigMap
metadata:
...
原因排查
Service IP NAT问题
在无法DNS解析Pod所在节点 执行如下命令,确认IPVS的转发表内有相应的表项:
ipvsadm -Ln | grep -A 3 10.96.0.10
正常应该有三个表项:
TCP 10.96.0.10:53 rr
-> 10.40.52.149:53 Masq 1 0 0
-> 10.40.52.171:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
-> 10.40.52.149:9153 Masq 1 0 0
-> 10.40.52.171:9153 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 10.40.52.149:53 Masq 1 0 6930
-> 10.40.52.171:53 Masq 1 0 6859
路由问题
如果上一步确认无误,在无法DNS解析Pod所在节点查看到达coredns的Pod IP的路由是否存在,假设coredns的节点IP为上述10.40.52.149和10.40.52.171,则执行如下命令确认相应路由是否存在:
ip route | grep 10.40.52
正确输出如下:
10.40.52.128/26 via 10.41.1.21 dev tunl0 proto bird onlink
这里 10.41.1.21 应该是coredns Pod所在节点的IP