kubernetes Service VIP和kube-prox
先介绍了解几个概念
Pod是集群上一组运行的容器(为何不说是正在运行,因为init容器在执行完配置初始化任务后会自动退出)。
Service:将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
Kubernetes 这样定义Service :逻辑上的一组 Pod,一种可以访问Pod的策略,通常称之为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过selector实现的。当我们调用某个服务时并不关心调用了哪个Pod,对外提供服务一组的 Pod 实际上可能会发生变化(是否能提供服务,或者在销毁中,或者在创建中),而Service 能够解耦这种关联。
Service找到pod:kube-proxy代理
在 Kubernetes 集群中,每个Node运行一个 kube-proxy代理进程。kube-proxy 负责为 Service实现了一种VIP(虚拟 IP)。
各版本kube-proxy支持的代理模式:
Kubernetes v1.0支持userspace代理模式。
Kubernetes v1.1添加了 iptables 模式代理,在Kubernetes v1.2,默认配置为iptables。
Kubernetes v1.8添加了 ipvs 代理模式。
1) userspace 代理模式
userspace代理模式下,kube-proxy会监视Kubernetes master对Service对象和Endpoints对象的添加和移除。 对每一个Service,kube-proxy在它运行的Node节点上打开一个随机选择的端口(称之为代理端口)。Kube-proxy捕获到达该Service的clusterIP(虚拟IP)和Port的请求,基于iptables规则重定向到代理端口。任何连接到“代理端口”的请求,都会被Kube-proxy基于SessionAffinity然后代理到Service内的某个Pod上面。
用户空间userspace模式下的kube-proxy通过一定的策略选择后端Pod,默认的策略是round-robin。
userspace代理模式2) iptables 代理模式
iptables模式下,kube-proxy会监视Kubernetes master对Service对象和Endpoints对象的添加和移除。 对于每一个Service,kube-proxy会安装iptables规则,从而捕获到达该Service的clusterIP和端口的请求,进而将请求重定向到Service的一组backend中的某个上面。 对于每一个Endpoints对象,kube-proxy也会安装iptables规则,这个规则会选择一个backend组合。
kube-proxy在 iptables 模式下采取随机的策略选择一个Pod。
使用iptables处理流量具有较低的系统开销,因为流量由Linux netfilter处理,而无需在用户空间和内核空间之间切换。这种方法也可能更可靠,为何是可能更可靠呢?下面一段来介绍。
如果kube-proxy在iptables模式下运行,并且所选的第一个Pod没有响应,则连接失败。而kube-proxy运行在userspace用户空间模式下,kube-proxy将检测到与第一个Pod的连接已失败,会自动使用其他后端Pod重试。那么怎能解决iptables模式下的这个问题呢?尽可能做的更可靠?
推荐使用Pod readiness探测器来验证Pod是否可以正常工作,以便iptables模式下kube-proxy仅看到运行正常的Pod,这样能避免kube-proxy发送到已知已失败的Pod。
iptables模式3) IPVS 代理模式
在ipvs模式下,Kube-proxy会监视Kubernetes master对Service对象和Endpoints对象的添加和移除。Kube-proxy调用netlink接口相应地创建IPVS规则,并定期将IPVS规则与Kubernetes Service和Endpoints同步。访问服务时,IPVS将请求重定向到后端Pod之一。
IPVS代理模式基于类似于iptables模式的 netfilter挂钩函数,但是使用哈希表作为基础数据结构,并且在内核空间中工作。 与iptables模式下相比,IPVS模式下的kube-proxy重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。与其他代理模式相比,IPVS模式还支持更高的网络流量吞吐量。
IPVS提供了6种选项来平衡后端Pod的流量,包括rr: round-robin轮询,lc: least connection (smallest number of open connections)最小连接,dh: destination hashing目的地址哈希,sh: source hashing源地址哈希,sed: shortest expected delay最小期望延迟,nq: never queue不排队。
注意:
在IPVS模式下运行kube-proxy,必须在启动kube-proxy前使IPVS Linux在节点上可用。
当kube-proxy以IPVS代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到IPVS内核模块,则kube-proxy将退回到以iptables代理模式运行。
IPVS总结
通过某个微服务的cluster ip访问多个后端pod ip,cluster ip指virtual ip虚拟ip。这个虚拟ip和前面介绍的ha高可用虚拟ip不太一样,前面介绍的场景将虚拟ip启动在主机上而备机不提供服务,kubernetes中是将调用虚拟ip的请求通过kube-proxy以某种代理模式重定向到各个pod上
kube-proxy不管在什么代理模式下,都会监控Kubernetes master对Service对象和Endpoints对象的添加和移除。usespace模式下Kube-proxy捕获到该Service的clusterIP(虚拟IP)和Port的请求,基于iptables规则重定向到代理端口,然后Kube-proxy基于SessionAffinity然后代理到Service内的某个Pod上面。iptables代理模式下kube-proxy捕获到该Service的clusterIP和端口的请求,根据iptables规则随机将请求重定向到Service的一组backend中的某个Pod上,对于每一个Endpoints对象,kube-proxy也一样根据iptables规则随机将请求重定向某个pod上。IPVS代理模式下Kube-proxy调用netlink接口相应地创建IPVS规则,并定期将IPVS规则与Kubernetes Service和Endpoints同步。访问服务时,IPVS根据策略将请求重定向到后端Pod之一。但有个人前提条件是IPVS代理模式下必须在启动kube-proxy前使IPVS Linux在节点上可用。
性能方面,iptables代理模式下处理流量具有较低的系统开销,因为流量由Linux netfilter处理,而无需在用户空间和内核空间之间切换。
可靠性方面,usespace代理模式下Kube-proxy重定向到第一个Pod的连接失败,会自动使用其他后端Pod重试。iptables代理模式下,Kube-proxy重定向到第一个Pod没有响应则连接失败,相对userspace代理的可靠性来说比较差,但可以通过Pod readiness探测器来验证Pod是否可以正常工作,以便Kube-proxy仅看到运行正常的Pod。
参考资料
https://kubernetes.io/zh/docs/concepts/services-networking/service/