Kubernetes之kube-proxy运行机制分析
一、基础知识
1.Kubernetes再创建服务时会为服务分配一个虚拟IP地址,客户端通过这个虚拟Ip地址来访问服务,而服务则负责将请求转发到后端pod上。
2.上述阐述的过程为一个反向代理的过程,但是这个反向代理和普通的反向代理的区别是它的IP地址是虚拟的而且它的部署和启动以及停止是由K8s统一自动管理。
3.在K8s集群里每个Node上都会运行一个kube-proxy服务进程,这个进程可以看作service的透明代理兼负载均衡器,主要作用就是把service的访问请求转发到后端的多个Pod实例上。
4.对于每一个TCP类型的Kuberbetes Service, kube-proxy都会在本地node上建立一个SocketServer来负责接收请求,然后均匀发送到后端某个pod的端口上,这个过程采用Round Robin负载均衡算法。
5.kube-proxy的负载均衡器只支持RoundRobin算法,另外在此算法的基础上也支持Session保持,如果service在定义中指定了session保持,则kube-proxy接收请求时会从本地查找是否存在来自该请求ip的affinityState对象,如果不存在,则会按照RR算法为该请求挑选一个Endpoint,并创建一个affinityState对象,记录请求的IP和指向的Endpoint,后面的请求就会粘连到这个创建好的affinityState对象上
二、kube-proxy实现细节
1.kube-proxy通过查询和监听API Server中service与Endpoints的变化,为每个Service都创建一个服务代理对象并自同步。其中服务代理对象是kube-proxy中的一种数据结构,它包括用于监听此服务请求的SocketServer(随机选择本地的一个空闲端口),另外它也在内部创建了一个LoadBalancer(保存了Service到对应的后端Endpoint列表的动态转发路由表)
2.kube-proxy针对iptables的操作(在iptables的NAT表中添加4条规则):
KUBE-PORTALS-CONTAINER:从容器中通过cluster IP和端口号访问Service的请求
KUBE-PORTALS-HOST:从主机中通过cluster ip和端口号访问service的请求
KUBE-NODEPORT-CONTAINER:从容器中通过service的NodePort端口号访问service的请求
KUBE-NODEPORT-HOST:从主机中通过Service的Nodeport端口号访问service的请求
此外,kube-proxy在iptables中为每个Service创建了由Cluster IP+Service端口到kube-proxy所在主机+service的代理服务所监听的端口的转发规则