配置适用于外部应用负载均衡器的 Ingress


本页面介绍如何通过创建 Kubernetes Ingress 对象来配置外部应用负载均衡器

在阅读本页内容之前,您应该先熟悉 GKE 网络概念

准备工作

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

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

启用 HttpLoadBalancing 插件

集群必须启用 HttpLoadBalancing 插件。默认情况下,此插件处于启用状态。在 Autopilot 集群中,您无法停用此插件。

您可以使用 Google Cloud 控制台或 Google Cloud CLI 启用 HttpLoadBalancing 插件。

控制台

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 点击要修改的集群的名称。

  3. 网络下的 HTTP 负载均衡字段中,点击 修改 HTTP 负载均衡

  4. 选中启用 HTTP 负载均衡复选框。

  5. 点击保存更改

gcloud

gcloud container clusters update CLUSTER_NAME --update-addons=HttpLoadBalancing=ENABLED

CLUSTER_NAME 替换为您的集群名称。

创建静态 IP 地址

外部应用负载均衡器提供一个稳定的 IP 地址,您可以使用该 IP 地址将请求路由到一个或多个 Service。如果您需要永久的 IP 地址,则必须在创建 Ingress 之前预留一个全球静态外部 IP 地址

如果您修改现有 Ingress 以使用静态 IP 地址而不是临时 IP 地址,则 GKE 可能会在重新创建负载均衡器的转发规则时更改负载均衡器的 IP 地址。

创建外部应用负载均衡器

在本练习中,您将配置外部应用负载均衡器,以根据网址路径将请求路由到不同的 Service。


如需在 Google Cloud 控制台中直接遵循有关此任务的分步指导,请点击操作演示

操作演示


创建 Deployment 和 Service

使用名为 hello-world-1hello-world-2 的 Service 创建两个 Deployment:

  1. 将以下清单保存为 hello-world-deployment-1.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-world-deployment-1
    spec:
      selector:
        matchLabels:
          greeting: hello
          version: one
      replicas: 3
      template:
        metadata:
          labels:
            greeting: hello
            version: one
        spec:
          containers:
          - name: hello-app-1
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0"
            env:
            - name: "PORT"
              value: "50000"
    

    此清单描述了一个包含三个副本的示例 Deployment。

  2. 将清单应用于集群:

    kubectl apply -f hello-world-deployment-1.yaml
    
  3. 将以下清单保存为 hello-world-service-1.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-world-1
    spec:
      type: NodePort
      selector:
        greeting: hello
        version: one
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50000
    

    此清单描述了具有以下属性的 Service:

    • 同时具有 greeting: hello 标签和 version: one 标签的任何 Pod 都是 Service 的成员。
    • GKE 会将发送到 TCP 端口 60000 上的 Service 的请求转发到 TCP 端口 50000 上的其中一个成员 Pod。
    • Service 类型为 NodePort,除非您使用容器原生负载均衡功能,否则必须使用该类型。如果使用容器原生负载均衡功能,则服务类型不存在限制。建议使用 type: ClusterIP
  4. 将清单应用于集群:

    kubectl apply -f hello-world-service-1.yaml
    
  5. 将以下清单保存为 hello-world-deployment-2.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-world-deployment-2
    spec:
      selector:
        matchLabels:
          greeting: hello
          version: two
      replicas: 3
      template:
        metadata:
          labels:
            greeting: hello
            version: two
        spec:
          containers:
          - name: hello-app-2
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
            env:
            - name: "PORT"
              value: "8080"
    

    此清单描述了一个包含三个副本的示例 Deployment。

  6. 将清单应用于集群:

    kubectl apply -f hello-world-deployment-2.yaml
    
  7. 将以下清单保存为 hello-world-service-2.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-world-2
    spec:
      type: NodePort
      selector:
        greeting: hello
        version: two
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
    

    此清单描述了具有以下属性的 Service:

    • 同时具有 greeting: hello 标签和 version: two 标签的任何 Pod 都是 Service 的成员。
    • GKE 会将发送到 TCP 端口 80 上的 Service 的请求转发到 TCP 端口 8080 上的其中一个成员 Pod。
  8. 将清单应用于集群:

    kubectl apply -f hello-world-service-2.yaml
    

