设置一个 Network Load Balancer for VPC

通过在 VPC 集群的每个区域中设置公共或私有 Kubernetes LoadBalancer 服务,将您的应用对外公开或仅限私有网络访问。 然后,您可以选择 通过 DNS 记录和 TLS 证书为 VPC NLB 进行注册。 VPC NLB 同时支持 TCP 和 UDP 这两种协议类型。

设置公共或私有 VPC NLB

通过在集群的每个区域中设置 Kubernetes LoadBalancer 服务,使您的应用能够处理网络流量。 当您创建“Kubernetes”LoadBalancer 服务时,系统会自动在您的 VPC 中(位于集群之外)为您创建一个公共或私有的 Network Load Balancer for VPC (VPC NLB),用于将请求路由到您的应用。

准备工作

  1. 请确保您拥有部署 Kubernetes 的命名空间的 WriterManager IBM Cloud IAM 服务访问角色。LoadBalancer VPC NLB 服务。
  2. 访问 Red Hat OpenShift 集群
  3. 要查看 VPC NLB,请安装 infrastructure-service 插件。 用于运行命令的前缀是 ibmcloud is
    ibmcloud plugin install infrastructure-service
    
  4. 对于私有 VPC NLB:连接到 VPC 专用网络,如通过 VPC VPN 连接
  5. 对于私有 VPC NLB:启用应用程序接收专用网络请求。
    1. 创建一个专用于 VPC NLB 的 VPC 子网。 该子网必须与群集位于同一 VPC 和位置,但不能连接到群集或任何工作节点。 如果输入特定 IP 范围,请勿使用以下保留范围:172.16.0.0/16, 172.18.0.0/16, 172.19.0.0/16,和 172.20.0.0/16。 配置子网后,请记下其 ID
    2. 如果通过 VPC NLB 连接到应用程序的客户端存在于专用 VPC 子网的 VPC 和区域之外,则必须 创建自定义入口路由表。 有关更多信息,请参阅 已知限制关于路由表和路由的 表格。 为自定义入口路由表选择以下 流量源之一:对于来自内部网络的流量,请选择直接链接。 对于来自其他 VPC 或传统基础设施的流量,请选择转接网关。 对于来自同一 VPC 中另一区域的流量,请选择 VPC 区域。 更多信息,请参阅 设置 VPC VPN 连接

配置 LoadBalancer 服务

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

  2. 为 Kubernetes LoadBalancer 服务创建配置 YAML 文件。 在 YAML 文件中,将 service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type 注释指定为 "public""private"。 示例文件中的 annotations 部分仅包含一些可用的注释。 有关必需和可选 VPC NLB 注释的完整列表,请参阅注释 和规范

    为使您的 VPC NLB 易于识别,请考虑以 <app_name>-vpc-nlb-<VPC_zone> 的格式命名服务。

    apiVersion: v1
    kind: Service
    metadata:
      name: <app_name>-vpc-nlb-<VPC_zone>
      annotations:
        service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-lb-name: "my-load-balancer"
        service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "nlb"
        service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: "public"
        service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-node-selector: "<key>=<value>"
        service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-subnets: "<subnet1_ID,subnet2_ID>"
    spec:
      type: LoadBalancer
      selector:
        <selector_key>: <selector_value>
      ports:
       - name: http
         protocol: TCP
         port: 8080
         targetPort: 8080 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise.
       - name: https
         protocol: TCP
         port: 443
         targetPort: 443 # Optional. By default, the `targetPort` is set to match the `port` value unless specified otherwise.
      externalTrafficPolicy: Local # Specify Local or Cluster.
    
  3. 在集群中创建 Kubernetes LoadBalancer 服务。

    oc apply -f <filename>.yaml -n <namespace>
    
  4. 验证 Kubernetes LoadBalancer 服务是否已在集群中成功创建。 创建服务时,LoadBalancer Ingress 字段将填入 VPC NLB 分配的外部 IP 地址。

