Bootstrap

剖析kubernetes service的IP能否在宿主机中ping通



前言

当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协议的封包过程


悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;