032.核心组件-kube-proxy
程序员文章站
2022-03-01 18:27:44
一kube-proxy原理 1.1kube-proxy概述 Kubernetes为了支持集群的水平扩展、高可用性,抽象出了Service的概念。Service是对一组Pod的抽象,它会根据访问策略(如负载均衡策略)来访问这组Pod。Kubernetes在创建Service时会为Service分配 ......
一 kube-proxy原理
1.1 kube-proxy概述
kubernetes为了支持集群的水平扩展、高可用性,抽象出了service的概念。service是对一组pod的抽象,它会根据访问策略(如负载均衡策略)来访问这组pod。kubernetes在创建service时会为service分配一个虚拟的ip地址,客户端通过访问这个虚拟的ip地址来访问服务,service则负责将请求转发到后端的pod上。
service作用类似反向代理,但与普通的反向代理有一些不同:首先,它的ip地址是虚拟的,默认情况无法从外面访问;其次,它的部署和启停是由kubernetes统一自动管理的。
然而,service是一个抽象概念,而真正提供service功能的是kube-proxy服务进程。在kubernetes集群的每个node上都会运行一个kube-proxy服务进程,可以简单理解此进程是service的透明代理兼负载均衡器,其核心功能是将到某个service的访问请求转发到后端的多个pod实例上。
此外,service的clusterip与nodeport等概念是kube-proxy服务通过iptables的nat转换实现的,kube-proxy在运行过程中动态创建与service相关的iptables规则,这些规则实现了将访问服务(clusterip或nodeport)的请求负载分发到后端pod的功能。
由于iptables机制针对的是本地的kube-proxy端口,所以在每个node上都要运行kube-proxy组件。这样一来,在kubernetes集群内部,才可以在任意node上发起对service的访问请求。
综上所述,由于kube-proxy的作用,在service的调用过程中客户端无须关心后端有几个pod,中间过程的通信、负载均衡及故障恢复都是透明的。
二 kube-proxy模式
2.1 userspace模式
起初,kube-proxy进程是一个真实的tcp/udp代理,类似haproxy,负责从service到pod的访问流量的转发,这种模式被称为userspace(用户空间代理)模式。
如图所示,当某个pod以clusterip方式访问某个service的时候,这个流量会被pod所在本机的iptables转发到本机的kube-proxy进程,然后由kube-proxy建立起到后端pod的tcp/udp连接,随后将请求转发到某个后端pod上,并在这个过程中实现负载均衡功能。
clusterip与nodeport的实现原理,以及kube-proxy与apiserver的交互过程,如下图所示:
提示:如上为旧版kube-proxy与apiserver的交互过程。
2.2 iptables模式
如图所示,kubernetes从1.2版本开始,将iptables作为kube-proxy的默认模式。iptables模式下的kube-proxy不再起到proxy的作用,其核心功能:通过api server的watch接口实时跟踪service与endpoint的变更信息,并更新对应的iptables规则,client的请求流量则通过iptables的nat机制“直接路由”到目标pod。
根据kubernetes的网络模型,一个node上的pod与其他node上的pod应该能够直接建立双向的tcp/ip通信通道,所以如果直接修改iptables规则,则也可以实现kube-proxy的功能,只不过后者更加高端,因为是全自动模式的。
与第1代的userspace模式相比,iptables模式完全工作在内核态,不用再经过用户态的kube-proxy中转,因而性能更强。
iptables模式虽然实现起来简单,但存在无法避免的缺陷:在集群中的service和pod大量增加以后,iptables中的规则会急速膨胀,导致性能显著下降,在某些极端情况下甚至会出现规则丢失的情况,并且这种故障难以重现与排查,于是kubernetes从1.8版本开始引入第3代的ipvs(ipvirtualserver)模式。
kube-proxy针对service和pod创建的一些主要的iptables规则如下。
- kube-cluster-ip:在masquerade-all=true或clustercidr指定的情况下对serviceclusterip地址进行伪装,以解决数据包欺骗问题。
- kube-external-ip:将数据包伪装成service的外部ip地址。
- kube-load-balancer、kube-load-balancerlocal:伪装loadbalancer类型的service流量。
- kube-node-port-tcp、kube-node-port-localtcp、kube-node-portudp、kube-node-port-local-udp:伪装nodeport类型的service流量。
2.3 ipvs模式
如图所示。ipvs在kubernetes1.11中升级为ga稳定版。iptables与ipvs虽然都是基于netfilter实现的,但因为定位不同,二者有着本质的差别:iptables是为防火墙而设计的;ipvs则专门用于高性能负载均衡,并使用更高效的数据结构(hash表),允许几乎无限的规模扩张,因此被kube-proxy采纳为第三代模式。
与iptables相比,ipvs拥有以下明显优势:
- 为大型集群提供了更好的可扩展性和性能;
- 支持比iptables更复杂的复制均衡算法(最小负载、最少连接、加权等);
- 支持服务器健康检查和连接重试等功能;
- 可以动态修改ipset的集合,即使iptables的规则正在使用这个集合。
由于ipvs无法提供包过滤、airpin-masqueradetricks(地址伪装)、snat等功能,因此在某些场景(如nodeport的实现)下还要与iptables搭配使用。
在ipvs模式下,kube-proxy又做了重要的升级,即使用iptables的扩展ipset,而不是直接调用iptables来生成规则链。iptables规则链是一个线性的数据结构,ipset则引入了带索引的数据结构,因此当规则很多时,也可以很高效地查找和匹配。
可以将ipset简单理解为一个ip(段)的集合,这个集合的内容可以是ip地址、ip网段、端口等,iptables可以直接添加规则对这个“可变的集合”进行操作,这样做的好处在于可以大大减少iptables规则的数量,从而减少性能损耗。假设要禁止上万个ip访问我们的服务器,则用iptables的话,就需要一条一条地添加规则,会在iptables中生成大量的规则;但是用ipset的话,只需将相关的ip地址(网段)加入ipset集合中即可,这样只需设置少量的iptables规则即可实现目标。
上一篇: 030.核心组件-Scheduler