当我们创建完 Pod 后,Pod 的 IP 与 Service IP 会自动分配,而 Pod IP 仅 K8s 集群内部访问,那 K8s 集群外部客户端又是如何访问 Pod 呢?看了官方相关文档,查询到是通过 Host 的 iptables
(即 K8s 集群节点的 iptables)来实现的,当然其负载均衡策略也是通过 iptables
来实现的。
在上图中,有个 Cluster IP 的字段,该 Cluster IP 是一个虚拟 IP,由 K8s 集群节点的 iptables 规则管理,查看当前节点的 iptables,并过滤与 Cluster IP 相关的规则。
iptables-save |grep '10.99.153.224'
下图中,我起了 2 个 Pod 副本和一个 Service 资源:
上图中两条 iptables 规则含义为:
- 第一条规则:当其他源地址访问 Service IP(nginx-srv)时,会跳转到
KUBE-SVC-QEOPNOJG5FJIEAZE
规则; - 第二条规则:当 Service IP(nginx-srv)收到来自集群 Pod IP(Pod)的请求时,则允许源 Pod IP 的请求。
那 K8s 集群外部是如何实现访问 Pod 的呢?我们继续看上图中第一条规则跳转后的 KUBE-SVC-QEOPNOJG5FJIEAZE
规则。
看红框部分:KUBE-SVC-QEOPNOJG5FJIEAZE
分别有两次 50% 的机会转发到下一条规则
-
第一条规则:其后的
--probability 0.50000000000
表示外部请求时,有 50% 的概率跳转到规则KUBE-SEP-JASFIS5KUS7Z3IZQ
-
第二条规则:其后没有
--probability 0.50000000000
,是因为我就起了 2 个 Pod,也就表示外部请求时,也有 50% 的概率跳转到规则KUBE-SEP-7BD4EFXYOH3EVXAM
继续看这两条规则的具体功能实现:
上面的这两条规则就分别对应 K8s 中的两个 Pod 资源,也就是 Host 将集群外部的请求分别转发到后端 2 个 Pod。从 iptables 规则转发的概率来看,iptables 将 K8s 集群外部的请求转发到后端 Pod,且使用了轮询的策略(即负载均衡策略)。之所以外部客户端都可以通过 K8s 集群任意一节点来请求/访问 K8s Pod 资源,是因为在整个 K8s 集群中的每个节点都配置了相同的 iptables 规则,因此每个节点都具备负载均衡的效果。