Kubernetes service 只是把应用对外提供服务的方式做了抽象,真正的应用跑在 Pod 中的 container 里,我们的哀求转到 kubernetes nodes 对应的 nodePort 上,那么 nodePort 上的哀求是怎样进一步转到提供后台服务的 Pod 的呢? 就是通过 kube-proxy 实现的
kube-proxy 部署在 k8s 的每一个 Node 节点上,是 Kubernetes 的核心组件,我们创建一个 service 的时候,kube-proxy 会在 iptables 中追加一些规则,为我们实现路由与负载均衡的功能。在 k8s1.8 之前,kube-proxy 默认使用的是 iptables 模式,通过各个 node 节点上的 iptables 规则来实现 service 的负载均衡,但是随着 service 数量的增大,iptables 模式由于线性查找匹配、全量更新等特点,其性能 会显著降落。从 k8s 的 1.8 版本开始,kube-proxy 引入了 IPVS 模式,IPVS 模式与 iptables 同样基于 Netfilter,但是接纳的 hash 表,因此当 service 数量到达肯定规模时,hash 查表的速度优势就会显现出来,从而提高 service 的服务性能。
kubectl get pods -n kube-system -o wide
复制代码
service 是一组 pod 的服务抽象,相称于一组 pod 的 LB,负责将哀求分发给对应的 pod。service 会为这个 LB 提供一个 IP,一般称为 cluster IP。kube-proxy 的作用重要是负责 service 的实现,详细来说,就是实现了内部从 pod 到 service 和外部的从 node port 向 service 的访问。
1、kube-proxy 其实就是管理 service 的访问入口,包罗集群内 Pod 到 Service 的访问和集群外访问 service。
2、kube-proxy 管理 sevice 的 Endpoints,该 service 对外暴露一个 Virtual IP,也可以称为是 Cluster IP, 集群内通过访问这个 Cluster IPort 就能访问到集群内对应的 serivce 下的 Pod。
kube-proxy 三种工作模式
1、Userspace 方式:
Client Pod 要访问 Server Pod 时,它先将哀求发给内核空间中的 service iptables 规则,由它再将哀求转给监听在指定套接字上的 kube-proxy 的端口,kube-proxy 处理完哀求,并分发哀求到指定Server Pod 后,再将哀求转发给内核空间中的 service ip,由 service iptables 将哀求转给各个节点中 的 Server Pod。
这个模式有很大的问题,客户端哀求先辈入内核空间的,又进去用户空间访问 kube-proxy,由 kube-proxy 封装完成后再进去内核空间的 iptables,再根据 iptables 的规则分发给各节点的用户空间的 pod。由于其需要来回在用户空间和内核空间交互通信,因此效率很差。在 Kubernetes 1.1 版本之前,userspace 是默认的代理模子。
2、iptables 方式:
客户端 IP 哀求时,直接哀求本地内核 service ip,根据 iptables 的规则直接将哀求转发到到各 pod 上,因为使用 iptable NAT 来完成转发,也存在不可忽视的性能消耗。另外,如果集群中存上万的 Service/Endpoint,那么 Node 上的 iptables rules 将会非常庞大,性能还会再打折 iptables 代理模式由 Kubernetes 1.1 版本引入,自 1.2 版本开始成为默认类型。
3、ipvs 方式: