现状概述
为了将运行在 Kubernetes 集群内部 Pod 上的应用程序投入使用,需要启用 K8S 集群上的服务(Service):NodePort 或 ClusterIP,然后再经过外部 LoadBalancer 或 Ingress 功能,将服务发布为可被集群外部客户端访问的 IP 地址或者 FQDN(如:web.example.com )。
NodePort 是在 Kubernetes 集群上提供的一种简便的服务发布方式:
01
在每个 Node 上公开一个 Port(即使 Pod 不在该 Node上),对应到实际 Pod 的服务端口,客户端需要访问应用时,流量被发送到特定的NodeIP:Port;
02
对 Node IP:Port 的访问流量,由运行在每个节点上的 kube-proxy 负责 Pod 之间重新分配流量。
虽然,NodePort 类型的服务是创建用于外部连接的(和任何应用程序容器)的快捷解决方案,不需要额外规划 IP 地址空间,但它具有以下缺点:
01
如果配置允许由 Kube-Proxy 在集群范围内进行外部流量的负载均衡( externalTrafficPolicy=Cluster ),那么目标 Pod 有可能不在第一跳 Node 上,需要进行节点间的第二跳路由转发;这种情况下,需要对传入流量执行源地址翻译( SNAT ),外部负载均衡器无法保证会话持久性。
02
如果配置仅允许 Kube-Proxy 在节点内部进行负载均衡( externalTrafficPolicy=Local),那么由外部负载均衡器传入到节点上的流量,将仅限于被发送到运行在本节点上的 Pod ;这种情况下,Pod 在节点上的实际分布情况可能会导致不均衡的负载分担。如下图:外部负载均衡器只将2个后端节点作为服务池成员,所有进入的访问请求按照50:50比例分配给这2个节点;但 Node -1上有2个 Pod 分担这50%的任务,而 Node -2 上仅有1个 Pod 承担50%的任务量。
03
出于简单配置和使用的目的,在每个 Node 上对外曝露相同的 Port,即便是该节点上并没有运行 Pod 实例。如在上图中增加一个空载的“ Node - 3 ”,外部负载均衡器发送给 Node-3 的流量将由 Kube-Proxy 转发给 Node-1 或 Node-2 ,增加了转发步骤;而且,外部负载均衡器无法通过健康检查的方式发现, Node -3 上并没有运行应用 Pod 实例。
04
出于简单配置和使用的目的,在每个 Node 上对外曝露相同的 Port ,但存在给定 Port 在某个 Node 上已被占用的可能性,此时就需要在所有节点上寻找并使用下一个可用的端口号。随着(采用 NodePort 类型的)服务数量的不断增加,最终将很快达到 Port 范围限制。
NodePortLocal 解决方案
VMware 提出了一种解决方案,使用 CNI Antrea 和NSX 高级负载均衡(以下简称 NSX-ALB)相结合,实现称为“ NodePortLocal ”( NPL )的技术方案来解决上述问题。NodePortLocal 提供了一种在 Kubernetes 集群的每个节点上、为每个 Pod 提供专属“ NodeIP:Port ”映射来曝露后端服务的方法。
注:
· Antrea 项目是一个 VMware 贡献的开源 Kubernetes CNI 网络插件解决方案,基于 Open vSwitch(OVS), 旨在提供 Kubernetes 原生的、高效、安全、跨平台的 CNI 和 NetworkPolicy 。2021年5月6日,经过云原生计算基金会( CNCF )技术监督委员会( TOC )投票通过, VMware 开源项目 Antrea 正式成为沙箱级项目( Sandbox Level Project )。
· NSX-ALB AKO 是一个Kubernetes 环境中的 Operator,用作 LoadBalancer 和 Ingress Controller,它作为集群中的 pod 运行,并通过 NSX-ALB 控制器将所需的 Kubernetes 服务转换为 NSX-ALB 配置,在NSX-ALB的转发服务引擎 (SE) 上自动实现 Ingresses/Routes/Services。
· Antrea 和 AKO 在原生 Kubernetes、VMware Tanzu 和 Openshift Container Platform 环境中均可以使用。
配置步骤
为了完成此任务,需要以下步骤完成 NPL 的配置。
(略过 Antrea 和 AKO 的基本安装、配置和使用方法的介绍)
1. 在 K8S 环境中进入 Antrea ConfigMap 编辑模式:
kubectl edit -n kube-system cm antrea-config-xxxxxxxxxx
2. 启用 NodePortLocal:
3.(可选)设定用于 NPL 映射的端口范围,避免与仍在使用的 NodePort 服务冲突;
4. 保存 Antrea ConfigMap 配置,重新启动 Antrea 代理 Pod;
5. 在 NSX-ALB AKO 的 yaml 配置文件中,设定启用 NPL 服务类型:
6. 保存 AKO 配置并更新到 AKO Pod。
采用 NPL 进行 L4 服务发布
1.在Kubernetes集群中创建Deployment(image=httpd)。本例在具有3个工作节点的集群上部署了4个Pod:
2. 通过 ServiceType=LoadBalancer 参数,将此应用曝露出去( Antrea 代理在后台监听这一服务的创建,按照 NodePortLocal 的模式工作):
3. NSX-ALB 的 AKO 感知到集群上的服务变化,并生成对应的负载均衡配置,在 NSX-ALB 控制器的管理界面上,可以看到 AKO 已经将上述服务发布出去(下图)。
NPL 有以下特点:
a. 将每个 Pod 对外曝露为一个专属的 NodeIP:Port 组合方式。本例中,worker-node-23(192.168.30.23)节点上部署了2个 Pod ,因此将它们分别映射为192.168.30.23:40000和192.168.30.23:40001。NodePortLocal 可以在不同节点上使用不同的 Port 曝露同一应用(而 NodePort 要求在所有节点上为同一应用绑定同样的 Port ,即便这个节点上没有运行该应用的 Pod)。对比之下,NodePortLocal 更加灵活地使用每个节点上的可用 Port,降低了端口资源消耗。
b. NSX-ALB 作为 Kubernetes 的外部负载均衡器,将4个 NodeIP:Port 作为后端服务池,进行负载均衡决策和转发,避免了多个 Pod 上的任务量不均衡。
c. 不需要像 ClusterIP 方式那样单独设置服务地址范围,不需要针对 ClusterIP 或 Pod IP 的静态路由——所有流量指向每个 NodeIP:Port,NSX-ALB 只需按照节点地址进行一跳路由,集群内不对此流量进行东西向转发。
d. NPL 在每个节点上编写了 iptable DNAT (目的地址翻译)规则来完成 NodeIP:Port<->PodIP:Port 的映射和转换,外部负载均衡器只感知并使用 NodeIP:Port,因此,可以在多个 K8S 集群上支持重叠的 Pod 网络地址段。
e. NSX-ALB 作为外部负载均衡器,对进入集群的流量只进行目的地址翻译( DNAT),不进行源地址翻译(SNAT),应用程序 Pod 看到的是原始客户端 IP,因实现会话持久性是可能的。
f. NSX-ALB 负载均衡器可以通过 NodeIP:Port 直达每个 Pod上 的应用端口,可以直接监控每个应用的健康状况,并可以据此做出负载均衡决策。
采用 NPL 辅助 L7 应用发布
在 Kubernetes 集群上使用 Ingress 进行 L7 应用发布时,应先创建 L4 服务(比如, NodePort ),再通过 Ingress Controller 识别 L4 服务,并按照管理员配置的策略,创建 L7 Ingress ,实现对应用的 L7 路由(比如,依据 URI 规则选择后端服务器)。
VMware NSX-ALB 应用交付方案可以与 CNI Antrea 中的 NodePortLocal 功能配合使用,将 NodePortLocal 创建的 L4 服务通过 Ingress 发布出去。
配置步骤要点如下:
1.在Kubernetes集群中创建Deployment(image=httpd)。本例在具有3个节点的集群上部署了4个httpd Pod:
2. 通过 ServiceType=ClusterIP 参数,将此应用曝露出去,服务名称为“svc-lb-httpd”(Antrea 代理在后台监听这一服务的创建,按照 NodePortLocal 的模式工作):
3. NSX-ALB 在集群上安装 AKO Pod,作为 Ingress Controller,默认采用“avi-lb”作为 ingressClassName,为服务“svc-lb-httpd”创建 Ingress,使用 yaml 文件示例如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: httpd-ingress
spec:
ingressClassName: avi-lb
rules:
- host: httpd.tanzu.corp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: svc-lb-httpd
port:
number: 80
4. 在 NSX 应用交付控制器上,可以看到为上述应用创建了 L7 虚拟服务,后端服务器池中 NodeIP:Port 映射方式表明,这采用的是 NodePortLocal 模式。
总结
“ NodePortLocal”( NPL )是 CNI 项目 Antrea 中提出的,可以提高在节点上通过端口映射的方式对外发布应用的效率,简化云原生应用投入生成过程的配置步骤。NPL 与 NSX AKO 相结合,将 NSX 应用交付平台上作为 Kubernetes 集群的外部负载均衡器 /Ingress Controller,这种“一步到位”的 做法是 VMware 对云原生应用的最新贡献。
文章转载自云原生网络Antrea。点击这里阅读原文了解更多。