kube-proxy iptables模式原理分析

在kubernetes集群内,访问一个pod应用可以通过pod IP,但是pod删除重建后IP会发生变化,而且在高可用多副本场景下直接通过IP访问,则会有客户端需要实现负载均衡等问题。为了解决上述问题,kubernetes在客户端和pod间引入了一个抽象层:service。

service通过labelSelector与pod关联,客户端通过service访问pod。访问类型可以分为两类:

  • 通过service VIP访问:通过访问service clusterIP代理到后端pod。
  • 通过service域名访问:在kubernetes集群内创建一个service对象后,kubernetes会生成一条 {serviceName}.{namespace}.svc.cluster.localDNS记录,客户端通过该DNS记录最终访问pod。

通过service域名访问时,根据service的配置又可以分为两类:

  • normal service:客户端向集群内的DNS服务(如coreDNS)解析service域名后得到的是service的VIP,之后流程和上述通过service VIP访问一样。
  • headless service:所谓headless service是指service对象spec.clusterIP=None的service。解析headless service域名时,得到的不再是service VIP,而是某一个后端pod的IP。这种类型的service主要是用来返回一系列ip地址

kube-proxy

当在kubernetes集群中创建一个service对象后,controller-manager组件会自动创建一个和service名称相同的endpoints对象。endpoints对象中的IP就是该service通过labelSelector关联的且已就绪pod IP,controller-manager里的endpoints controller会监听pod的状态,实时维护endpoints对象中的数据。

新版本kubernetes(v1.21+)中,controller-manager组件除了会创建endpoints对象,一般还会创建两个endpointsSlice对象,这两个endpointsSlice对象一个负责ipv4,一个负责ipv6,名称是service名称加上一个后缀。
endpointsSlice会记录service关联的所有pod IP,即使这个pod非ready状态。

kube-proxy在kubernetes集群中以daemonSet形式启动,也就每个节点上都会启动一个kube-proxy服务的pod。kube-proxy的pod通过监听集群中service和endpoints资源的变化,刷新节点上的iptables/ipvs规则,从而实现访问service VIP代理到后端pod的功能。

三种模式
kube-proxy先后出现了三种模式:userspace、iptables、ipvs,其中userspace模式是通过用户态程序实现转发,因性能问题基本被弃用,当前主流的模式是iptables和ipvs。kube-proxy默认配置是iptables模式,可以通过修改kube-system命名空间下名称为kube-proxy的configMap资源的mode字段来选择kube-proxy的模式。
本文只介绍kube-proxy iptables模式实现的普通clusterIP类型的service原理,其它类型的service原理大家可以参考本文和其它资料自行分析。如无特殊场景,下文不再对kube-proxy模式和service类型做特别说明。


 

你可能感兴趣的:(K8S,kubernetes)