创建基于后端服务的外部负载均衡器


本页面介绍了如何部署外部 LoadBalancer Service,以构建基于后端服务的外部直通式网络负载均衡器。在阅读本页面之前,请确保您熟悉以下内容:

如需详细了解外部直通式网络负载均衡器,请参阅基于后端服务的外部直通式网络负载均衡器

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

要求

  • 如需创建使用基于后端服务的外部直通式网络负载均衡器的外部 LoadBalancer Service,GKE 集群必须使用 1.25.5 版或更高版本。如需使用加权负载均衡,集群必须使用 1.31.0-gke.1506000 版或更高版本。

  • 您必须在集群中启用 HttpLoadBalancing 插件。默认情况下,此插件处于启用状态。它允许集群管理使用后端服务的负载均衡器。

选择集群

您可以创建新集群,也可以选择符合要求的现有集群。

创建新集群

Autopilot

如需创建新的 Autopilot 集群,请运行以下命令:

gcloud container clusters create-auto CLUSTER_NAME \
    --release-channel=RELEASE_CHANNEL \
    --cluster-version=VERSION \
    --location=COMPUTE_LOCATION

替换以下内容:

  • CLUSTER_NAME:新集群的名称。
  • RELEASE_CHANNEL:集群的 GKE 发布渠道的名称。
  • VERSION:集群的 GKE 版本。
  • COMPUTE_LOCATION:集群的 Compute Engine 区域

如需为 LoadBalancer Service 停用自动 VPC 防火墙规则创建功能,请添加 --disable-l4-lb-firewall-reconciliation 标志。如需了解详情,请参阅 GKE LoadBalancer Service 的用户管理防火墙规则

Standard

如需创建新的 Standard 集群,请运行以下命令:

gcloud container clusters create CLUSTER_NAME \
    --release-channel=RELEASE_CHANNEL \
    --cluster-version=VERSION \
    --location=COMPUTE_LOCATION

替换以下内容:

  • CLUSTER_NAME:新集群的名称。
  • RELEASE_CHANNEL:集群的 GKE 发布渠道的名称。
  • VERSION:集群的 GKE 版本。
  • COMPUTE_LOCATION:集群的 Compute Engine 区域

如需为 LoadBalancer Service 停用自动 VPC 防火墙规则创建功能,请添加 --disable-l4-lb-firewall-reconciliation 标志。如需了解详情,请参阅适用于 GKE LoadBalancer Service 的用户管理防火墙规则

升级现有集群

使用 gcloud CLI 更新现有集群:

gcloud container clusters upgrade CLUSTER_NAME \
    --cluster-version=VERSION \
    --master \
    --location=COMPUTE_LOCATION

替换以下内容:

如需为 LoadBalancer Service 停用自动 VPC 防火墙规则创建功能,请添加 --disable-l4-lb-firewall-reconciliation 标志。如需了解详情,请参阅适用于 GKE LoadBalancer Service 的用户管理防火墙规则

部署示例工作负载

部署以下示例工作负载,以便为外部 LoadBalancer Service 提供服务 Pod。

  1. 将以下示例 Deployment 保存为 store-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store
    spec:
      replicas: 20
      selector:
        matchLabels:
          app: store
      template:
        metadata:
          labels:
            app: store
        spec:
          containers:
          - image: gcr.io/google_containers/echoserver:1.10
            imagePullPolicy: Always
            name: echoserver
            ports:
              - name: http
                containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
                scheme: HTTP
    
  2. 将清单应用于集群:

    kubectl apply -f store-deployment.yaml
    
  3. 验证该 Deployment 是否有 20 个服务 Pod:

    kubectl get pods
    

    输出类似于以下内容:

    NAME                     READY   STATUS    RESTARTS   AGE
    store-cdb9bb4d6-s25vw      1/1     Running   0          10s
    store-cdb9bb4d6-vck6s      1/1     Running   0          10s
    ....
    

