文章目录
前言
当kubernetes的kube-proxy组件使用iptables模式时,已经创建好的service产生的ip是否能在宿主机中ping通?这也算是初级k8s面试中常问到的一个问题,因此本篇文章就针对该问题进行剖析,看是否能ping通?以及ping不通的原因是什么进行探索。
一、serviceIP是怎么产生的
确认kube-proxy使用的工作模式w为iptables
[root@xmhl-std24 ~]# curl 127.0.0.1:10249/proxyMode
iptables
service 示例
service ip的产生方式
service-cluster-ip-range=10.96.0.0/12表明了service ip地址的范围起始 10.96.0.1--10.111.255.254
二、宿主机中ping serviceIP地址
1.ping示例
以上述第一张截图中的svc ip地址为例进行ping测试,发现ping没返回值,ping不通
2.为什么ping不通剖析
先温习以下TCP/IP四层协议
由上图可知ICMP 是网络层协议,但是它不像 IP 协议和 ARP 协议一样直接传递给数据链路层,
而是先封装成 IP 数据包然后再传递给数据链路层。所以在 IP 数据包中如果协议类型字段的值是 1 的话,就表示 IP 数据是 ICMP 报文。
IP 数据包就是靠这个协议类型字段来区分不同的数据包的。
2.1.封装及解封装过程
2.2.ICMP报文以太网数据帧格式
2.3.原因
如上两张图,icmp协议用于探测两台主机之间是否能够通信
而icmp是位于网络层的协议,网络层下还有数据链路层【mac地址在这一层进行封装】主机在接收到一个icmp的【Echo request】请求时
必须回复一个 【Echo replay】才能确认两个主机之间能够通信, 但是在回复 【Echo replay】之前,主机会确认请求中的ip是否是自己
以及Mac地址是否是自己的。然而虚拟IP是没有mac地址的,所有这个数据被直接丢弃了。
三、ping不通svcIP是否跟iptables规则有关?
背景: k8s版本1.18,kube-proxy使用的是iptables模式 ;service是cluster/NodePort类型
结论: 这个说法是错误的,与iptables规则没有关系。请看下面的示例分析
剖析过程
1、当在宿主机master对svc ip发起ping请求时,根据上图所示,首先进入的是NAT表中的PREROUTING链,查看该链
[root@xxx ~]# iptables -nv -t nat -L PREROUTING
Chain PREROUTING (policy ACCEPT 3757 packets, 259K bytes)
pkts bytes target prot opt in out source destination
219M 15G KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
116M 8303M DOCKER all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
2、查看k8下svc的自定义链KUBE-SERVICES
[root@xxx ~]# iptables -nv -t nat -L KUBE-SERVICES |grep '10.106.217.166'
0 0 KUBE-SVC-VN4GKQXOG5WZADQZ tcp -- * * 0.0.0.0/0 10.106.217.166 /* default/kube-controller-manager:https cluster IP */ tcp dpt:10257
3、查看该svc 对应KUBE-SERVICES链下的规则
[root@xxx ~]# iptables -nv -t nat -L KUBE-SVC-VN4GKQXOG5WZADQZ
Chain KUBE-SVC-VN4GKQXOG5WZADQZ (1 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-SEP-TJB7QBJQQRG5Z5OE all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/kube-controller-manager:https */ statistic mode random probability 0.33333333349
0 0 KUBE-SEP-MP3K7DO6P2Y6F4TD all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/kube-controller-manager:https */ statistic mode random probability 0.50000000000
0 0 KUBE-SEP-2LOQ54ZVXRADQ4ZA all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/kube-controller-manager:https */
4、查看其中任意一条规则
[root@xxx ~]# iptables -nv -t nat -L KUBE-SEP-TJB7QBJQQRG5Z5OE
Chain KUBE-SEP-TJB7QBJQQRG5Z5OE (1 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-MARK-MASQ all -- * * 10.241.243.202 0.0.0.0/0 /* default/kube-controller-manager:https */
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/kube-controller-manager:https */ tcp to:10.241.243.202:10257
如上所示,iptables并没有拒绝icmp协议的数据包,只针对该service的tcp协议做了流量转发,并没有对icmp协议进行额外处理,因此与iptables规则无关.
四、为什么ipvs的的clusterIP类型的service能够ping通?
如下所示
[root@xxx ~]# ip a|grep ipvs0
11: ipvs0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether ce:8b:5d:28:59:28 brd ff:ff:ff:ff:ff:ff
inet 10.107.3.175/22 scope global ipvs0
valid_lft forever preferred_lft forever
inet6 fe80::cc8b:5dff:fe28:5928/64 scope link
valid_lft forever preferred_lft forever
因为ipvs将所有的clusterIP都设置在了一个kube-ipvs0的网卡上不再是虚拟IP,这个ipvs既有实际的ip地址,还有对应的mac地址,同时也符合icmp协议的封包过程