設定外部應用程式負載平衡器的 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 叢集中,您無法停用這個外掛程式。

您可以使用 Trusted Cloud 控制台或 Google Cloud CLI 啟用 HttpLoadBalancing 外掛程式。

控制台

  1. 前往 Trusted Cloud 控制台的「Google Kubernetes Engine」頁面。

    前往「Google Kubernetes Engine」

  2. 按一下您要修改的叢集名稱。

  3. 在「Networking」(網路) 下方的「HTTP Load Balancing」(HTTP 負載平衡) 欄位中,按一下「Edit HTTP Load Balancing」(編輯 HTTP 負載平衡)

  4. 勾選「啟用 HTTP 負載平衡」核取方塊。

  5. 按一下 [儲存變更]。

gcloud

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

CLUSTER_NAME 替換為叢集名稱。

建立靜態 IP 位址

外部應用程式負載平衡器提供穩定的 IP 位址,用來將要求轉送到一或多個服務。如要使用永久 IP 位址,請先保留全域靜態外部 IP 位址,再建立 Ingress。

如果您修改現有 Ingress,改為使用靜態 IP 位址而非臨時 IP 位址,GKE 重新建立負載平衡器的轉送規則時,可能會變更負載平衡器的 IP 位址。

建立外部應用程式負載平衡器

在本練習中,您將設定外部應用程式負載平衡器,根據網址路徑將要求轉送至不同的服務。

建立 Deployment 和服務

建立兩個 Deployment 物件,並將 Service 命名為 hello-world-1hello-world-2

  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"
    

    這個資訊清單說明含有三個備用資源的範例部署。

  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 的成員。
    • 當要求傳送至 TCP 通訊埠 60000 上的 Service 時,GKE 會將其轉送至 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"
    

    這個資訊清單說明含有三個備用資源的範例部署。

  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 的成員。
    • 當要求傳送至 TCP 通訊埠 80 上的 Service 時,GKE 會將其轉送至 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 類別會部署內部應用程式負載平衡器

    • 部署 Ingress 資源時,如果沒有 spec.ingressClassNamekubernetes.io/ingress.class 註解,GKE 會建立外部應用程式負載平衡器。如果您指定 kubernetes.io/ingress.class: gce 註解,也會發生相同行為。詳情請參閱「GKE Ingress 控制器行為」。

    • GKE 會為每個 backend.service 建立Trusted Cloud 後端服務。每個後端服務都對應至 Kubernetes 服務,且每個後端服務都必須參照Trusted Cloud 健康狀態檢查。這項健康狀態檢查與 Kubernetes 執行中或已就緒探測器不同,因為健康狀態檢查是在叢集外部實作。詳情請參閱健康狀態檢查

    • 當用戶端傳送要求至網址路徑為 / 的負載平衡器時,GKE 會將要求轉送至通訊埠 60000 上的 hello-world-1 Service。當用戶端使用網址路徑 /v2 向負載平衡器發送要求時,GKE 會將要求轉送至通訊埠 80 上的 hello-world-2 Service。如要進一步瞭解 pathpathType 屬性,請參閱「網址路徑」。

  2. 將資訊清單套用至叢集:

    kubectl apply -f my-ingress.yaml
    

測試外部應用程式負載平衡器

請稍候大約五分鐘,讓負載平衡器進行設定,然後測試外部應用程式負載平衡器:

  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 的運作方式

外部應用程式負載平衡器是用戶端與應用程式間的 Proxy。如果要接受來自用戶端的 HTTPS 要求,負載平衡器必須要有憑證,以向用戶端證明其身分。 負載平衡器還必須要有私密金鑰才能完成 HTTPS 握手。 如需詳細資訊,請參閱:

網址路徑

Ingress 的 path 欄位僅支援 * 字元做為萬用字元。* 字元必須在正斜線 (/) 之後,並且必須是模式中的最後一個字元。例如,/*/foo/*/foo/bar/* 是有效模式,但 */foo/bar*/foo/*/bar 則不是。

較明確的模式會優先於較不明確的模式。如果您同時有 /foo/*/foo/bar/*,系統會使用 /foo/bar/bat 來比對 /foo/bar/*。如要進一步瞭解路徑限制和模式比對,請參閱網址對應說明文件

如果 GKE 叢集執行的版本早於 1.21.3-gke.1600,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。詳情請參閱用於與 Ingress 進行負載平衡的 HTTP/2 一文。

網路端點群組

如果叢集支援容器原生負載平衡,建議使用網路端點群組 (NEG)。對於 1.17 以上版本的 GKE 叢集,以及符合特定條件的叢集,系統會預設使用容器原生負載平衡,且不需要明確的 cloud.google.com/neg: '{"ingress": true}' 服務註解。

共用虛擬私有雲

如果您要部署 Ingress 資源的 GKE 叢集位於服務專案中,且希望 GKE 控制平面管理主專案中的防火牆資源,則必須按照「管理共用 VPC 叢集的防火牆資源」一文所述,在主專案中授予服務專案的 GKE 服務帳戶適當的 IAM 權限。這可讓 Ingress 控制器建立防火牆規則,允許輸入流量和 Trusted Cloud 健康狀態檢查流量。

以下是 Ingress 資源記錄中可能出現的事件範例。如果權限設定不正確,Ingress 控制器就無法建立防火牆規則,允許 Trusted Cloud 健康狀態檢查的 Ingress 流量,因此會發生這個錯誤。

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 使用此註解自訂負載平衡器的用戶端設定。詳情請參閱輸入設定
networking.gke.io/suppress-firewall-xpn-error 至於 Ingress 負載平衡器,如果 Kubernetes 因權限不足而無法變更防火牆規則,則每幾分鐘就會建立一次 firewallXPNError 事件。在 GLBC 1.4 以上版本中,可以將 firewallXPNError 事件設為忽略項目,方法是將 networking.gke.io/suppress-firewall-xpn-error: "true" 註解新增到輸入資源。移除該註解即可取消設為忽略項目。可能的值為 truefalse。 預設值為 false
註解 說明
cloud.google.com/app-protocols 使用此註解可設定負載平衡器與應用程式之間的通訊協定。可能的通訊協定為 HTTP、HTTPS 和 HTTP2。 請參閱「負載平衡器與您應用程式之間的 HTTPS」和「用於與 Ingress 進行負載平衡的 HTTP/2」。
cloud.google.com/backend-config 使用此註解設定與服務相關聯的後端服務。詳情請參閱輸入設定
cloud.google.com/neg 使用此註解指定負載平衡器應使用網路端點群組。請參閱「使用容器原生負載平衡功能」。

後續步驟