经典:使用 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 之前,必须完成以下必备步骤。

  1. 要允许 NLB 2.0 将请求转发到多个专区中的应用程序 pod,请打开支持案例以请求对 VLAN 进行容量聚集。 此配置设置不会导致任何网络中断。

    1. 登录到 IBM Cloud 控制台
    2. 在菜单栏中,单击支持,单击管理案例选项卡,然后单击创建新案例
    3. 在案例字段中,输入以下内容: 主题:网络 - 配置 子主题:经典 - VLAN
    4. 将以下信息添加到描述中: 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 标识。
    5. 单击提交
  2. 为 IBM Cloud 基础架构帐户启用虚拟路由器功能 (VRF)。 要启用 VRF,请参阅 启用 VRF。 要检查是否已启用 VRF,请使用 ibmcloud account show 命令。 如果无法或不想启用 VRF,请启用 VLAN 生成。 启用了 VRF 或 VLAN 生成后,NLB 2.0 可以将包路由到帐户中的各种子网。

  3. 如果使用 Calico DNAT 前网络策略 来管理到 NLB 2.0的流量,那么必须将 applyOnForward: truedoNotTrack: true 字段添加到策略中的 spec 部分并从其中除去 preDNAT: trueapplyOnForward: 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,请执行以下操作:

  1. 将应用程序部署到集群。 确保在配置文件的 metadata 部分中添加针对您的部署的标签。 此定制标签可标识运行您的应用程序的所有 pod,以便在负载均衡中包含这些 pod。

  2. 针对要向公用因特网或专用网络公开的应用程序创建 Load Balancer 服务。

    1. 创建名为 myloadbalancer.yaml(举例来说)的服务配置文件。
    2. 针对要公开的应用程序定义 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
        ```
    
  3. 验证 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 balancer
    

    LoadBalancer Ingress IP 地址是分配给 NLB 服务的可移植 IP 地址。

  4. 如果创建了公共 NLB,请从因特网访问该应用程序。

    1. 打开首选的 Web 浏览器。
    2. 输入 NLB 的可移植公共 IP 地址和端口。
        http://169.xx.xxx.xxx:8080
        ```
    
  5. 为了实现高可用性,请重复步骤 2–4,在每个部署了应用程序实例的区域中添加一个 NLB 2.0。

  6. 可选: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 服务,请执行以下操作:

  1. 将应用程序部署到集群。 确保在部署配置文件的 metadata 部分中添加标签。 此定制标签可标识运行您的应用程序的所有 pod,以便在负载均衡中包含这些 pod。

  2. 针对要向公用因特网或专用网络公开的应用程序创建 Load Balancer 服务。

    1. 创建名为 myloadbalancer.yaml(举例来说)的服务配置文件。

    2. 针对要公开的应用程序定义 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
        ```
    
  3. 验证 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 balancer
    

    LoadBalancer Ingress IP 地址是分配给 NLB 服务的可移植 IP 地址。

  4. 如果创建了公共 NLB,请从因特网访问该应用程序。

    1. 打开首选的 Web 浏览器。
    2. 输入 NLB 的可移植公共 IP 地址和端口。
        http://169.xx.xxx.xxx:8080
        ```
    
  5. 可选:NLB 服务还可使应用程序在服务的 NodePort 上可用。 对于集群内的每个节点,在每个公共和专用 IP 地址上都可以访问 NodePort。 要在使用 NLB 服务时阻止流至 NodePort 的流量,请参阅控制流至网络负载均衡器 (NLB) 或 NodePort 服务的入站流量

接下来,可以注册 NLB 子域

安排算法

调度算法确定 NLB 2.0 如何将网络连接分配给应用程序 pod。 客户机请求到达集群时,NLB 会根据调度算法将请求包路由到工作程序节点。 要使用调度算法,请在 NLB 服务配置文件的调度器注解中指定其短名称 Keepalivedservice.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)