1.iptables模式无法ping通原因分析
iptables模式下,无法ping通任何svc,包括clusterip.所有ns下,下面来分析原因:
查看kubernetes的网络模式
curl 127.0.0.1:10249/proxyMode
[root@k8s-master01 ~]# curl 127.0.0.1:10249/proxyMode
iptables
可以看到当前我的网络模式是 iptables
那么当应用程序通过服务连接到另一个应用程序时,将发生以下事件:
1.应用程序使用集群DNS将服务名称解析为ClusterIP(虚拟IP)和端口 例如将:redis.elk:6379 解析为 10.0.0.144:6379
2.应用程序将连接请求发送给特定端口(10.0.0.144:6379)ClusterIP
3.由于ClusterIP位于没有路由的特殊网络上,因此请求将转到默认网关
4.请求发送到集群节点的默认网关时,由节点内核处理
5.将所有集群节点配置为,捕获服务正在使用的端口6379上进入ClusterIP地址的请求
6.trap导致数据包头被重写,以便将请求重定向到特定的Pod
7.Pod接收流量并服务请求
问题在于,当请求前往svc服务中定义的端口上的ClusterIP时,才会发生trap。无法将ping流量发送到特定端口,因此永远不会发生trap。
Why?
因为ping基于ICMP ,ICMP不能在TCP/UDP上运行,因此没有TCP/UDP端口的概念。因此,无法在配置为侦听和trap的服务的端口上使用ping。
为什么nc 探测是成功的?
nc 默认是基于tcp, nc -u 是基于udp 所以他探测的协议是tcp/udp 所以是可以探测成功的。
为什么开发语言同样可以连接成功?
因为开发语言是通过(研发可以控制)TCP协议形式的Socket连接。
2.为什么iptables模式下无法ping通svc? 而ipvs模式可以?
来查看下iptables模式下kube-proxy的iptables转发规则
查看filter:
iptable默认策略为拒绝任何icmp端口,除非你手动打开让其支持icmp协议才可以ping通。
而IPVS的ICMP报文处理-由外到内,默认是支持的,所以可以ping通,具体见以下链接: IPVS的ICMP报文处理-由内到外
3.小结
iptables:clusterIP只是iptables中的规则,只会处理ip:port四层数据包,reject了icmp。不能 ping通。
IPVS:ipvs依赖iptables进行包过滤、SNAT、masquared(伪装)。 使用 ipset 来存储需要 DROP 或 masquared 的流量的源或目标地址,以确保 iptables 规则的数量是恒定的,这样我们就不需要关心我们有多少服务了
二者有着本质的差别:iptables是为防火墙而设计的;IPVS则专门用于高性能负载均衡,并使用更高效的数据结构(Hash表),允许几乎无限的规模扩张。
详细可以看这里这位大佬分析的很透彻 跳转