在您的 VPC 中配置 VPC NLB 需要几分钟时间。 在 VPC NLB 完全配置完成之前,您的 Kubernetes LoadBalancer 服务的外部 IP 地址可能是 pending

```sh {: pre}
oc describe svc myloadbalancer -n <namespace>
```
公共 `LoadBalancer` 服务的 CLI 输出示例:
```sh {: screen}
NAME:                     myapp-vpc-nlb-us-east
Namespace:                default
Labels:                   <none>
Annotations:              service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: nlb
Selector:                 app=echo-server
Type:                     LoadBalancer
IP:                       172.21.204.12
LoadBalancer Ingress:     169.XXX.XXX.XXX
Port:                     tcp-80  80/TCP
TargetPort:               8080/TCP
NodePort:                 tcp-80  32022/TCP
Endpoints:                172.17.17.133:8080,172.17.22.68:8080,172.17.34.18:8080 + 3 more...
Session Affinity:         None
External Traffic Policy:  Local
HealthCheck NodePort:     30882
Events:
    Type     Reason                           Age                  From                Message
----     ------                           ----                 ----                -------
Warning  SyncLoadBalancerFailed           13m (x5 over 15m)    service-controller  Error syncing load balancer: failed to ensure load balancer: kube-bqcssbbd0bsui62odcdg-2d93b07decf641d2ad3f9c2985122ec1 for service default/myvpcnlb is busy: offline/create_pending
Normal   EnsuringLoadBalancer             9m27s (x7 over 15m)  service-controller  Ensuring load balancer
Normal   EnsuredLoadBalancer              9m20s                service-controller  Ensured load balancer
Normal   CloudVPCLoadBalancerNormalEvent  8m17s                ibm-cloud-provider  Event on cloud load balancer myvpcnlb for service default/myvpcnlb with UID 2d93b07d-ecf6-41d2-ad3f-9c2985122ec1: The VPC load balancer that routes requests to this Kubernetes LoadBalancer service is currently online/active.
```
  1. 请确认 VPC NLB 已在您的 VPC 中成功创建。 在输出结果中,请确认 VPC NLB 的“运行状态”为 online,且“配置状态”为 active

    ibmcloud is load-balancers
    

    在下面的 CLI 输出示例中,为 Kubernetes LoadBalancer 服务创建了一个名为 kube-bh077ne10vqpekt0domg-046e0f754d624dca8b287a033d55f96e 的 VPC NLB:

    ID                                     Name                                                         Created          Host Name                                  Is Public   Listeners                               Operating Status   Pools                                   Private IPs              Provision Status   Public IPs                    Subnets                                Resource Group
    06496f64-a689-4693-ba23-320959b7b677   kube-bh077ne10vqpekt0domg-046e0f754d624dca8b287a033d55f96e   8 minutes ago    1234abcd-us-south.lb.appdomain.cloud       yes         95482dcf-6b9b-4c6a-be54-04d3c46cf017    online             717f2122-5431-403c-b21d-630a12fc3a5a    10.241.0.7               active             169.63.99.184                 c6540331-1c1c-40f4-9c35-aa42a98fe0d9   00809211b934565df546a95f86160f62
    
  2. 访问在步骤 4 中找到的 Kubernetes LoadBalancer 服务的 IP 地址和应用程序端口,格式为 <external_IP>:<app_port>

  3. 可选:重复上述步骤,在每个要公开应用程序的区域部署公共 VPC NLB。 然后,可以在每个区域中用一个 DNS 子域 注册 VPC NLB 的外部 IP 地址。

在创建群集时或在区域中添加工作节点时,请勿删除附加到群集的子网。 如果删除群集使用过的 VPC 子网,使用该子网 IP 地址的任何 VPC NLB 都可能出现问题,而且可能无法创建新的负载平衡器。

使用端口范围设置公共 NLB

