Kubernetes 之 kube-proxy

124 阅读5分钟

kube-proxy 简介

由于Kubernetes中的Pods是临时的,可随时被终止或重启。由于这种行为,我们不能依赖于它们的IP地址,因为它们总是在变。而ServicesPods提供一个稳定的IP地址,用于连接Pods。每个Service与一组Pods相关联。当流量到达Service时,根据规则将其重定向到相应的后端Pods,而这个规则的实现就是kube-proxy

Kube-Proxy是安装在 每个节点 中的Kubernetes代理。它监视与Service对象及其端点相关的更改。然后将这些更改转换为节点内的实际网络规则。Kube-Proxy通常以 DaemonSet 的形式在集群中运行。

工作原理

kube-proxy 监听 API server 中资源对象的变化情况,包括以下三种:

  • service
  • endpoint/endpointslices
  • node

然后根据监听资源变化操作代理后端来为服务配置负载均衡。 image.png

代理模式

目前 Kube-proxy 支持4种代理模式:

  • userspace
  • iptables
  • ipvs
  • kernelspace

userspace mode(丢弃)

客户端访问ServiceIP(clusterIP)请求会先从用户空间到内核中的iptables,然后回到用户空间kube-proxy,kube-proxy负责代理工作。

缺点:userspace最大的问题是:service的请求会先从用户空间进入内核iptables,然后再回到用户空间,由kube-proxy完成后端Endpoints的选择和代理工作,这样流量从用户空间进出内核带来的性能损耗是不可接受的。这也是k8s v1.0及之前版本中对kube-proxy质疑最大的一点,因此社区就开始研究iptables mode。

工作流程:kube-proxy 持续监听 Service 以及 Endpoints 对象的变化;对每个 Service,它都为其在本地节点开放一个端口,作为其服务代理端口;发往该端口的请求会采用一定的策略转发给与该服务对应的后端 Pod 实体。kube-proxy 同时会在本地节点设置 iptables 规则,配置一个 Virtual IP,把发往 Virtual IP 的请求重定向到与该 Virtual IP 对应的服务代理端口上。其工作流程大体如下: 分析:该模式请求在到达 iptables 进行处理时就会进入内核,而 kube-proxy 监听则是在用户态, 请求就形成了从用户态到内核态再返回到用户态的传递过程, 一定程度降低了服务性能。

iptables模式(默认模式)

该模式完全利用内核iptables来实现service的代理和LB, 这是K8s在v1.2及之后版本默认模式。

缺点:iptables mode因为使用iptable NAT来完成转发,也存在不可忽视的性能损耗。另外,如果集群中存在上万的Service/Endpoint,那么Node上的iptables rules将会非常庞大,性能还会再打折扣。这也导致目前大部分企业用k8s上生产时,都不会直接用kube-proxy作为服务代理,而是通过自己开发或者通过Ingress Controller来集成HAProxy, Nginx来代替kube-proxy。

详细工作流程:iptables 模式与 userspace 相同,kube-proxy 持续监听 Service 以及 Endpoints 对象的变化;但它并不在本地节点开启反向代理服务,而是把反向代理全部交给 iptables 来实现;即 iptables 直接将对 VIP 的请求转发给后端 Pod,通过 iptables 设置转发策略。其工作流程大体如下: 分析:该模式相比 userspace 模式,克服了请求在用户态-内核态反复传递的问题,性能上有所提升,但使用 iptables NAT 来完成转发,存在不可忽视的性能损耗,而且在大规模场景下,iptables 规则的条目会十分巨大,性能上还要再打折扣。

ipvs模型

在kubernetes 1.8以上的版本中,对于kube-proxy组件增加了除iptables模式和用户模式之外还支持ipvs模式。kube-proxy ipvs 是基于 NAT 实现的,通过ipvs的NAT模式,对访问k8s service的请求进行虚IP到POD IP的转发。当创建一个 service 后,kubernetes 会在每个节点上创建一个网卡,同时帮你将 Service IP(VIP) 绑定上,此时相当于每个 Node 都是一个 ds,而其他任何 Node 上的 Pod,甚至是宿主机服务(比如 kube-apiserver 的 6443)都可能成为 rs。

详细工作流程:与iptables、userspace 模式一样,kube-proxy 依然监听Service以及Endpoints对象的变化, 不过它并不创建反向代理, 也不创建大量的 iptables 规则, 而是通过netlink 创建ipvs规则,并使用k8s Service与Endpoints信息,对所在节点的ipvs规则进行定期同步; netlink 与 iptables 底层都是基于 netfilter 钩子,但是 netlink 由于采用了 hash table 而且直接工作在内核态,在性能上比 iptables 更优。

分析:ipvs 是目前 kube-proxy 所支持的最新代理模式,相比使用 iptables,使用 ipvs 具有更高的性能。

Kernelspace模型

Kernelspace模式是kube-proxy的另一种实现方案,通过在内核空间中实现路由转发规则。这种模式的优点是可以利用操作系统的网络栈和内核优化来提高性能和效率。但是由于需要在内核空间中实现路由转发规则,因此需要具备一定的系统内核编程能力。