IBM Cloud Docs
建立一个 Network Load Balancer for VPC

建立一个 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. 确保您拥有 WriterManager IBM Cloud IAM 服务访问角色,用于为 VPC NLB 部署 Kubernetes LoadBalancer 服务的命名空间。
  2. 登录您的账户。 如果适用,请将相应的资源组设定为目标。 设置集群的上下文。
  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/16172.18.0.0/16172.19.0.0/16172.20.0.0/16。 配置子网后,请注意其 ID
    2. 如果通过 VPC NLB 连接到应用程序的客户端存在于专用 VPC 子网的 VPC 和区域之外,您必须 创建自定义入口路由表。 有关详细信息,请参阅 已知限制关于路由表和路由 中的表格。 为自定义入口路由表选择以下 流量源之一:对于来自内部网络的流量,请选择直接链接。 对于来自其他 VPC 或传统基础架构的流量,请选择 Transit gateway。 对于来自同一 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 服务。

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

    在 VPC 中配置 VPC NLB 只需几分钟时间。 Kubernetes LoadBalancer 服务的外部 IP 地址可能是 pending 直到 VPC NLB 完全调配。

    kubectl describe svc myloadbalancer -n <namespace>
    

    公共 LoadBalancer 服务的 CLI 输出示例:

    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.
    
  5. 验证是否已在 VPC 中成功创建 VPC NLB。 在输出中,验证 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
    
  6. 访问在步骤 4 中找到的 Kubernetes LoadBalancer 服务的 IP 地址,以及格式为 <external_IP>:<app_port> 的应用程序端口。

  7. 可选:重复上述步骤,在每个要公开应用程序的区域部署公共 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. 创建服务。

    kubectl 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 服务。

    kubectl 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 地址。

    kubectl 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 ks 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 ks 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 ks subnets --provider vpc-gen2 --vpc-id <vpc> --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 负载平衡器资源上设置健康检查协议。 可用选项为 httphttpstcp。 通常,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 端口。
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"
1.30 或更高版本。
使用指定的 Ingress domain 注册负载平衡器的 IP 地址。 如果指定的域不存在,则会创建一个使用内部 IBM 托管提供程序 (akamai)的域。要创建新域,名称必须在所有现有域(不仅是群集中的域)中唯一。 删除负载平衡器服务会从域中删除 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 管理的安全组,并替换为您指定的安全组。 从现有负载平衡器中删除注释后,您添加的安全组将替换为 IBM 管理的安全组。 您可以随时添加或删除此注释。 您有责任管理您的安全组并保持更新。
service.kubernetes.io/ibm-load-balancer-cloud-provider-vpc-allow-outbound-traffic
适用于运行 Secure by Default 的群集。 注释,为与您指定的外部端口相关联的 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 上配置的外部端口不同。