当需要从一个主机名托管服务时,可以在公共 NLB 中使用端口范围,该主机名有多个后端应用程序,每个应用程序监听一个单独的端口号。 要在 Kubernetes 集群中使用端口范围,必须进行一些手动配置。 首先,必须设置 ibm-load-balancer-cloud-provider-vpc-port-range 选项。 它可以包括一个或多个范围,每个范围用逗号分隔。 spec.ports.port 值也必须设置为端口范围内的最小值。

在下面的示例中,使用的端口范围是 30000-30010

必须为 NLB 服务转发请求的每个部署手动创建 Nodeport 服务。 每个 Nodeport 服务的端口号都必须在 NLB 服务配置的端口范围内。

在下图示例中,为部署 1 创建了端口为 30000 的 Nodeport 服务,而为部署 2 创建了端口为 30001 的 Nodeport 服务。

用户向包含端口范围的 NLB 30001 端口发出请求。 该请求会被定向到 VPC NLB 服务,后者会将请求定向到群集中同样监听 30001 端口的 Nodeport 服务,在本例中就是部署 2。 然后,Nodeport 服务会将请求指向部署 2 中所选 pod 的目标端口。

使用端口范围的 VPC NLB。
带端口范围的 VPC NLB

使用以下示例创建一个使用端口范围的 NLB。 选择器和后端 pod 必须与端口范围负载平衡服务相关联,这样健康检查才会返回成功,数据才会传送到端口范围内的端口。 要使用端口范围,必须创建额外的 NodePort 服务,其端口值必须在负载平衡器服务定义的范围内。

  1. 将以下 LoadBalancer 配置示例保存为名为 loadbalancer.yaml 的文件。

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: nlb
        service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-port-range: 30000-30010
      name: nlb-port-range
    spec:
      externalTrafficPolicy: Cluster
      ports:
      - port: 30000 # Must match min from the port range
        protocol: TCP
        nodePort: 30011 # Can be port in range or not
        targetPort: 8080
      selector:
        app: echo-server  # Must be valid for health checks to work
      type: LoadBalancer
    
  2. 创建服务。

    oc apply -f loadbalancer.yaml
    
  3. 创建 NodePort 服务,其端口值应在先前创建的 LoadBalancer 中指定的端口范围内。

    apiVersion: v1
    kind: Service
    metadata:
      name: echo-server-node-port
    spec:
      ports:
      - port: 80
        protocol: TCP # The protocol of the port range
        nodePort: 30003 # Node port in the port range
        targetPort: 8080
      selector:
        app: echo-server
      type: NodePort
    
  4. 创建 NodePort 服务。

    oc apply -f nodeport.yaml
    
  5. 访问 NLB 提供范围内的端口。

    curl https://<public ip assigned to NLB>:30003
    
    • 30003 = 是响应请求范围内的节点端口
    • 除非创建额外的节点端口服务,否则该范围内的其他端口不会响应。

注册 DNS 记录和 TLS 证书

VPC NLB 提供静态外部 IP 地址,您可以通过它访问应用程序。 若要为您的应用域名注册一个 SSL 证书以支持 HTTPS,您可以创建一个由 IBM 提供的子域名,或使用您自己的自定义域名。

例如,您有一个多区集群,并在集群每个区的工作节点上运行应用程序的副本。 您为每个区域创建一个 VPC NLB,以公开应用程序副本。 然后,就可以用一个 DNS 条目注册每个 VPC NLB 提供的外部 IP 地址。

为 VPC NLB 创建 DNS 子域名后,您将无法使用 nlb-dns health-monitor 命令来创建自定义健康检查。 取而代之的是使用默认的 VPC 健康检查。 有关更多信息,请参阅 VPC 文档

  • 为应用程序的每个区域创建一个 VPC NLB。 确保在配置 VPC NLB 的 Kubernetes LoadBalancer 服务中定义 HTTPS 端口。
  • 若要使用 SSL 证书通过 HTTPS 访问您的应用,您的应用必须能够终止 TLS 连接。

