问题现象:
新建的k8s集群,在主机节点上无法访问本主机的podip。
排查过程
通过进入容器的网络命令空间抓包,发现容器里面能收到主机上的ping包,并且返回出去了,但是ping的界面一直无响应。
tcpdump -i eth0 icmp -ne
查看主机的ip信息,主机上有多个ip,容器收到的ping ip和主机建立连接的calico ip并非同一ip。
容器回包的流程应该是 容器eth0接口——> calico calixxxx网卡—->根据主机上路由规则转发应用侧。
通过tcpdump 抓取calico calixxx网卡发现也可以正常收到报文,那么问题就可能是路由规则或者是iptables防火墙问题。
iptables -nL
查看并未发现有drop的相关规则,而且在容器中ping主机上的ip,有2个ip是可以正常通信,2个ip无法通信。
ip route show
主机路由和容器路由并无其他异常
ip rule show
查看主机的路由策略,发现有两条额外的策略路由,正好是无法ping通的ip地址。
这两条策略路由说明来自这两个ip的报文,都从路由表是100或者101的路由出去。
ip route show table 100
规则路由中还有其他三种路由表local、main、default
local:路由表local包含本机路由及广播信息。例如,在本机上执行ssh 127.0.0.1时,就会参考这份路由表的内容,在正常情况下,只要配置好网卡的网络设置,就会自动生成local路由表的内容,我们应该也不必修改其内容。
main:使用传统命令route -n所看到的路由表就是main的内容。Linux系统在默认情况下使用这份路由表的内容来传输数据包,因此,其内容极为重要,在正常情况下,只要配置好网卡的网络设置,就会自动生成main路由表的内容。
default:最后是default路由表,这个路由表在默认情况下内容为空;除非有特别的要求,否则保持其内容为空即可。
因为路由规则中的另外两个的优先级100、101大于main的优先级,所以在主机上ping容器的ip优先使用id是100的优先级路由ip,这条规则路由会把容器的报文转发到其指定路由上,从而导致ping容器ip无法收到报文。
解决方案
新建一条优先级更高的规则路由,把目标是容器网段的规则路由转发主路由表中。
ip rule add to 172.20.0.0/16 table main prio 99