创建外部 LoadBalancer 服务

  1. 通过创建外部 LoadBalancer Service 来公开示例工作负载。

    1. 将以下服务清单保存为 store-v1-lb-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: store-v1-lb-svc
        annotations:
          cloud.google.com/l4-rbs: "enabled"
      spec:
        type: LoadBalancer
        selector:
          app: store
        ports:
        - name: tcp-port
          protocol: TCP
          port: 8080
          targetPort: 8080
      
    2. 将清单应用于集群:

      kubectl apply -f store-v1-lb-svc.yaml
      

    请注意以下有关此示例清单的事项:

    • 在 Service 清单首次应用于集群时,该清单必须包含 cloud.google.com/l4-rbs: "enabled" 注解。这会指示 GKE 创建基于后端服务的外部直通式网络负载均衡器。基于后端服务的外部直通式网络负载均衡器必须支持 IPv6 和加权负载均衡等功能。

    • 如果您将 cloud.google.com/l4-rbs: "enabled" 注解添加到现有的外部 LoadBalancer Service 的清单中(即在创建负载均衡器后),则 GKE 会忽略该注解。在清单中未添加此注解的情况下创建的外部 LoadBalancer Service 使用基于目标池的外部直通式网络负载均衡器。不建议使用基于目标池的外部直通式网络负载均衡器。

启用加权负载均衡

如需根据每个节点上存在的服务 Pod、准备就绪 Pod 和未终止 Pod 的数量按比例向节点分配新连接,请通过将 networking.gke.io/weighted-load-balancing: "pods-per-node" 注解添加到 Service 清单中来启用加权负载均衡。

  1. networking.gke.io/weighted-load-balancing: "pods-per-node" 注解添加到 store-v1-lb-svc.yaml Service 清单中,并确保您也设置了 externalTrafficPolicy: Local,使其如下所示:

    apiVersion: v1
    kind: Service
    metadata:
      name: store-v1-lb-svc
      annotations:
        cloud.google.com/l4-rbs: "enabled"
        networking.gke.io/weighted-load-balancing: "pods-per-node"
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local
      selector:
        app: store
      ports:
      - name: tcp-port
        protocol: TCP
        port: 8080
        targetPort: 8080
    
  2. 将清单应用于集群:

    kubectl apply -f store-v1-lb-svc.yaml
    

请注意以下有关加权负载均衡的示例:

  • Service 清单使用 externalTrafficPolicy: Local。如果您不需要启用加权负载均衡,则也可以使用 externalTrafficPolicy: Cluster。如需详细了解 externalTrafficPolicy 如何定义节点分组、有哪些节点通过了其负载均衡器健康检查以及数据包的处理方式,请参阅 LoadBalancer Service 概念

  • 如果您启用了加权负载均衡,GKE 不会阻止您使用 externalTrafficPolicy: Cluster,但 externalTrafficPolicy: Cluster 会有效地停用加权负载均衡,因为数据包可能会在负载均衡器之后路由到其他节点。

您还可以使用 kubectl edit svc service-name 在现有的外部 LoadBalancer Service 上启用加权负载均衡。kubectl edit 命令会在您配置的文本编辑器中打开现有负载均衡器的 Service 清单,您可以在其中修改清单并保存更改。修改现有的外部 LoadBalancer Service 时,请注意以下几点:

  • 现有的外部 LoadBalancer Service 必须已创建基于后端服务的外部直通式网络负载均衡器。这意味着,在首次将清单应用于集群时,现有的外部 LoadBalancer Service 必须已包含 cloud.google.com/l4-rbs: "enabled" 注解。

    networking.gke.io/weighted-load-balancing: "pods-per-node" 注解添加到使用基于目标池的外部直通式网络负载均衡器的现有外部 LoadBalancer Service 不会产生任何影响。

  • 更新现有的外部 LoadBalancer Service 清单时,请务必设置 externalTrafficPolicy: Local。使用 externalTrafficPolicy: Cluster 会有效地停用加权负载均衡,因为数据包可能会在负载均衡器之后路由到其他节点。

停用加权负载均衡

如需向节点分配新连接(无论每个节点上有多少个服务 Pod),请从 Service 清单中移除 networking.gke.io/weighted-load-balancing: "pods-per-node" 注解,以停用加权负载均衡。