创建 Ingress

创建一个 Ingress,指定根据请求中的网址路径路由请求的规则。当您创建 Ingress 时,GKE Ingress 控制器会创建并配置外部应用负载均衡器。

  1. 将以下清单保存为 my-ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-ingress
      annotations:
        # If the class annotation is not specified it defaults to "gce".
        kubernetes.io/ingress.class: "gce"
    spec:
      rules:
      - http:
          paths:
          - path: /*
            pathType: ImplementationSpecific
            backend:
              service:
                name: hello-world-1
                port:
                  number: 60000
          - path: /v2
            pathType: ImplementationSpecific
            backend:
              service:
                name: hello-world-2
                port:
                  number: 80
    

    此清单描述了具有以下属性的 Ingress:

    • 有两个 GKE Ingress 类。指定 Ingress 类必须使用 kubernetes.io/ingress.class 注解。您不能使用 spec.ingressClassName 指定 GKE Ingress。

    • gce 类会部署外部应用负载均衡器

    • gce-internal 类会部署内部应用负载均衡器

    • 当您部署不带注解 spec.ingressClassNamekubernetes.io/ingress.class 的 Ingress 资源时,GKE 会创建一个外部应用负载均衡器。这与指定 kubernetes.io/ingress.class: gce 注解时发生的行为相同。如需了解详情,请参阅 GKE Ingress 控制器行为

    • GKE 会为每个 backend.service 创建一个 Google Cloud 后端 Service

    • 当客户端将请求发送到网址路径为 / 的负载均衡器时,GKE 会将请求转发到端口 60000 上的 hello-world-1 Service。当客户端将请求发送到网址路径为 /v2 的负载均衡器时,GKE 会将请求转发到端口 80 上的 hello-world-2 Service。如需详细了解 pathpathType 属性,请参阅网址路径

  2. 将清单应用于集群:

    kubectl apply -f my-ingress.yaml
    

测试外部应用负载均衡器

请等待 5 分钟,让负载均衡器完成配置,然后测试外部应用负载均衡器:

  1. 查看 Ingress:

    kubectl get ingress my-ingress --output yaml
    

    输出结果会显示外部应用负载均衡器的 IP 地址:

    status:
      loadBalancer:
        ingress:
        - ip: 203.0.113.1
    
  2. 测试 / 路径:

    curl LOAD_BALANCER_IP_ADDRESS/
    

    LOAD_BALANCER_IP_ADDRESS 替换为负载均衡器的外部 IP 地址。

    输出类似于以下内容:

    Hello, world!
    Version: 1.0.0
    Hostname: ...
    

    如果输出包含 404 错误,请等待几分钟。

  3. 测试 /v2 路径:

    curl load-balancer-ip/v2
    

    输出类似于以下内容:

    Hello, world!
    Version: 2.0.0
    Hostname: ...
    

适用于外部负载均衡的 Ingress 的工作原理

外部应用负载均衡器充当您的客户端和应用之间的代理。如果您想要接受来自客户端的 HTTPS 请求,则负载均衡器必须具有证书,这样才能向客户端证明其身份。 负载均衡器还必须具有私钥才能完成 HTTPS 握手。 有关详情,请参阅:

网址路径

Ingress 的 path 字段唯一支持的通配符是 * 字符。* 字符必须紧跟在正斜线 (/) 之后,并且必须是格式中的最后一个字符。例如,/*/foo/*/foo/bar/* 是有效格式,但 */foo/bar*/foo/*/bar 不是有效格式。

较具体的格式优先于不太具体的格式。如果您同时拥有 /foo/*/foo/bar/*,则选择 /foo/bar/bat 来匹配 /foo/bar/*。 如需详细了解路径限制和格式匹配,请参阅网址映射文档

对于运行低于 1.21.3-gke.1600 的版本的 GKE 集群,pathType 字段唯一支持的值为 ImplementationSpecific。对于运行 1.21.3-gke.1600 版或更高版本的集群,pathType 还支持 PrefixExact 值。

停用 HTTP

如果希望客户端和负载均衡器之间的所有流量都使用 HTTPS,则可以停用 HTTP。如需了解详情,请参阅停用 HTTP

负载均衡器和应用之间的 HTTPS

如果在 GKE Pod 中运行的应用能够接收 HTTPS 请求,您可以将负载均衡器配置成使用 HTTPS 将请求转发给应用。如需了解详情,请参阅负载均衡器和应用之间的 HTTPS (TLS)

客户端和负载均衡器之间的 HTTP/2

客户端可以使用 HTTP/2 向负载均衡器发送请求。无需配置。

负载均衡器和应用之间的 HTTP/2

如果在 GKE Pod 中运行的应用能够接收 HTTP/2 请求,则可以将负载均衡器配置为在将请求转发给应用时使用 HTTP/2。如需了解详情,请参阅 HTTP/2 与 Ingress 搭配使用实现负载均衡

网络端点组

如果您的集群支持容器原生负载均衡,则建议使用网络端点组 (NEG)。对于 GKE 集群 1.17 和更高版本,以及在特定条件下,容器原生负载均衡是默认负载均衡,不需要明确的 cloud.google.com/neg: '{"ingress": true}' Service 注释。

共享 VPC

如果要在其中部署 Ingress 资源的 GKE 集群位于某个服务项目中,并且您希望由 GKE 控制层面来管理宿主项目中的防火墙资源,则必须按照为具有共享 VPC 的集群管理防火墙资源中的要求,为该服务项目的 GKE 服务账号在宿主项目中授予适当的 IAM 权限。这样,Ingress 控制器便可创建防火墙规则,允许用于 Google Cloud 健康检查的入站流量及普通流量。

以下是 Ingress 资源日志中可能存在的事件示例。如果 Ingress 控制器由于未正确配置权限而无法创建防火墙规则来允许用于 Google Cloud 健康检查的入站流量,则会发生此错误。

Firewall change required by security admin: `gcloud compute firewall-rules update <RULE_NAME> --description "GCE L7 firewall rule" --allow tcp:<PORT> --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags <TARGET_TAG> --project <HOST_PROJECT>

如果您希望从宿主项目手动预配防火墙规则,则可以将 networking.gke.io/suppress-firewall-xpn-error: "true" 注释添加到 Ingress 资源,以忽略 firewallXPNError 事件。

外部 Ingress 注释摘要

Ingress 注释

注解 说明
kubernetes.io/ingress.allow-http 指定是否允许客户端与 HTTP(S) 负载均衡器之间的 HTTP 流量。可能的值为“true”和“false”。默认为“true”。 请参阅停用 HTTP
ingress.gcp.kubernetes.io/pre-shared-cert 使用此注释将证书资源附加到 GKE Ingress 资源。如需了解详情,请参阅将多个 SSL 证书与外部应用负载均衡器搭配使用
kubernetes.io/ingress.global-static-ip-name 使用此注释指定负载均衡器应使用先前创建的静态外部 IP 地址。请参阅 HTTP(S) 负载均衡器的静态 IP 地址
networking.gke.io/v1beta1.FrontendConfig 使用此注释可以自定义负载均衡器面向客户端的配置。如需了解详情,请参阅 Ingress 配置
networking.gke.io/suppress-firewall-xpn-error 对于 Ingress 负载均衡器,如果 Kubernetes 由于权限不足而无法更改防火墙规则,则系统会每隔几分钟创建一次 firewallXPNError 事件。在 GLBC 1.4 及更高版本中,您可以通过将 networking.gke.io/suppress-firewall-xpn-error: "true" 注释添加到 Ingress 资源,忽略 firewallXPNError 事件。您可以随时移除此注释以取消忽略。可能的值有 truefalse。默认值为 false
注解 说明
cloud.google.com/app-protocols 使用此注释可设置负载均衡器与应用之间的通信协议。可能的协议有 HTTP、HTTPS 和 HTTP2。 请参阅负载均衡器与应用之间的 HTTPS使用 Ingress 进行负载均衡的 HTTP/2
cloud.google.com/backend-config 使用此注解配置与 Service 关联的后端服务。如需了解详情,请参阅 Ingress 配置
cloud.google.com/neg 使用此注释指定负载均衡器应使用网络端点组。请参阅使用容器原生负载均衡

后续步骤