本质上来讲,一个 Service
对象对应于工作节点内核之中的一组 iptables 或 ipvs 规则,这些规则能够将到达 Service
对象的 ClusterIP 的流量调度转发至相应 Endpoint
对象指向的 IP 地址和端口之上。内核中的 iptables 或 ipvs 规则的作用域仅为其所在工作节点的一个主机,因而生效于集群范围内的 Service
对象就需要在每个工作节点上都生成相关规则,从而确保任一节点上发往该 Service
对象请求的流量都能被正确转发。
每个工作节点的 kube-proxy 组件通过 APIServer 持续监控着各 Service
及其关联的 Pod
对象,并将 Service
对象的创建或变动实时反映至当前工作节点上相应的 iptables 或 ipvs 规则上。客户端、Service
及 Pod
对象的关系如图所示。
Nefilter 是 Linux 内核中用于管理网络报文的框架,它具有网络地址转换(NAT)、报文改动和报文过滤等防火墙功能,用户可借助用户空间的 iptables
等工具按需自由定制规则使用其各项功能。ipvs 是借助于 Netfilter 实现的网络请求报文调度框架,支持 rr、wrr、lc、wIc、sh、sed 和 nq 等 10 余种调度算法,用户空间的命令行工具是 ipvsadm
,用于管理工作于 ipvs 之上的调度规则。
Service
对象的 ClusterIP 事实上是用于生成 iptables 或 ipvs 规则时使用的 IP 地址,它仅用于实现 Kubernetes 集群网络内部通信,且仅能够以规则中定义的转发服务的请求作为目标地址予以响应,这也是它之所以被称作虚拟 IP 的原因之一。kube-proxy 把请求代理至相应端点的方式有 3 种:userspace、iptables 和 ipvs。
userspace 代理模型
此处的 userspace 是指 Linux 操作系统的用户空间。在这种模型中,kube-proxy 负责跟踪 API Server 上 Service
和 Endpoints
对象的变动(创建或移除),并据此调整 Service
资源的定义。对于每个 Service
对象,它会随机打开一个本地端口(运行于用户空间的 kube-proxy 进程负责监听),任何到达此代理端口的连接请求都将被代理至当前 Service
资源后端的各 Pod
对象,至于哪个 Pod
对象会被选中则取决于当前 Service 资源的调度方式,默认调度算法是轮询(round-robin)。userspace 代理模型工作逻辑如图所示。
另外,此类 Service
对象还会创建 iptables 规则以捕获任何到达 ClusterlP 和端口的流量。在 Kubernetes 1.1 版本之前,userspace 是默认的代理模型。
在这种代理模型中,请求流量到达内核空间后经由套接字送往用户空间中的 kube-proxy 进程,而后由该进程送回内核空间,发往调度分配的目标后端 Pod 对象。因请求报文在内核空间和用户空间来回转发,所以必然导致模型效率不高。
iptables 代理模型
创建 Service
对象的操作会触发集群中的每个 kube-proxy 并将其转换为定义在所属节点上的 iptables 规则,用于转发工作接口接收到的、与此 Service
资源 ClusterIP 和端口相关的流量。客户端发来请求将直接由相关的 iptables 规则进行目标地址转换(DNAT)后根据算法调度并转发至集群内的 Pod
对象之上,而无须再经由 kube-proxy 进程进行处理,因而称为 iptables
代理模型,如图所示。
对于每个 Endpoints
对象,Service
资源会为其创建 iptables 规则并指向其 iptables 地址和端口,而流量转发到多个 Endpoint 对象之上的默认调度机制是随机算法。iptables 代理模型由 Kubernetes v1.1 版本引入,并于 v1.2 版本成为默认的类型。
在 iptables 代理模型中,Service
的服务发现和负载均衡功能都使用 iptables 规则实现,而无须将流量在用户空间和内核空间来回切
换,因此更为高效和可靠,但是性能一般,而且受规模影响较大,仅适用于少量 Service
规模的集群。
ipvs 代理模型
Kubernetes 自 v1.9 版本起引入 ipvs 代理模型,且自 v1.11 版本起成为默认设置。在此种模型中,kube-proxy 跟踪 API Server 上 Service
和 Endpoints
对象的变动,并据此来调用 netlink 接口创建或变更 ipvs(NAT)规则,如图所示。
它与 iptables 规则的不同之处仅在于客户端请求流量的调度功能由 ipvs 实现,余下的其他功能仍由 iptables 完成。
ipvs 代理模型中 Service
的服务发现和负载均衡功能均基于内核中的 ipvs 规则实现。类似于 iptables,ipvs 也构建于内核中的 nefilter 之上,但它使用 hash 表作为底层数据结构且工作于内核空间,因此具有流量转发速度快、规则同步性能好的特性,适用于存在大量 Service
资源且对性能要求较高的场景。ipvs 代理模型支持 rr、Ic、 dh、 sh、sed 和 nq 等多种调度算法。
评论区