验证外部 LoadBalancer 服务及其组件

  1. 验证您的服务是否正在运行:

    kubectl get svc store-v1-lb-svc
    

    输出类似于以下内容:

    NAME               TYPE           CLUSTER-IP        EXTERNAL-IP     PORT(S)          AGE
    store-v1-lb-svc   LoadBalancer   10.44.196.160     35.193.28.231   8080:32466/TCP   11m
    

    GKE 为外部直通网络负载均衡器分配了一个 EXTERNAL_IP

  2. 测试与负载均衡器之间的连接:

    curl EXTERNAL_IP:PORT
    

    替换以下内容:

    • EXTERNAL_IP:为外部直通式网络负载均衡器分配的 IP 地址。
    • PORT:为外部直通网络负载均衡器分配的端口号。

    输出类似于以下内容:

    Hostname: store-v1-lb-svc-cdb9bb4d6-hflxd
    
    Pod Information:
      -no pod information available-
    
    Server values:
      server_version=nginx: 1.13.3 - lua: 10008
    
    Request Information:
      client_address=10.128.0.50
      method=GET
      real path=/
      query=
      request_version=1.1
      request_scheme=http
      request_uri=EXTERNAL_IP
    
    Request Headers:
      accept=*/*
      host=EXTERNAL_IP
      user-agent=curl/7.81.0
    
    Request Body:
      -no body in request-
    
    
  3. 检查 LoadBalancer Service 以及描述其Google Cloud 资源的一组注解:

    kubectl describe svc store-v1-lb-svc
    

    输出类似于以下内容:

    Name:                     my-service-external
    Namespace:                default
    Labels:                   <none>
    Annotations:              cloud.google.com/l4-rbs: enabled
                              networking.gke.io/weighted-load-balancing: pods-per-node #This annotation appears in the output only if weighted load balancing is enabled.
                              service.kubernetes.io/backend-service: k8s2-qvveq1d8-default-my-service-ext-5s55db85
                              service.kubernetes.io/firewall-rule: k8s2-qvveq1d8-default-my-service-ext-5s55db85
                              service.kubernetes.io/firewall-rule-for-hc: k8s2-qvveq1d8-default-my-service-ext-5s55db85-fw
                              service.kubernetes.io/healthcheck: k8s2-qvveq1d8-default-my-service-ext-5s55db85
                              service.kubernetes.io/tcp-forwarding-rule: a808124abf8ce406ca51ab3d4e7d0b7d
    Selector:                 app=my-app
    Type:                     LoadBalancer
    IP Family Policy:         SingleStack
    IP Families:              IPv4
    IP:                       10.18.102.23
    IPs:                      10.18.102.23
    LoadBalancer Ingress:     35.184.160.229
    Port:                     tcp-port  8080/TCP
    TargetPort:               8080/TCP
    NodePort:                 tcp-port  31864/TCP
    Endpoints:                10.20.1.28:8080,10.20.1.29:8080
    Session Affinity:         None
    External Traffic Policy:  Local
    HealthCheck NodePort:     30394
    
    Events:
      Type    Reason                Age                    From                     Message
      ----    ------                ----                   ----                     -------
      Normal  ADD                   4m55s                  loadbalancer-controller  default/my-service-ext
    

    有几个字段表明已成功创建基于后端服务的外部直通式网络负载均衡器及其 Google Cloud 资源:

    • Events 字段。如果 LoadBalancer 服务及其资源创建成功,则该字段为空。如果发生错误,则会在该字段列出。
    • 已启用 Annotations 的列表:GKE 会将以下只读注解的列表添加到 Service 清单中。名称以 service.kubernetes.io/ 开头的每个注解都用于指示作为负载均衡器的一部分创建或为了支持负载均衡器而创建的Google Cloud 资源的名称。

      • networking.gke.io/weighted-load-balancing: pods-per-node 注解指示已应用加权负载均衡,并且负载均衡器会根据每个节点上运行的 Pod 数量将流量分配到后端 Pod。
      • service.kubernetes.io/backend-service 注解指示负载均衡器的后端服务的名称。
      • service.kubernetes.io/healthcheck 注解指示后端服务使用的负载均衡器健康检查的名称。
      • service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule 注解指示负载均衡器的转发规则的名称。
      • service.kubernetes.io/firewall-rule 注释指示为允许流向集群节点的流量而创建的防火墙规则的名称。 此防火墙规则的来源范围可使用 spec.loadBalancerSourceRanges[] 进行自定义。如需详细了解 LoadBalancer Service 的防火墙规则,请参阅防火墙规则和来源 IP 地址许可名单
      • service.kubernetes.io/firewall-rule-for-hc 注解指示负载均衡器健康检查所需的防火墙规则的名称。
  4. 验证是否已为外部 LoadBalancer Service 创建负载均衡器资源和防火墙规则:

    • 如需查看转发规则,请运行以下命令:

        gcloud compute forwarding-rules describe FWD_RULE_NAME \
          --region=REGION_NAME
      

      替换以下内容:

      • FWD_RULE_NAME:由 service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule 只读注解提供的转发规则名称。如需查看这些注解,请运行 kubectl describe svc SERVICE_NAME
      • REGION_NAME:包含集群的 Google Cloud 区域。对于可用区级集群,该区域包含集群使用的可用区。
    • 如需查看后端服务,请运行以下命令:

      gcloud compute backend-services describe BACKEND_SERVICE_NAME \
        --region=REGION_NAME
      

      替换以下内容:

      • BACKEND_SERVICE_NAME:由 service.kubernetes.io/backend-service 只读注解提供的后端服务的名称。如需查看此只读注释,请运行 kubectl describe svc SERVICE_NAME
      • REGION_NAME:包含集群的 Google Cloud 区域。对于可用区级集群,该区域包含集群使用的可用区。
    • 如需查看负载均衡器健康检查,请运行以下命令:

      gcloud compute health-checks describe HEALTH_CHECK_NAME \
        --region=REGION_NAME
      

      替换以下内容:

      • HEALTH_CHECK_NAME:负载均衡器健康检查的名称。健康检查的名称由 service.kubernetes.io/healthcheck 只读注解提供。如需查看此只读注解,请运行 kubectl describe svc SERVICE_NAME
      • REGION_NAME:包含集群的 Google Cloud 区域。对于可用区级集群,该区域包含集群使用的可用区。
    • 如需查看防火墙规则,请运行以下命令:

      gcloud compute firewall-rules describe FIREWALL_RULE_NAME \
      gcloud compute firewall-rules describe HEALTH_CHECK_FIREWALL_RULE_NAME
      

      替换以下内容:

      • FIREWALL_RULE_NAME:允许流量流向负载均衡器的防火墙规则的名称。此防火墙规则的名称由 service.kubernetes.io/firewall-rule 只读注解提供。如需查看此只读注释,请运行 kubectl describe svc SERVICE_NAME
      • HEALTH_CHECK_FIREWALL_RULE_NAME:允许对负载均衡器后端(集群节点)进行健康检查的防火墙规则的名称。此防火墙规则的名称由 service.kubernetes.io/firewall-rule-for-hc 只读注解提供。如需查看此只读注解,请运行 kubectl describe svc SERVICE_NAME

删除外部 LoadBalancer Service

如需删除示例 store-v1-lb-svc 外部 LoadBalancer Service,请使用以下命令:

kubectl delete service store-v1-lb-svc

GKE 会自动移除为外部 LoadBalancer Service 创建的所有负载均衡器资源。

问题排查

本部分介绍了您在配置加权负载均衡时可能遇到的问题。

加权负载均衡的外部流量政策有误

如果您在启用加权负载均衡时未设置 externalTrafficPolicy: Local,则在使用以下命令描述 Service 时,您可能会收到警告事件:

kubectl describe svc store-v1-lb-svc`
Events:
  Type     Reason                   Age      From                     Message
  ----     ------                   ----     ----                     -------
  Warning  UnsupportedConfiguration 4m55s    loadbalancer-controller  Weighted load balancing by pods-per-node has no effect with External Traffic Policy: Cluster.

如需有效地启用加权负载均衡,您必须设置 externalTrafficPolicy: Local

后续步骤