service的概念
在k8s集群中,service是一个抽象概念,它通过一个虚拟的IP映射指定的端口,将代理客户端发来的请求转到后端一组pod中的一个上。这是个神马意思呢?pod中的容器经常在不停地销毁和重建,因此pod的IP会不停的改变,这时候客户端就没法访问到pod了,现在有了service作为客户端和pod的中间层,它在这里抽象出一个虚拟IP,然后集群内部都可以通过这个虚拟IP访问到具体的pod。
其实service在kubernetes版本迭代中,有过几次变更。在kubernetes v1.0 中开始使用userspace proxy mode(用户空间代理态代理模式),kubernetes v1.1增加了iptables代理模式,kubernetes v1.2 默认把iptables当成kube-proxy的代理模式。在kubernetes v1.8 增加了性能更强劲的ipvs proxy mode。
kube-proxy的作用
在k8s中,service的集群IP能够实现数据报文请求的转发,需要在node节点上部署的一个组件kube-proxy,具体来说kube-proxy实现的主要有几点:
- 实时监控API,获取service和pod的信息,来保持pod和虚拟IP的映射关系
- 维护本地Netfilter 、iptables、IPVS等内核组件,实现数据报文的转发规则
- 实现每个node节点上虚拟IP的发布和路由维护
- 构建路由信息,通过转发规则转发报文到虚拟IP对应的pod
kube-proxy的三种模式
在k8s中,kube-proxy有三种模式可以实现虚拟IP、路由信息和报文转发。
Userspace Proxy Mode
在userspace代理模式下,kube-proxy起到一个反向代理的功能,对userspace的报文封装往kernelspace转发,主要是处理路由规则下发,数据包转发和负载均衡,所以kube-proxy会在网络流量和数据报文传输频率较高时频繁地在userspace和kernelspace之间进行上下文切换。
在这个模式下,kube-proxy主要进行这么几步:
- 监控k8s集群的API,获取新建或删除service和pod的指令
- 当获取到新建service的指令后,kube-proxy在node上开放随机端口,然后转发到pod上
- kube-proxy会安装iptables规则,将访问service的虚拟IP和端口的流量拦截并重定向到上面开发的端口
- 当重定向的流量获取到node端口时,kube-proxy作为一个负载均衡器,把流量分发给后端的pod
简单来说就是从虚拟IP转发流量并重定向到node上的随机端口,进行netfiller包过滤,再回到userspace进行负载均衡转发。在这个模式下,kube-proxy会多次进行userspace和kernelspace的切换,因此性能损耗较大。
Iptables Proxy Mode
userspace代理模式由于性能原因,在kubernetes v1.2以后就不再怎么使用了,取而代之的是iptables代理模式。在iptables模式中,kube-proxy不再作为反向代理而在虚拟IP和pod之间进行转发,而是将这个工作交给四层的iptables来做,iptables和netfiller紧密合作在kernelspace里就实现了数据包的转发。
在这个模式下,kube-proxy主要进行这么几步:
- 监控k8s集群的API,获取新建或删除service和pod的指令
- kube-proxy在node上设置iptables规则,当有请求发送到service的虚拟IP上时,会立即被捕获并重定向到此service对应的一个pod上
- kube-proxy会在node上为每一个service对应的pod设置iptables规则
在iptables模式中,kube-proxy把流量转发和负载均衡完全委托给iptables和netfiller来做,因此全部工作都在kernelspace完成了,比userspace模式性能提升很多。
当然这个模式也有缺点。在userspace模式下,负载均衡带有健康检测机制,如果选择的pod没有响应,kube-proxy会重新选择;但在iptables模式下则没有健康检测机制,如果pod无法响应,且没有被k8s集群摘除,就会导致转发到此pod的请求超时。
IPVS proxy mode
IPVS是lvs的一个组件,提供高性能、高可靠的基于四层的负载均衡器,IPVS是IP Virtual Server的简写。IPVS构建在netfiller上,作为Linux内核的一部分,在四层实现了负载均衡。IPVS能直接转发基于service的TCP/UDP到真实机上;还能直接构建一个虚拟IP并通过负载均衡算法,把请求转发到pod上。这里的IPVS的功能就类似kube-proxy在userspace代理模式下做的工作。
而在iptables代理模式中,一个k8s集群会有大量service,也就意味着会有极大量的iptables规则,IPVS在这方面也做了改进,它将网络转发规则用hash tabels来存储而且主要工作在kernelspace,减少了上下文切换影响的性能。
在这个模式下,kube-proxy主要进行这么几步:
- 监控k8s集群的API,获取新建或删除service和pod的指令
- 当有新的service建立,kube-proxy回调网络接口,构建IPVS规则
- kube-proxy会定期同步service和pod的转发规则,确保失效的转发及时更新
- 有请求转发到后端时,IPVS的负载均衡直接将其转发给pod