我们前面介绍过在Kubernetes中的一个重要组件Service,它的作用为Pod提供一个入口,我们在集群中只要访问servie的IP+Port就可以代理到后端的Pod,在它们之前的请求转发离不开每个Node节点上的kube-proxy组件。
kube-proxy的模式有以下三种:
- Userspace
- iptables
- ipvs
kube-proxy的主要作用是:
- 监听kube-api,获取Service相关的所有信息;
- 修改所有node上的转发规则,维护路由信息;
- 将请求转发到对应的Pod上;
一、Userspace
其工作流程为:请求到达Service IP的内核空间,然后回到当前组件的用户空间kube-proxy,然后生成相应的规则再到内核空间,再由iptables规则代理到请求的Pod。
在这整个过程中,kube-proxy起到代理的作用,整个调度都要经过它。
二、iptables
其工作流程为:请求到达内核空间service IP,直接由其iptables规则转发到相应Pod。
相比于userspace,iptables模式全工作在内核态,不用经过用户态kube-proxy中转。
三、ipvs
与iptables相比,IPVS拥有以下明显优势:
◎ 为大型集群提供了更好的可扩展性和性能;
◎ 支持比iptables更复杂的复制均衡算法(最小负载、最少连接、加权等);
◎ 支持服务器健康检查和连接重试等功能;
◎ 可以动态修改ipset的集合,即使iptables的规则正在使用这个集合。
由于IPVS无法提供包过滤、airpin-masquerade tricks(地址伪装)、SNAT等功能,因此在某些场景(如NodePort的实现)下还要与iptables搭配使用。在IPVS模式下,kube-proxy又做了重要的升级,即使用iptables的扩展ipset,而不是直接调用iptables来生成规则链。
其工作流程:请求到达内核空间Service IP,然后由ipvs规则转发到相应的Pod。
四、包转发路径
从网络的角度看kube-proxy的包转发路径:
步骤:
- 网卡收到一个包(通过 DMA 放到 ring-buffer)。
- 包经过 XDP hook 点。
- 内核给包分配内存,此时才有了大家熟悉的 skb(包的内核结构体表示),然后 送到内核协议栈。
- 包经过 GRO 处理,对分片包进行重组。
- 包进入 tc(traffic control)的 ingress hook。接下来,所有橙色的框都是 Netfilter 处理点。
- Netfilter:在 PREROUTING hook 点处理 raw table 里的 iptables 规则。
- 包经过内核的连接跟踪(conntrack)模块。
- Netfilter:在 PREROUTING hook 点处理 mangle table 的 iptables 规则。
- Netfilter:在 PREROUTING hook 点处理 nat table 的 iptables 规则。
- 进行路由判断(FIB:Forwarding Information Base,路由条目的内核表示,译者注) 。接下来又是四个 Netfilter 处理点。
- Netfilter:在 FORWARD hook 点处理 mangle table 里的iptables 规则。
- Netfilter:在 FORWARD hook 点处理 filter table 里的iptables 规则。
- Netfilter:在 POSTROUTING hook 点处理 mangle table 里的iptables 规则。
- Netfilter:在 POSTROUTING hook 点处理 nat table 里的iptables 规则。
- 包到达 TC egress hook 点,会进行出方向(egress)的判断,例如判断这个包是到本 地设备,还是到主机外。
- 对大包进行分片。根据 step 15 判断的结果,这个包接下来可能会:发送到一个本机 veth 设备,或者一个本机 service endpoint, 或者,如果目的 IP 是主机外,就通过网卡发出去。