@七禾页话
学习永无止境,记录相伴相随! —— 琉璃康康
最近有同事问我为什么有的SVC的External IP可以从k8s的control节点ping或者curl通,有的却不能。
经过查看发现是跟service中的external-traffic-policy有关系,那么external-traffic-policy是什么?为什么会有业务影响呢?
external-traffic-policy直白翻译就是“外部流量策略”,是控制外部访问service地址之后如何分发给Endpoint也就是相关业务POD的策略,是将流量仅仅转给node-local的POD还是可以转给cluster级别的也就是其他node上的POD。
external-traffic-policy有两个值:
读起来比较绕口,请看图:
@七禾页话
这两种模式的存在是因为kube-proxy在转发报文的时候是否需要保留原访问者的IP也就是数据包里的源地址。那么Local和Cluster两种模式有什么区别呢?
Cluster模式是K8s中默认的external-traffic-policy模式,此模式中kube-proxy不用管POD到底在哪个node上,都会公平的转发。
因为其公平转发,当外部流量进入到集群中后,即使接收外部流量的node上存在业务POD,kube-proxy也可能将流量转给其他node上的POD,从而会看到node之间的不必要的传输,即增加了node之间的东西流量;与此同时,当kube-proxy在给pod转发外部流量的时候,还会做一次SNAT,将数据包中的源地址SNAT成接收此流量的Node的IP。看着也比较拗口,请看图:
@七禾页话
使用此模式后,数据包的IP如下:
@七禾页话
Local模式下,kube-proxy只会将外部流量转发给同节点上的业务POD,不会出现跨Node的流量,从而减少了集群中东西向流量的压力,如下图:
@七禾页话
需要注意的是Local模式下,service的Type只能是NodePort或者LoadBalancer:
$ kubectl apply -f mysvc.yml
The Service "mysvc" is invalid: spec.externalTrafficPolicy: Invalid value: "Local": ExternalTrafficPolicy can only be set on NodePort and LoadBalancer service
在Local的模式下,由于不会出现跨Node的消息转发,所以需要一个LoadBalancer做到负载均衡,如下图:
@七禾页话
但是这样依然会造成POD之间的流量不均衡,因为LoadBalancer只会看到两个Node,是无法知道各个Node上有多少POD的,所以此时需要POD之间使用反亲和(anti-affinity)的设置从而保证每个Node上的POD是平均分布的:
@七禾页话
另外对于Local模式,如果某种原因导致外部流量发给了一个没有响应业务POD的Node,数据就会被丢弃,给大家的感知就是业务不通:
@七禾页话
造成这样的原因比如:
总的来说Cluster和Local两种模式各有千秋,存在即合理:
所以具体怎么使用,要结合集群所使用的相关技术来择优选择。
以上,欢迎留言来一起了解学习ICT的相关知识!