请按照以下步骤使用 DNS 子域注册 VPC NLB IP 地址。

  1. 读取负载平衡器的外部 IP 地址。

    oc get svc -o wide
    

    示例输出

    NAME                      TYPE           CLUSTER-IP       EXTERNAL-IP       PORT(S)            AGE      SELECTOR
    ...
    myapp-vpc-nlb-jp-tok-3    LoadBalancer   172.21.xxx.xxx   169.xx.xxx.xx     8080:30532/TCP     1d       run=webserver
    
  2. 为 IP 地址创建自定义或 IBM 提供的 DNS 子域。

    • 自定义域名

      1. 与您的域名服务 (DNS) 提供商或 IBM Cloud DNS 合作,注册自定义域名。
      2. 通过将负载平衡器 IP 地址指定为 A 记录,为自定义域定义别名。
    • IBM-提供的子域名:使用 nlb-dns 命令,为这些 IP 地址生成一个带有 SSL 证书的子域名。IBM Cloud 将为您自动生成并维护该子域名的通配符 SSL 证书。

      1. 创建一个 DNS 子域名和 SSL 证书。
        ibmcloud oc nlb-dns create vpc-gen2 --type public --cluster CLUSTER_NAME_OR_ID --ip VPC_NLB1_IP --ip VPC_NLB2_IP --ip VPC_NLB3_IP
        
      2. 验证子域是否已创建。 有关更多信息,请参阅了解子域格式
        ibmcloud oc nlb-dns ls --cluster CLUSTER_NAME_OR_ID
        
        示例输出
        Subdomain                                                                               IP(s)                                        Health Monitor   SSL Cert Status           SSL Cert Secret Name
        mycluster-a1b2cdef345678g9hi012j3kl4567890-0001.us-south.containers.appdomain.cloud     169.46.xx.x,169.48.xxx.xx,169.48.xxx.xx      None             created                   <certificate>
        
  3. 打开浏览器,输入 URL,通过子域访问应用程序。

若要使用 SSL 证书通过 HTTPS 访问您的应用,请确保已在 Kubernetes LoadBalancer 服务中 定义了 HTTPS 端口。 您可以通过运行 curl -v --insecure https://<domain> 来验证请求是否正确地通过 HTTPS 端口进行路由。 连接错误表明该服务上没有打开的 HTTPS 端口。 此外,请确保您的应用能够终止 TLS 连接。 您可以通过运行 curl -v https://<domain> 来验证您的应用是否正确终止了 TLS。 证书错误表明您的应用未正确关闭 TLS 连接。

注释和规格

查看所需和可选的 VPC NLB 注释和规范。

所需的注释和规格

service.kubernetes.io/ibm-load-balancer-cloud-provider-enable-features: "nlb"
注释来创建 VPC NLB。 如果不包含此注释并指定 nlb,则默认创建一个 VPC ALB。
service.kubernetes.io/ibm-load-balancer-cloud-provider-ip-type: "private"
(私有 NLB 需要)用于指定接受私有请求的服务的注解。 如果未包含此注释,则会创建公共 VPC NLB。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-subnets
(私有 NLB 需要,公共 NLB 可选)用于指定 VPC NLB 部署到的专用子网的注释。 该值可指定为 VPC 子网 ID、VPC 子网名称或 VPC 子网 CIDR。 您必须只指定一个子网。 子网必须与群集位于同一 VPC 中,并位于群集有工作节点的区域内,但不能将工作节点连接到该子网。 与该子网位于同一区域的工作节点被配置为接收来自 VPC NLB 的流量。 要查看所有资源组中的子网,请运行 ibmcloud oc subnets --provider vpc-gen2 --vpc-id VPC_ID --zone ZONE
externalTrafficPolicy
指定 LocalCluster
设置为 Local 可保留客户端向应用程序发出请求时的源 IP 地址。 此设置可防止将传入流量转发到其他节点。 该选项还可配置 HTTP 健康检查。
如果设置了 Cluster,则仅从 VPC NLB 最初转发传入请求的工作节点实施 DSR。 传入请求到达后,请求会被转发到包含应用程序 pod 的工作节点,该工作节点可能位于不同的区域。 应用程序 pod 的响应会发送到原始工作节点,该工作节点会使用 DSR 绕过 VPC NLB 直接将响应发回客户端。 此选项还会配置 TCP 的健康检查。 对于 UDP 负载均衡器,如果选择“Cluster”选项,则必须使用 service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-udp。 如需了解更多信息,请参阅 《 为 UDP 负载均衡器配置 TCP 健康检查 》。

