经典:使用 NLB 配置 DSR 负载均衡 2.0
版本 2.0:NLB 仅可在经典集群中创建,无法在 VPC 集群中创建。 要在 VPC 集群中进行负载均衡,请参阅使用 VPC 负载均衡器公开应用程序。
公开一个端口,并使用第 4 层网络负载均衡器 (NLB) 的可移植 IP 地址来公开容器化应用程序。 有关 V2.0 NLB 的更多信息,请参阅 NLB 2.0 的组件和体系结构。
先决条件
无法将现有版本的 1.0 NLB 升级至 2.0。 您必须创建新的 NLB 2.0。 您可以在一个集群中同时运行 1.0 和 2.0 版本的NLB。 要使用 NLB 2.0,您的集群必须运行 Red Hat OpenShift 版本 4。
创建 NLB 2.0 之前,必须完成以下必备步骤。
-
要允许 NLB 2.0 将请求转发到多个专区中的应用程序 pod,请打开支持案例以请求对 VLAN 进行容量聚集。 此配置设置不会导致任何网络中断。
- 登录到 IBM Cloud 控制台。
- 在菜单栏中,单击支持,单击管理案例选项卡,然后单击创建新案例。
- 在案例字段中,输入以下内容: 主题:网络 - 配置 子主题:经典 - VLAN
- 将以下信息添加到描述中:
Please set up the network to allow capacity aggregation on the public and private VLANs associated with my account. This is related to /docs/openshift?topic=openshift-loadbalancer-v2#ipvs_provision, and is needed so I can configure NLB v2.0 LoadBalancers in my Classic Kubernetes Cluster.。 请注意,如果要允许特定 VLAN 上的容量聚集(例如,仅一个集群的公用 VLAN),那么可以在描述中指定这些 VLAN 标识。 - 单击提交。
-
为 IBM Cloud 基础架构帐户启用虚拟路由器功能 (VRF)。 要启用 VRF,请参阅 启用 VRF。 要检查是否已启用 VRF,请使用
ibmcloud account show命令。 如果无法或不想启用 VRF,请启用 VLAN 生成。 启用了 VRF 或 VLAN 生成后,NLB 2.0 可以将包路由到帐户中的各种子网。 -
如果使用 Calico DNAT 前网络策略 来管理到 NLB 2.0的流量,那么必须将
applyOnForward: true和doNotTrack: true字段添加到策略中的spec部分并从其中除去preDNAT: true。applyOnForward: true确保 Calico 策略在封装和转发时应用于流量。doNotTrack: true确保工作程序节点可以使用 DSR 将响应包直接返回到客户机,而无需跟踪连接。 例如,如果您使用“Calico”策略,仅允许来自特定 IP 地址的流量访问您的 NLB IP 地址,则该策略大致如下所示:apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: allowlist spec: applyOnForward: true doNotTrack: true ingress: - action: Allow destination: nets: - <loadbalancer_IP>/32 ports: - 80 protocol: TCP source: nets: - <client_address>/32 selector: ibm.role=='worker_public' order: 500 types: - Ingress
接下来,您可以执行在多专区集群中设置 NLB 2.0 或在单专区集群中设置 NLB 2.0 中的步骤。
在多专区集群中设置 NLB 2.0
准备工作
在继续操作之前,请先满足 NLB 2.0 的先决条件。
-
要在多个专区中创建公共 NLB,至少一个公用 VLAN 必须在每个专区中提供可移植子网。 要在多个专区中创建专用 NLB,至少一个专用 VLAN 必须在每个专区中提供可移植子网。 您可以执行配置集群的子网中的步骤来添加子网。
-
请确保您拥有
default命名空间的 “Writer”或 “Manager” IBM Cloud IAM服务访问角色。 -
确保您具有必需数量的工作程序节点:
- 经典集群:如果将网络流量限制为流至边缘工作程序节点,请确保每个专区中至少启用 2 个边缘工作程序节点,以便 NLB 能以均匀方式进行部署。
-
重新装入集群节点或集群主节点更新包含新的
keepalived映像时,负载均衡器虚拟 IP 将移至新节点的网络接口。 发生此情况时,必须重新建立与负载均衡器的任何长期连接。 请考虑在应用程序中包含重试逻辑,以便快速尝试重新建立连接。
要在多专区集群中设置 NLB 2.0,请执行以下操作:
-
将应用程序部署到集群。 确保在配置文件的 metadata 部分中添加针对您的部署的标签。 此定制标签可标识运行您的应用程序的所有 pod,以便在负载均衡中包含这些 pod。
-
针对要向公用因特网或专用网络公开的应用程序创建 Load Balancer 服务。
- 创建名为
myloadbalancer.yaml(举例来说)的服务配置文件。 - 针对要公开的应用程序定义 LoadBalancer 服务。 您可以指定专区、VLAN 和 IP 地址。
apiVersion: v1 kind: Service metadata: name: myloadbalancer annotations: service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: <public_or_private> service.kubernetes.io/ibm-load-balancer-cloud-provider-zone: "<zone>" service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan: "<vlan_id>" service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs" service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "<algorithm>" spec: type: LoadBalancer selector: <selector_key>: <selector_value> ports: - protocol: TCP port: 8080 targetPort: 8080 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise. loadBalancerIP: <IP_address> externalTrafficPolicy: Local ``` `service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type` : 用于指定 `private` 或 `public` 负载均衡器的注释。 `service.kubernetes.io/ibm-load-balancer-cloud-provider-zone` : 用于指定 LoadBalancer 服务部署到的专区的注释。 要查看分区,请运行 `ibmcloud oc zone ls`。 `service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan` : 用于指定 LoadBalancer 服务部署到的 VLAN 的注释。 要查看VLAN,请运行 `ibmcloud oc vlan ls --zone ZONE`。 `service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs"` : 用于指定 V2.0 负载均衡器的注释。 `service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler` : 可选:用于指定调度算法的注释。 允许的取值为:轮询(round-robin)模式下的 `"rr"` (默认值)或源哈希(Source Hashing)模式下的 `"sh"`。 有关更多信息,请参阅 [2.0:调度算法](#scheduling)。 `selector` : 您在应用部署 YAML 文件的 `spec.template.metadata.labels` 部分中使用的标签键(`<selector_key>` )和标签值(`<selector_value>` )。 `port` : 服务侦听的端口。 `loadBalancerIP` : 可选:要创建专用 NLB 或要将特定可移植 IP 地址用于公共 NLB,请指定要使用的 IP 地址。 该 IP 地址必须位于在注释中指定的专区和 VLAN 中。 如果您未指定 IP 地址: : 如果集群位于公用 VLAN 上,那么将使用可移植的公共 IP 地址。 大多数集群都位于公用 VLAN 上。 : 如果集群仅位于专用 VLAN 上,那么将使用可移植的专用 IP 地址。 `externalTrafficPolicy: Local` : 将其设置为 `Local`。 以下是在 `dal12` 中创建一个使用轮询调度算法的 NLB 2.0 服务的配置文件示例: ```yaml {: codeblock} apiVersion: v1 kind: Service metadata: name: myloadbalancer annotations: service.kubernetes.io/ibm-load-balancer-cloud-provider-zone: "dal12" service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs" service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "rr" spec: type: LoadBalancer selector: app: nginx ports: - protocol: TCP port: 8080 targetPort: 8080 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise. externalTrafficPolicy: Local ``` 3. 可选:通过在“`spec.loadBalancerSourceRanges`”字段中指定 IP 地址,将 NLB 服务仅限特定 IP 地址范围访问。集群中的 `kube-proxy` 通过在工作节点上应用 iptables 规则,实现了“`loadBalancerSourceRanges`”功能。 如需了解更多信息,请参阅 [Kubernetes 文档](https://kubernetes.io/docs/concepts/services-networking/){: external}。 4. 在集群中创建服务。 ```sh {: pre} oc apply -f myloadbalancer.yaml ``` - 创建名为
-
验证 NLB 服务是否已成功创建。 这可能需要几分钟时间,才能正确创建 NLB 服务并使应用程序可用。
oc describe service myloadbalancer示例输出:
NAME: myloadbalancer Namespace: default Labels: <none> Selector: app=liberty Type: LoadBalancer Zone: dal10 IP: 172.21.xxx.xxx LoadBalancer Ingress: 169.xx.xxx.xxx Port: <unset> 8080/TCP NodePort: <unset> 32040/TCP Endpoints: 172.30.xxx.xxx:8080 Session Affinity: None Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- ---- ------ ------- 10s 10s 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer 10s 10s 1 {service-controller } Normal CreatedLoadBalancer Created load balancerLoadBalancer Ingress IP 地址是分配给 NLB 服务的可移植 IP 地址。
-
如果创建了公共 NLB,请从因特网访问该应用程序。
- 打开首选的 Web 浏览器。
- 输入 NLB 的可移植公共 IP 地址和端口。
http://169.xx.xxx.xxx:8080 ``` -
为了实现高可用性,请重复步骤 2–4,在每个部署了应用程序实例的区域中添加一个 NLB 2.0。
-
可选:NLB 服务还可使应用程序在服务的 NodePort 上可用。 对于集群内的每个节点,在每个公共和专用 IP 地址上都可以访问 NodePort。 要在使用 NLB 服务时阻止流至 NodePort 的流量,请参阅控制流至网络负载均衡器 (NLB) 或 NodePort 服务的入站流量。
接下来,可以注册 NLB 子域。
在单专区集群中设置 NLB 2.0
准备工作
在继续操作之前,请先满足 NLB 2.0 的先决条件。
-
必须有可用的可移植公共或专用 IP 地址可分配给 NLB 服务。 有关更多信息,请参阅配置集群的子网。
-
请确保您拥有
default命名空间的 “Writer”或 “Manager” IBM Cloud IAM服务访问角色。 -
重新装入集群节点或集群主节点更新包含新的
keepalived映像时,负载均衡器虚拟 IP 将移至新节点的网络接口。 发生此情况时,必须重新建立与负载均衡器的任何长期连接。 请考虑在应用程序中包含重试逻辑,以便快速尝试重新建立连接。
要在单专区集群中创建 NLB 2.0 服务,请执行以下操作:
-
将应用程序部署到集群。 确保在部署配置文件的 metadata 部分中添加标签。 此定制标签可标识运行您的应用程序的所有 pod,以便在负载均衡中包含这些 pod。
-
针对要向公用因特网或专用网络公开的应用程序创建 Load Balancer 服务。
-
创建名为
myloadbalancer.yaml(举例来说)的服务配置文件。 -
针对要公开的应用程序定义 LoadBalancer 2.0 服务。
apiVersion: v1 kind: Service metadata: name: myloadbalancer annotations: service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: <public_or_private> service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan: "<vlan_id>" service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs" service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "<algorithm>" spec: type: LoadBalancer selector: <selector_key>: <selector_value> ports: - protocol: TCP port: 8080 targetPort: 8080 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise. loadBalancerIP: <IP_address> externalTrafficPolicy: Local ``` `service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type` : 用于指定 `private` 或 `public` 负载均衡器的注释。 `service.kubernetes.io/ibm-load-balancer-cloud-provider-vlan` : 可选:用于指定 LoadBalancer 服务部署到的 VLAN 的注释。 要查看VLAN,请运行 `ibmcloud oc vlan ls --zone ZONE`。 `service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "ipvs"` : 用于指定 LoadBalancer 2.0 的注释。 `service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler` : 可选:用于指定调度算法的注释。 允许的取值为:轮询(round-robin)模式下的 `"rr"` (默认值)或源哈希(Source Hashing)模式下的 `"sh"`。 有关更多信息,请参阅 [2.0:调度算法](#scheduling)。 `selector` : 您在应用部署 YAML 文件的 `spec.template.metadata.labels` 部分中使用的标签键(`<selector_key>` )和标签值(`<selector_value>` )。 `port` : 服务侦听的端口。 `loadBalancerIP` : 可选:要创建专用 NLB 或要将特定可移植 IP 地址用于公共 NLB,请指定要使用的 IP 地址。 该 IP 地址必须位于在注释中指定的 VLAN 上。 如果您未指定 IP 地址: - 如果集群位于公用 VLAN 上,那么将使用可移植的公共 IP 地址。 大多数集群都位于公用 VLAN 上。 - 如果集群仅位于专用 VLAN 上,那么将使用可移植的专用 IP 地址。 `externalTrafficPolicy: Local` : 将其设置为 `Local`。 3. 可选:通过在“`spec.loadBalancerSourceRanges`”字段中指定 IP 地址,将 NLB 服务仅限特定 IP 地址范围访问。集群中的 `kube-proxy` 通过在工作节点上应用 iptables 规则,实现了“`loadBalancerSourceRanges`”功能。 如需了解更多信息,请参阅 [Kubernetes 文档](https://kubernetes.io/docs/concepts/services-networking/){: external}。 4. 在集群中创建服务。 ```sh {: pre} oc apply -f myloadbalancer.yaml ``` -
-
验证 NLB 服务是否已成功创建。 可能需要几分钟时间,才能创建该服务并使应用程序可用。
oc describe service myloadbalancer示例输出:
NAME: myloadbalancer Namespace: default Labels: <none> Selector: app=liberty Type: LoadBalancer Location: dal10 IP: 172.21.xxx.xxx LoadBalancer Ingress: 169.xx.xxx.xxx Port: <unset> 8080/TCP NodePort: <unset> 32040/TCP Endpoints: 172.30.xxx.xxx:8080 Session Affinity: None Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- ---- ------ ------- 10s 10s 1 {service-controller } Normal CreatingLoadBalancer Creating load balancer 10s 10s 1 {service-controller } Normal CreatedLoadBalancer Created load balancerLoadBalancer Ingress IP 地址是分配给 NLB 服务的可移植 IP 地址。
-
如果创建了公共 NLB,请从因特网访问该应用程序。
- 打开首选的 Web 浏览器。
- 输入 NLB 的可移植公共 IP 地址和端口。
http://169.xx.xxx.xxx:8080 ``` -
可选:NLB 服务还可使应用程序在服务的 NodePort 上可用。 对于集群内的每个节点,在每个公共和专用 IP 地址上都可以访问 NodePort。 要在使用 NLB 服务时阻止流至 NodePort 的流量,请参阅控制流至网络负载均衡器 (NLB) 或 NodePort 服务的入站流量。
接下来,可以注册 NLB 子域。
安排算法
调度算法确定 NLB 2.0 如何将网络连接分配给应用程序 pod。 客户机请求到达集群时,NLB 会根据调度算法将请求包路由到工作程序节点。 要使用调度算法,请在 NLB 服务配置文件的调度器注解中指定其短名称 Keepalived:service.kubernetes.io/ibm-load-balancer-cloud-provider-ipvs-scheduler: "rr"。 请查看以下列表以了解
Red Hat OpenShift on IBM Cloud 中支持哪些调度算法。 如果未指定调度算法,则默认使用循环调度算法。 如需了解更多信息,请参阅 Keepalived 文档。
支持的调度算法
- 轮询(
rr) - 当将连接路由到工作程序节点时,NLB 会在应用程序 pod 列表中循环,对每个应用程序 pod 进行同等处理。循环法是 V 2.0 NLB 的缺省调度算法。
- 源代码哈希(
sh) - NLB 会基于客户机请求包的源 IP 地址生成一个散列键。 然后,NLB 会在静态分配的散列表中查找该散列键,并将请求路由到用于处理该范围的散列的应用程序 pod。 此算法可确保来自特定客户机的请求始终定向到同一应用程序 pod。 Kubernetes 使用 iptables 规则,这些规则会将请求转发到 worker 上的某个随机 pod。 要使用此调度算法,您必须确保每个工作程序节点仅部署一个应用程序 pod。 例如,如果每个 Pod 都有标签
run=<app_name>,请在应用程序部署的spec部分中添加以下反亲和性规则:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: run
operator: In
values:
- <APP_NAME>
topologyKey: kubernetes.io/hostname
不受支持的调度算法
- 目标哈希(
dh) - 包的目标(即 NLB IP 地址和端口)用于确定哪个工作程序节点处理入局请求。 但是,Red Hat OpenShift on IBM Cloud 中 NLB 的 IP 地址和端口不会更改。 NLB 被迫在其所在的工作程序节点中保留该请求,因此只有一个工作程序上的应用程序 pod 处理所有入局请求。
- 动态连接计数算法
- 以下算法取决于客户机与 NLB 之间的动态连接计数。 但是,由于直接服务返回 (DSR) 会阻止 NLB 2.0 pod 位于返回数据包路径中,因此 NLB 不会跟踪建立的连接。
- 最小连接 (
lc) - 基于局部性的最小连接(
lblc) - 基于局部性的带复制功能的最少连接算法(
lblcr) - 永不排队 (
nq) - 最短预期延迟(
seq)
- 最小连接 (
- 加权的 pod 算法
- 以下算法取决于加权的应用程序 pod。 但是,在 Red Hat OpenShift on IBM Cloud 中,所有应用程序 pod 会分配有相同的权重以实现负载均衡。
- 加权最小连接(
wlc) - 加权循环法 (
wrr)
- 加权最小连接(