可选注释和规格

service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-lb-name
包含一个唯一的名称,使您的 VPC 负载均衡器具有持久性。 删除所属群集时,不会删除持久 VPC 负载平衡器。 有关详细信息,请参阅 持久 VPC 负载平衡器。 此注释只能在创建负载平衡器时设置。 它不能用于更新操作。
service.kubernetes.io/ibm-load-balancer-cloud-provider-zone
注释,以指定群集所连接的 VPC 区域。 VPC NLB 部署到与工人节点相连的该区域的同一子网中。 如果以后将此注释更改为其他区域,VPC NLB 不会移动到新区域。 如果不指定此注释或 service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-subnets annotation,VPC NLB 将部署到最佳区域(如有处于 Ready 状态的工作节点的区域)。 如果在工作节点上设置了 dedicated: edge 标签并指定了此注释,则只有指定区域中的边缘节点才会被配置为接收流量。 其他区域的边缘节点和指定区域的非边缘节点不会接收来自负载平衡器的流量。 要查看分区,请运行 ibmcloud ks zone ls --provider vpc-gen2
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-node-selector
注释,用于指定工作节点标签选择器。 您可以通过指定标签选择器密钥,将群集中的特定工作节点配置为接收流量。 注释中只能包含一个标签选择器,而且必须以 "key=value" 格式指定该选择器。 如果未指定此注释,群集中的所有工作节点都会被配置为接收来自 VPC NLB 的流量。 该注释优先于 service.kubernetes.io/ibm-load-balancer-cloud-provider-zone 注释,工作节点上的任何 dedicated: edge 标签都会被忽略。 要将流量限制在特定区域内,可以使用此注释指定该区域内的工作者节点。 请注意,在群集工作节点上设置新标签并不会自动将工作节点配置为接收流量;您必须重新创建或更新 VPC NLB,才能让新标签的工作节点接收流量。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-udp
在 UDP 负载均衡器中,用于 TCP 健康检查的 TCP 节点端口。 对于将 externalTrafficPolicy 设置为 Cluster 的 UDP 负载均衡器,此设置是必需的。 在设置端口值之前,请参阅 《 配置适用于 UDP 负载均衡器的 TCP 健康检查 》以了解其他注意事项。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-protocol
此注解设置了与 Kubernetes 负载平衡器服务相关联的 VPC 负载平衡器资源的健康检查协议。 可用选项为 http, https,或 tcp。 通常,VPC LB 健康检查协议由 Kubernetes 负载平衡器服务规范中的 externalTrafficPolicy 设置值决定。 但是,本注释会覆盖这一逻辑。 该注释不会改变 Kubernetes,特别是 kube-proxy 在 externalTrafficPolicy 的各种设置下的行为方式。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-port
用于健康检查的 TCP 端口。 只有同时指定 ibm-load-balancer-cloud-provider-vpc-health-check-protocol 时,该注释才适用。 如果指定的 TCP 端口超出了 Kubernetes 节点端口范围(30,000-32,767),则必须修改应用于集群工作节点的VPC安全组,以允许该端口的入站流量。 如果将此注释应用于与 VPC ALB 关联的 Kubernetes 负载均衡服务,则必须修改分配给该 VPC ALB 的安全组的出站规则,以允许出站流量流向指定的 TCP 端口。 有关更多信息,请参阅 了解默认情况下的安全群集 VPC 网络 以及 创建和管理 VPC 安全组
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-path
健康检查 URL 路径,用于 HTTP 和 HTTPs 健康检查。 只有当 ibm-load-balancer-cloud-provider-vpc-health-check-protocol 设置为 httphttps 时,此注释才适用。 URL 路径必须采用 origin-form 请求目标的格式。 如果未指定此注释,且 ibm-load-balancer-cloud-provider-vpc-health-check-protocol 注释设置为 httphttps,则应用默认值 /
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-delay
可选。 两次健康检查之间的等待秒数。 默认情况下,该值设置为 5,最小值为 2,最大值为 60。 该值必须大于 ibm-load-balancer-cloud-provider-vpc-health-check-timeout 值,默认设置为 2
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-timeout
可选。 等待健康检查回复的秒数。 默认情况下,该值设置为 2,最小值为 1,最大值为 59。 该值必须小于 ibm-load-balancer-cloud-provider-vpc-health-check-delay,默认设置为 5
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-health-check-retries
VPC 负载均衡器健康检查重试的最大次数。 默认情况下,该值设置为 2,最小值为 1,最大值为 10
service.kubernetes.io/ibm-load-balancer-cloud-provider-dns-name: "example-ingress-domain.<region>.containers.appdomain.cloud"
版本为 4.16 或更高版本。
将负载平衡器的 IP 地址注册到指定的 输入域。 如果指定的域不存在,则会创建一个使用内部 IBM 管理提供程序 (IBM NS1) 的域。要创建新域,名称必须在所有现有域(不只是群集中的域)中唯一。 删除负载平衡器服务会从域中删除 IP 地址。 但是,删除注释并不会从域中删除 IP 地址。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-member-quota
可选。 负载平衡器路由到的每个区域的工作节点数量。 缺省值为 8。 对于工作节点分布在三个区域的集群,这将导致负载均衡器将流量路由到总共 24 个工作节点。 负载平衡器路由到的所有区域的工作节点总数不能超过 50 个。 如果集群中所有区域的工作节点都少于 50 个,则指定 0 以路由到区域中的所有工作节点。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-security-group
1.30 及更高版本。
可选。 要添加到 VPC 负载平衡器的客户管理安全组。 如果您不想使用 IBM 管理的安全组,请指定您拥有和管理的安全组。 该选项删除 IBM-managed 安全组,代之以你指定的安全组。 从现有负载平衡器中删除注释后,您添加的安全组就会替换为 IBM-managed 安全组。 您可以随时添加或删除此注释。 您有责任管理您的安全组并保持更新。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-allow-outbound-traffic
适用于运行“默认安全”的群集。 注释,为与您指定的外部端口相关联的 ALB 的每个 IP 地址创建安全组。 这些规则在群集安全组中创建。 用逗号分隔的列表指定有效的外部端口,如 80,443。 在本例中,如果与每个外部端口值相关联的每个公共 ALB 有两个 IP 地址,则每个 IP 地址创建一条出站规则,总共创建 4 条新规则。 您可以随时添加或删除此注释。
selector
您在应用部署 YAML 文件的 spec.template.metadata.labels 部分中使用的标签键(<selector_key> )和标签值(<selector_value> )。 此定制标签可标识运行您的应用程序的所有 pod,以便在负载均衡中包含这些 pod。
port
服务侦听的端口。
targetPort
可选:服务将流量转发到的端口。 在 Pod 中运行的应用程序必须监听该目标端口上的传入 TCP 流量。 目标端口通常在应用程序 pod 中运行的映像中静态定义。 pod 中配置的目标端口与服务的节点端口不同,也可能与 VPC LB 上配置的外部端口不同。