部署閘道

部署 Kubernetes Gateway 資源,管理外部流量如何到達單一 Google Kubernetes Engine (GKE) 叢集內的應用程式。設定 GKE Gateway 可讓您靈活且強大地控管輸入流量,提高應用程式的擴充性和可靠性。舉例來說,GKE Gateway 提供最佳化轉送和自動調度資源功能。這些功能對於低延遲線上提供至關重要,可確保使用者體驗流暢,同時協助控管成本。

如要在多個叢集或機群中部署閘道,請參閱「部署多叢集閘道」。如要瞭解跨命名空間轉送和 HTTP 流量拆分等特定閘道設定,請參閱閘道 API 使用手冊。

事前準備

開始之前,請確認您已執行下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 確認您已有 Autopilot 或 Standard 叢集。如要建立新叢集,請參閱「建立 Autopilot 叢集」。

  • 確認使用者帳戶具備 Certificate Manager 編輯者 (roles/certificatemanager.editor) 角色,以便建立必要的憑證對應組合。

GKE Gateway 控制器需求

  • Gateway API 僅支援 VPC 原生叢集。
  • 如果使用區域性或跨區域 GatewayClass,則必須啟用僅限 Proxy 的子網路。
  • 叢集必須啟用 HttpLoadBalancing 外掛程式。
  • 如果您使用 Istio,則必須將 Istio 升級至下列其中一個版本:
    • 1.15.2 以上版本
    • 1.14.5 以上版本
    • 1.13.9 以上版本。
  • 如果您使用 Shared VPC,則必須在主專案中,將 Compute Network User 角色指派給服務專案的 GKE 服務帳戶。

規定與限制

使用 GKE Gateway 時,請注意下列限制:

  • GKE GatewayClass 支援的功能會因使用的負載平衡器而異。如要進一步瞭解各 GatewayClass 支援的不同功能,請參閱「GatewayClass 功能」。

    最佳做法:

    為確保最佳效能,閘道數量上限為 100 個。超過這個上限可能會影響效能,或導致延遲時間增加。

  • GKE Gateway 僅支援 Gateway API 標準發布版本。

  • Autopilot 叢集一律會啟用 GKE Gateway。您無法在 Autopilot 叢集上安裝 Gateway API 實驗性發布管道 CRD。

  • 您無法使用 FrontendConfig 或 BackendConfig 設定閘道。您必須使用政策。

  • GKE Gateway 的行為與 Ingress 不同,因為 Gateway 不會推論健康狀態檢查參數。如果服務未針對 GET / 的要求傳回 200,或您有其他經過調整的 Pod 準備度檢查,則需要為服務設定 HealthCheckPolicy。

  • 您無法直接在主機名稱中指定通訊埠編號 (例如 web.example.com:80) 來轉送流量。

  • 您可以在 Google Cloud 控制台中查看 GKE 為閘道建立的負載平衡器資源,但這些資源不會參照其附加的閘道或 GKE 叢集。

  • 您無法透過閘道自動產生 Google 代管的 SSL 憑證,但可以手動建立及參照 Google 代管的 SSL 憑證。詳情請參閱「保護閘道」。

  • HTTPRoute 是唯一支援的路由類型。不支援 TCPRoute、UDPRoute 和 TLSRoute。如要查看 GKE Gateway 控制器支援的欄位清單,請參閱「GatewayClass 功能」。

  • 只有 GKE 1.27 以上版本,才支援透過閘道自訂要求和回應標頭,或透過閘道重新導向路徑和重寫網址。

  • 如果是含有閘道和路徑重新導向的自訂要求和回應標頭,以及含有閘道的網址重寫,則不支援 GatewayClass gke-l7-gxlb。

  • 設定 HTTPRoute 自訂要求標頭時,不支援Google Cloud 變數 origin_request_header。如要設定 CORS,可以使用 CORS 篩選器類型。

  • Google Cloud 傳統版應用程式負載平衡器的限制適用於 GKE Gateway。此外,您無法在後端服務中設定自訂 Host 回應標頭。

  • 路徑重新導向和網址重寫功能互斥,無法在相同規則中同時使用這兩種篩選器。

  • Cloud Load Balancing 不支援將流量重新導向至其他通訊埠。如要查看 GKE Gateway 控制器支援的欄位清單,請參閱「GatewayClass 功能」。

  • GKE Gateway 不支援萬用字元和動態網址。gke-l7-gxlb 和 gke-l7-gxlb-mc GatewayClass 不支援規則運算式。詳情請參閱「設定規則運算式比對」。

  • 如果您指定具有區域性外部閘道類別的閘道,控制器會佈建內部 IP 位址,而非外部位址。如要瞭解如何將具名位址與區域性外部應用程式負載平衡器搭配使用,請參閱「部署區域性外部閘道」。

  • Gateway 會使用獨立 NEG 佈建網路端點群組。為確保閘道控制器能正確協調負載平衡器設定,您無法修改閘道中 Service 的 cloud.google.com/neg 註解。

  • GKE Gateway 不支援參照 GKE Ingress 也參照的 Service。

  • 如果閘道設為佈建 IP 位址,則不支援變更 Gateway.spec.gatewayClass。為確保閘道控制器正確協調負載平衡器,請刪除現有閘道,並使用更新後的 gatewayClass 值重新部署資訊清單。

  • 系統不支援 networking.gke.io/app-protocols 註解。請改用 appProtocol 欄位,達到相同效果。

  • 如果您將 GKE Gateway 與 external-dns 搭配使用,且 Gateway 的健康狀態不良,則根據預設,與 Gateway 相關聯的所有 DNS 記錄都會從 DNS 區域中刪除。

    最佳做法:

    執行 external-dns 時,請設定 policy=upsert-only 旗標。這項設定有助於防止刪除現有的 DNS 記錄。

  • 如果從 GKE Gateway 透過路由參照的 Service 中移除通訊埠,您也必須更新 Service 上的獨立 NEG 註解,以移除該通訊埠。否則 NEG 控制器最終會停止同步處理這個 Service 的 Pod 端點。詳情請參閱「從 Service 移除通訊埠時,NEG 控制器會停止管理端點」。

  • 如果部署作業使用多叢集閘道 (MCG) 和可用區叢集,在叢集升級期間,服務可能會中斷。發生這個問題的原因是,當可用區叢集的控制層暫時無法使用時,舊版網路端點群組 (NEG) 探索機制可能會誤報後端數量為零。我們正在著手長期修正。為避免發生單點故障,請使用區域 GKE 叢集搭配 MCG。

在叢集中啟用 Gateway API

您必須先在叢集啟用 Gateway API,才能在 GKE 中使用閘道資源。

更新現有 GKE 叢集以啟用 Gateway API 前,請先確認符合最低需求,再繼續更新。

如要在現有的 GKE 叢集 (Autopilot 或 Standard) 啟用 Gateway API,請使用下列指令。這項作業最多可能需要 45 分鐘,叢集才能協調並安裝 CustomResourceDefinition。

gcloud container clusters update CLUSTER_NAME \
    --location=CLUSTER_LOCATION\
    --gateway-api=standard

更改下列內容:

--gateway-api=standard 旗標會指示 GKE 透過叢集安裝 Gateway API 標準管道的 CRD。

驗證叢集

建立或升級叢集後,GKE Gateway 控制器會自動安裝 GatewayClass。控制器可能需要幾分鐘才能辨識 CRD 並安裝 GatewayClasses。

  1. 確認 GKE 控制層已啟用 Gateway API:

    gcloud container clusters describe CLUSTER_NAME \
      --location=CLUSTER_LOCATION \
      --format json
    

    輸出結果大致如下。如果輸出內容空白,請重新執行叢集更新指令。

    "networkConfig": {
      ...
      "gatewayApiConfig": {
        "channel": "CHANNEL_STANDARD"
      },
      ...
    },
    
  2. 確認叢集已安裝 GatewayClasses:

    kubectl get gatewayclass
    

    輸出結果會與下列內容相似:

    NAME                             CONTROLLER                  ACCEPTED   AGE
    gke-l7-global-external-managed   networking.gke.io/gateway   True       16h
    gke-l7-regional-external-managed networking.gke.io/gateway   True       16h
    gke-l7-gxlb                      networking.gke.io/gateway   True       16h
    gke-l7-rilb                      networking.gke.io/gateway   True       16h
    

如要瞭解各個 GatewayClass 的功能,請參閱「GatewayClass 功能」。

系統只會自動安裝單一叢集 GatewayClass。如要安裝及使用多叢集 GatewayClass,進行內部和外部多叢集負載平衡,請參閱「啟用多叢集閘道」。

部署內部閘道

內部閘道會公開只能從虛擬私有雲或連線至虛擬私有雲的網路存取的應用程式。

部署區域性內部閘道

以下範例說明如何部署區域性內部閘道,在特定地理區域內的服務之間,實現高效且安全的通訊。

設定 Proxy 專用子網路

您必須先設定僅限 Proxy 的子網路,才能建立使用內部應用程式負載平衡器的閘道。在您使用內部應用程式負載平衡器的虛擬私有雲中,每個區域都必須有僅限 Proxy 子網路。這個子網路會為負載平衡器 Proxy 提供內部 IP 位址。

  1. 建立 Proxy 專用子網路:

    gcloud compute networks subnets create SUBNET_NAME \
        --purpose=REGIONAL_MANAGED_PROXY \
        --role=ACTIVE \
        --region=COMPUTE_REGION \
        --network=VPC_NETWORK_NAME \
        --range=CIDR_RANGE
    

    更改下列內容:

    • SUBNET_NAME:僅限 Proxy 的子網路名稱。
    • COMPUTE_REGION:僅限 Proxy 子網路的區域。
    • VPC_NETWORK_NAME:要在其中建立這個僅限 Proxy 子網路的虛擬私有雲網路名稱。請確認這個虛擬私有雲網路與 GKE 叢集和閘道部署位置相同。這項設定很重要,可確保負載平衡器與後端服務之間的通訊順暢。
    • CIDR_RANGE:子網路的主要 IP 位址範圍。您必須使用不超過 /26 的子網路遮罩,確保該區域中的 Proxy 至少有 64 個可用的 IP 位址。建議的子網路遮罩為 /23。
  2. 驗證 Proxy 專用子網路:

    gcloud compute networks subnets describe SUBNET_NAME \
        --region=COMPUTE_REGION
    

    輸出結果會與下列內容相似:

    ...
    gatewayAddress: 10.1.1.1
    ipCidrRange: 10.1.1.0/24
    kind: compute#subnetwork
    name: proxy-subnet
    network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default
    privateIpGoogleAccess: false
    privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS
    purpose: REGIONAL_MANAGED_PROXY
    region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION
    role: ACTIVE
    selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet
    state: READY
    

建立閘道

閘道資源代表在 Kubernetes 中轉送流量的資料層。Gateway 可代表多種不同的負載平衡和轉送,具體取決於其衍生自的 GatewayClass。如要進一步瞭解閘道資源,請參閱閘道資源說明或 API 規格。

在這個案例中,GKE 叢集的管理員想要建立一個閘道,供不同團隊在內部公開應用程式。管理員部署閘道,應用程式團隊則獨立部署路徑,並將路徑附加至這個閘道。

  1. 將下列閘道資訊清單儲存至名為 gateway.yaml 的檔案:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
       name: internal-http
    spec:
      # Specify an existing GatewayClass.
      gatewayClassName: gke-l7-rilb
      listeners:
      # Listen for HTTP traffic on port 80.
      - name: http
        protocol: HTTP
        port: 80
    

    這個資訊清單包含下列欄位:

    • gatewayClassName: gke-l7-rilb:指定這個閘道衍生自哪個 GatewayClass。gke-l7-rilb 對應至內部應用程式負載平衡器。
    • port: 80:指定閘道僅公開通訊埠 80,用於監聽 HTTP 流量。

    這個閘道設為僅處理通訊埠 80 的 HTTP 流量。根據預設,這項服務不支援 HTTPS (通訊埠 443),如果嘗試透過 HTTPS 連線,要求可能會失敗。

  2. 在叢集中部署閘道:

    kubectl apply -f gateway.yaml
    
  3. 確認閘道已正確部署。所有資源應該會在幾分鐘內部署完畢。

    kubectl describe gateways.gateway.networking.k8s.io internal-http
    

    輸出結果會與下列內容相似:

    Name:         internal-http
    Namespace:    default
    Spec:
      Gateway Class Name:  gke-l7-rilb
      Listeners:
        Allowed Routes:
          Kinds:
            Group:  gateway.networking.k8s.io
            Kind:   HTTPRoute
          Namespaces:
            From:  Same
        Name:      http
        Port:      80
        Protocol:  HTTP
     Status:
       Addresses:
         Type:   IPAddress
         Value:  192.168.1.14
       Conditions:
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:               The OSS Gateway API has deprecated this condition, do not depend on it.
         Observed Generation:   1
         Reason:                Scheduled
         Status:                True
         Type:                  Scheduled
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Accepted
         Status:                True
         Type:                  Accepted
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Programmed
         Status:                True # Indicates that the Gateway is ready.
         Type:                  Programmed
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:               The OSS Gateway API has altered the "Ready" condition semantics and reserved it for future use.  GKE Gateway will stop emitting it in a future update, use "Programmed" instead.
         Observed Generation:   1
         Reason:                Ready
         Status:                True
         Type:                  Ready
         Last Transition Time:  2025-03-19T19:53:46Z
         Message:
         Observed Generation:   1
         Reason:                Healthy
         Status:                True
         Type:                  networking.gke.io/GatewayHealthy
    Events:
      Type    Reason  Age                From                       Message
      ----    ------  ----               ----                       -------
      Normal  ADD     92s                networking.gke.io/gateway  test/internal-http
      Normal  UPDATE  45s (x3 over 91s)  networking.gke.io/gateway  test/internal-http
      Normal  SYNC    45s                networking.gke.io/gateway  SYNC on test/internal-http was a success
    

    在這個輸出內容中,Programmed 條件的 True 狀態表示閘道已就緒。

    此時,叢集中已部署閘道,並佈建負載平衡器和 IP 位址。不過,閘道沒有路徑,因此不知道如何將流量傳送至後端。如果沒有路徑,所有流量都會傳送至預設後端,並傳回 HTTP 404。接著,您要部署應用程式和路由,讓閘道知道如何連至應用程式後端。

部署試用版應用程式

應用程式團隊可以獨立部署應用程式和路徑,不受閘道部署作業影響。在某些情況下,應用程式團隊可能也想擁有閘道,並自行部署為應用程式專用的資源。如要瞭解閘道和路由的不同擁有權模式,請參閱「路由繫結」。不過,在這個範例中,商店團隊會部署應用程式和隨附的 HTTPRoute,透過上一節建立的 internal-http 閘道公開應用程式。

HTTPRoute 資源有許多可設定的流量比對欄位。如需 HTTPRoute 欄位的說明,請參閱 API 規格。

  1. 將商店應用程式 (store-v1、store-v2 和 store-german Deployment) 部署至叢集:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
    

    這會建立三個 Deployment 和三個 Service,分別名為 store-v1、store-v2 和 store-german。

  2. 確認應用程式已成功部署:

    kubectl get pod
    

    應用程式執行後,輸出內容大致如下:

    NAME                        READY   STATUS    RESTARTS   AGE
    store-german-66dcb75977-5gr2n   1/1     Running   0          38s
    store-v1-65b47557df-jkjbm       1/1     Running   0          14m
    store-v2-6856f59f7f-sq889       1/1     Running   0          14m
    
  3. 確認服務已部署:

    kubectl get service
    

    輸出內容會顯示各商店 Deployment 的 Service:

    NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    store-german   ClusterIP   10.48.3.183   <none>        8080/TCP   4s
    store-v1       ClusterIP   10.48.2.224   <none>        8080/TCP   5s
    store-v2       ClusterIP   10.48.4.48    <none>        8080/TCP   5s
    

部署 HTTPRoute

路由資源會定義通訊協定專屬規則,將流量從閘道對應至 Kubernetes 後端。HTTPRoute 資源會比對及篩選 HTTP 和 HTTPS 流量,且所有 gke-l7 GatewayClass 都支援這項資源。

在本節中,您將部署 HTTPRoute,為閘道設定連至商店應用程式所需的路由規則。

  1. 將下列 HTTPRoute 資訊清單儲存至名為 store-route.yaml 的檔案:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store
    spec:
      # Attach the HTTPRoute to a Gateway.
      parentRefs:
      - kind: Gateway
        name: internal-http
      # Route requests that have `store.example.com` in the Host header.
      hostnames:
      - "store.example.com"
      rules:
      # Send requests with the `env: canary` header to the `store-v2` Service.
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
        - name: store-v2
          port: 8080
      # Send requests with `/de` in the path to the `store-german` Service.
      - matches:
        - path:
            value: /de
        backendRefs:
        - name: store-german
          port: 8080
      # Send unmatched requests to the store-v1 Service.
      - backendRefs:
        - name: store-v1
          port: 8080
    
  2. 在叢集中部署 HTTPRoute:

    kubectl apply -f store-route.yaml
    

    store HTTPRoute 會使用 parentRefs 屬性繫結至 internal-http 閘道。這些路由規則是在基礎負載平衡器上設定,如下圖所示:

    由商店 HTTPRoute 設定的路由規則

    這些路由規則會以下列方式處理 HTTP 流量:

    • store.example.com/de 的流量會傳送至 Service store-german。
    • 含有 HTTP 標頭 "env: canary" 的 store.example.com 流量會傳送至 Service store-v2。
    • 其餘流向 store.example.com 的流量會傳送至服務 store-v1。
  3. 確認 HTTPRoute 已部署:

    kubectl describe httproute store
    

    輸出結果會與下列內容相似:

    Name:         store
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  gateway.networking.k8s.io/v1
    Kind:         HTTPRoute
    # Multiple lines are omitted here.
    Spec:
      Hostnames:
        store.example.com
      Parent Refs:
        Group:  gateway.networking.k8s.io
        Kind:   Gateway
        Name:   internal-http
      Rules:
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v1
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v2
          Port:    8080
          Weight:  1
        Matches:
          Headers:
            Name:   env
            Type:   Exact
            Value:  canary
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-german
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        Conditions:
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2022-11-01T04:18:52Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
    Events:
      Type    Reason  Age                From                   Message
      ----    ------  ----               ----                   -------
      Normal  ADD     24m                sc-gateway-controller  default/store
      Normal  SYNC    16m (x4 over 23m)  sc-gateway-controller  Bind of HTTPRoute "default/store" to ParentRef {Group:       gateway.networking.k8s.io",
      # Multiple lines are omitted here.
    
  4. 確認 HTTPRoute 已繫結至閘道:

    kubectl describe gateway
    

    輸出結果會與下列內容相似:

    Name:         internal-http
    Namespace:    default
    Labels:       <none>
    <...>
    Status:
      Addresses:
        Type:   IPAddress
        Value:  10.128.15.203
      Conditions:
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T03:47:01Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T03:47:01Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    http
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
          <...>
    

將流量傳送至應用程式

現在,閘道、路徑和應用程式已部署至叢集,您可以將流量傳送至應用程式。閘道設定為僅在通訊埠 80 提供 HTTP 流量。除非已另外設定 TLS,否則使用 HTTPS 提出的要求可能會失敗。

  1. 從閘道擷取 IP 位址,以便將流量傳送至應用程式:

    kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"
    

    輸出內容為 IP 位址。

  2. 從與叢集連線的虛擬機器 (VM) 執行個體,將流量傳送至這個 IP 位址。這是因為閘道具有內部 IP 位址,且只能從虛擬私有雲網路存取。由於 internal-http 是區域性負載平衡器,用戶端 VM 必須與 GKE 叢集位於相同區域。

    在相同的虛擬私有雲網路和區域中,建立測試 VM:

    gcloud compute instances create test-vm \
        --zone=COMPUTE_ZONE \
        --network=VPC_NETWORK_NAME
    

    使用 SSH 連線至 VM:

    gcloud compute ssh test-vm --zone=COMPUTE_ZONE
    

    在 VM 的殼層中,向 store.example.com 發出要求:

    curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    將 GATEWAY_IP_ADDRESS 替換為上一個步驟中的 IP 位址。

    試用版應用程式的輸出內容會顯示應用程式執行位置的相關資訊:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v1-84b47c7f58-pmgmk",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:31:17",
      "zone": "ZONE_NAME"
    }
    
  3. 前往 store.example.com/de 的德文版商店服務,測試路徑比對:

    curl http://store.example.com/de --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    輸出內容會確認要求是由 store-german Pod 提供:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "Gutentag!", 
      "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal",
      "pod_name": "store-german-5cb6474c55-lq5pl", 
      "pod_name_emoji": "🧞‍♀",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:35:37",
      "zone": "ZONE_NAME"
    }
    
  4. 最後,使用 env: canary HTTP 標頭,將流量傳送至商店 Service 的初期測試版本:

    curl -H "env: canary" http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    輸出內容會確認要求是由 store-v2 Pod 提供:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v2", 
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v2-5788476cbd-s9thb", 
      "pod_name_emoji": "🦰",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-10-25T13:38:26",
      "zone": "ZONE_NAME"
    }
    

部署外部閘道

外部閘道會公開可從網際網路或虛擬私有雲網路以外網路連線的應用程式。這項部署作業與內部閘道部署作業類似,但您必須保護應用程式,因為閘道可透過公開網際網路存取。

建立外部閘道的方式有兩種:全域外部閘道或區域性外部閘道。

  • 區域性外部閘道:這個閘道會使用區域性 IP 位址做為閘道的前端。這個閘道的行為取決於您選取的網路服務級別:
    • 如果選擇標準網路服務級別 (預設),區域性 IP 位址只會在部署區域性外部閘道的本機 Google Cloud Compute 區域中 advertise。用戶端將流量傳送至這個 IP 位址時,流量會先由本機網際網路服務供應商 (ISP) 透過公開網際網路轉送,然後才抵達公告 IP 位址的 Google 區域。
    • 如果選擇進階網路服務級別,區域性 IP 位址會在 Google 的全球網路中 advertise。這表示用戶端流量會從盡可能靠近用戶端的 Google 邊緣對接點,進入 Google 的優質全球骨幹網路,即使目的地是區域性 IP 位址也一樣。這個位置可大幅縮短延遲時間並提升效能,因為流量在公開網際網路上的傳輸距離會縮到最短。
  • 全域外部閘道:這類閘道使用全域 IP 位址 (或任意傳播 IP 位址) 做為前端。這個 IP 位址會在所有 Google Cloud Compute 區域中 advertising。用戶端將流量傳送至這個任意傳播 IP 位址時,系統會將流量轉送至最靠近的 Google 位置,也就是該 IP 位址的 advertise 位置。全域外部閘道僅適用於進階網路服務級別。

部署區域性外部閘道

以下範例說明如何使用自行管理的憑證和 HTTPRoute,公開附加多個憑證至區域性外部閘道的商店應用程式。

為區域性閘道建立 Proxy 子網路

您必須先設定僅限 Proxy 的子網路,才能建立使用區域性外部應用程式負載平衡器的閘道。在您使用區域性外部應用程式負載平衡器的虛擬私有雲中,每個區域都必須有 external_managed_proxy 子網路。這個子網路會為負載平衡器 Proxy 提供內部 IP 位址。

建立憑證,保護用戶端流量

您可以使用憑證授權單位 (CA) 核發及驗證的憑證,也可以建立自行簽署的憑證。如要進一步瞭解如何建立憑證,請參閱「將憑證儲存在 Kubernetes Secret 中」。

如要保護用戶端與區域閘道之間的流量,可以採用下列方法:

  • Google 代管或自行管理的 Certificate Manager 憑證
  • 自行管理的區域性 SSL 憑證
  • Kubernetes Secret

區域性閘道不支援CertificateMap或 Google 代管的 SSL 憑證。

詳情請參閱「憑證和 Google Cloud 負載平衡器」。

建立區域性外部 HTTP(S) 閘道

  1. 為外部負載平衡器建立區域性靜態 IP 位址。

    gcloud compute addresses create IP_ADDRESS_NAME \
      --region=COMPUTE_REGION \
      --network-tier=STANDARD
    

    更改下列內容:

    • IP_ADDRESS_NAME:新靜態 IP 位址的名稱。
    • COMPUTE_REGION:叢集執行的 Compute Engine 區域。
  2. 使用自行管理的憑證建立區域性外部應用程式負載平衡器閘道,如下所示,並將資訊清單儲存為 regional-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: external-regional-http
      spec:
        # Name of an existing GatewayClass.
        gatewayClassName: gke-l7-regional-external-managed
        # Listen for HTTPS traffic on port 443
        listeners:
        - name: https
          protocol: HTTPS
          port: 443
          tls:
            # Terminate the TLS session with the client at the Gateway.
            mode: Terminate
            # Certificates for the Gateway to use to create a new TLS session.
            certificateRefs:
            - name: store-example-com
        # The name of the static IP address of the external load balancer.
        # You can also use the `IPAddress` type to specify the actual IP address.
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
    
  3. 套用 regional-gateway 資訊清單:

      kubectl apply -f regional-gateway.yaml
    
  4. 驗證設定。

      kubectl get gateway
    

    輸出結果會與下列內容相似:

    NAME            CLASS                              ADDRESS         READY   AGE
    external-http   gke-l7-regional-external-managed   35.118.32.224   True    49s
    

    如要查看更多詳細資料,請使用 describe 指令:

    kubectl describe gateway
    

    輸出結果會與下列內容相似:

    Name:         external-regional-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-regional-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
      ...
    

部署試用版應用程式

應用程式團隊可以獨立部署應用程式和路徑,不受閘道部署作業影響。在某些情況下,應用程式團隊可能也想擁有閘道,並自行部署為應用程式專用的資源。如要瞭解閘道和路由的不同擁有權模式,請參閱「路由繫結」。在這個範例中,商店團隊部署應用程式和隨附的 HTTPRoute,透過上一節建立的 external-http Gateway 公開應用程式。

如要進一步瞭解 HTTPRoute 欄位,請參閱 API 規格。

  1. 將範例應用程式部署至叢集:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml
    

    這個範例應用程式會建立三個 Deployment 和三個 Service,分別命名為 store-v1、store-v2 和 store-german。

  2. 確認應用程式已成功部署:

    kubectl get pod
    

    輸出結果會與下列內容相似:

    NAME                            READY   STATUS    RESTARTS   AGE
    store-german-66dcb75977-5gr2n   1/1     Running   0          38s
    store-v1-65b47557df-jkjbm       1/1     Running   0          14m
    store-v2-6856f59f7f-sq889       1/1     Running   0          14m
    
  3. 確認 Service 已成功部署:

    kubectl get service
    

    輸出結果會與下列內容相似:

    NAME           TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    store-german   ClusterIP   10.48.3.183   <none>        8080/TCP   4s
    store-v1       ClusterIP   10.48.2.224   <none>        8080/TCP   5s
    store-v2       ClusterIP   10.48.4.48    <none>        8080/TCP   5s
    

建立 HTTPRoute

路由資源會定義通訊協定專屬規則,將流量從閘道對應至 Kubernetes 後端。HTTPRoute 資源會比對及篩選 HTTP 和 HTTPS 流量,且所有 gke-l7-* GatewayClass 都支援這項資源。

在本節中,您將部署 HTTPRoute,為閘道設定連至範例應用程式所需的路由規則。

  1. 將下列資訊清單儲存至名為 store-route-external.yaml 的檔案:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
    spec:
      parentRefs:
      # Bind the route to the 'external-http' Gateway.
      - kind: Gateway
        name: external-http
      hostnames:
      - "store.example.com"
      rules:
      # Default rule for store.example.com that sends traffic to the store-v1 service.
      - backendRefs:
        - name: store-v1
          port: 8080
      # Match requests with the "env: canary" header and send them to the store-v2 service.
      - matches:
        - headers:
          - name: env
            value: canary
        backendRefs:
        - name: store-v2
          port: 8080
      # Match requests with the path "/de" and sends them to the store-german service.
      - matches:
        - path:
            value: /de
        backendRefs:
        - name: store-german
          port: 8080
    

    這個資訊清單描述參照 external-http 閘道的 HTTPRoute。

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

    kubectl apply -f store-route-external.yaml
    

    store HTTPRoute 會使用 parentRefs 屬性繫結至 external-http 閘道。下圖顯示基礎負載平衡器上設定的路由規則:

    由商店 HTTPRoute 設定的路由規則

    路由規則會按照下列方式處理 HTTP 流量:

    • 傳送至 store.example.com/de 的流量會轉送至服務 store-german。
    • HTTP 標頭為 "env: canary" 的 store.example.com 流量會轉送至服務 store-v2。
    • 其餘流向 store.example.com 的流量則會轉送至服務 store-v1。
  3. 確認 HTTPRoute 已部署:

    kubectl describe httproute store-external
    

    輸出結果會與下列內容相似:

    Name:         store-external
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  gateway.networking.k8s.io/v1
    Kind:         HTTPRoute
    # Multiple lines are omitted here.
    Spec:
      Hostnames:
        store.example.com
      Parent Refs:
        Group:  gateway.networking.k8s.io
        Kind:   Gateway
        Name:   external-http
      Rules:
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v1
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-v2
          Port:    8080
          Weight:  1
        Matches:
          Headers:
            Name:   env
            Type:   Exact
            Value:  canary
          Path:
            Type:   PathPrefix
            Value:  /
        Backend Refs:
          Group:
          Kind:    Service
          Name:    store-german
          Port:    8080
          Weight:  1
        Matches:
          Path:
            Type:   PathPrefix
            Value:  /de
    Status:
      Parents:
        # This section shows the status of this route in relation to each Gateway attached.
        Conditions:
          Last Transition Time:  2022-11-01T05:42:31Z
          Message:
          Reason:                Accepted
          Status:                True # Means that the Gateway has validated and accepted this route's configuration.
          Type:                  Accepted
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
    Events:
      Type     Reason  Age    From                   Message
      ----     ------  ----   ----                   -------
      Normal   ADD     2m48s  sc-gateway-controller  default/store-external
      Normal  SYNC  61s (x3 over 2m27s)  sc-gateway-controller  Bind of HTTPRoute "default/store-external" to ParentRef Group:       "gateway.networking.k8s.io",
      ...
    
  4. 確認 HTTPRoute 已繫結至閘道:

    kubectl describe gateway external-http
    

    輸出結果會與下列內容相似:

    Name:         external-http
    Namespace:    default
    Labels:       <none>
    # Multiple lines are omitted here.
    Status:
      Addresses:
        Type:   IPAddress
        Value:  34.149.207.45
      Conditions:
        Last Transition Time:  2022-11-01T05:37:21Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
        Last Transition Time:  2022-11-01T05:43:18Z
        Message:
        Reason:                Ready
        Status:                True
        Type:                  Ready
      Listeners:
        Attached Routes:  1
        Conditions:
          Last Transition Time:  2022-11-01T05:43:18Z
          Message:
          Reason:                Ready
          Status:                True
          Type:                  Ready
        Name:                    https
        Supported Kinds:
          Group:  gateway.networking.k8s.io
          Kind:   HTTPRoute
          # Multiple lines are omitted here.
    

將流量傳送至應用程式

現在,閘道、路徑和應用程式已部署至叢集,您可以將流量傳送至應用程式。

  1. 取得閘道的 IP 位址:

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"
    

    輸出內容為 IP 位址。

  2. 建立 VM:

    gcloud cloud-shell ssh
    
  3. 從 VM 將流量傳送至閘道 IP 位址。您必須手動設定主機標頭,因為您並非 example.com 主機名稱的擁有者。

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    將 GATEWAY_IP_ADDRESS 替換為上一個步驟中的閘道 IP 位址。

    cacert.pem:您產生的憑證檔案。請務必將這個檔案儲存在用來連線至閘道的機器上。

    輸出內容會顯示試用版應用程式的資訊,說明應用程式的執行位置:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v1-84b47c7f58-pmgmk",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:31:17",
      "zone": "us-central1-a"
    }
    
  4. 前往 store.example.com/de 的德文版 store 服務,測試路徑比對:

    curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    輸出內容會確認要求是由 store-german Pod 提供:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "Gutentag!",
      "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal",
      "pod_name": "store-german-5cb6474c55-lq5pl",
      "pod_name_emoji": "🧞‍♀",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:35:37",
      "zone": "us-central1-a"
    }
    
  5. 使用 env: canary HTTP 標頭,將流量傳送至 store 服務的金絲雀版本:

    curl -H "env: canary" https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
    

    輸出內容會確認要求是由 store-v2 Pod 提供:

    {
      "cluster_name": "gke1",
      "host_header": "store.example.com",
      "metadata": "store-v2",
      "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal",
      "pod_name": "store-v2-5788476cbd-s9thb",
      "pod_name_emoji": "👩🏿",
      "project_id": "gateway-demo-243723",
      "timestamp": "2022-09-25T13:38:26",
      "zone": "us-central1-a"
    }
    

部署全域外部閘道

以下範例說明如何使用 Certificate Manager 和 HTTPRoute,公開附加多個憑證至全域外部閘道,並分組至憑證對應組合的商店應用程式。

建立憑證對應組合

如果每個閘道需要 15 個以上的憑證,或需要使用萬用字元憑證,Google 建議您使用 Certificate Manager 管理憑證。

您也可以使用 Kubernetes Secret 或 Google 代管的 SSL 憑證,保護外部閘道。詳情請參閱「閘道安全性」。

在本節中,您將使用 Certificate Manager 建立憑證,保護在叢集上執行的應用程式。

  1. 啟用 Certificate Manager API:

    gcloud services enable certificatemanager.googleapis.com
    
  2. 建立憑證對應組合:

    gcloud beta certificate-manager maps create store-example-com-map
    
  3. 將 Google 代管的憑證和金鑰載入憑證:

    gcloud beta certificate-manager certificates create store-example-com-cert \
        --certificate-file="CERTIFICATE_FILE" \
        --private-key-file="PRIVATE_KEY_FILE"
    

    更改下列內容:

    • CERTIFICATE_FILE:憑證檔案名稱。檔案的副檔名必須是 .pem。例如:cert.pem。
    • PRIVATE_KEY_FILE:私密金鑰檔案的名稱。

    詳情請參閱「建立私密金鑰和憑證」。

  4. 建立 CertificateMapEntry,將憑證指派給憑證對應組合:

    gcloud beta certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

如要瞭解如何使用其他憑證來源 (例如 Kubernetes Secret 或 SSL 憑證) 保護閘道,請參閱「保護閘道」。

建立閘道

閘道資源代表在 Kubernetes 中轉送流量的資料層。Gateway 可根據使用的 GatewayClass,代表多種不同的負載平衡和轉送。

如要進一步瞭解閘道資源,請參閱閘道資源說明或 API 規格。

在本節中,您將建立閘道。應用程式團隊可以獨立部署路徑,並將路徑安全地附加至閘道,透過閘道將應用程式公開至網際網路。

  1. 將下列資訊清單儲存至名為 gateway.yaml 的檔案:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      # This GatewayClass uses a global external Application Load Balancer.
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
    
    

    這個資訊清單描述的閘道包含下列欄位:

    • gatewayClassName: gke-l7-global-external-managed:指定這個閘道的 GatewayClass。這個閘道類別使用全域外部應用程式負載平衡器。
    • protocol: HTTPS 和 port: 443:指定閘道公開 HTTPS 流量的通訊埠 443。這些欄位會啟用 TLS。
    • networking.gke.io/certmap: store-example-com-map:指定 Certificate Manager 中的憑證對應組合名稱。

    由於 TLS 是透過 Certificate Manager 設定,並使用 networking.gke.io/certmap 註解,因此沒有 TLS 區段。

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

    kubectl apply -f gateway.yaml
    

    GKE 可能需要幾分鐘才能部署資源。

  3. 確認閘道已成功部署:

    kubectl describe gateway
    

    輸出結果會與下列內容相似:

    Name:         external-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-global-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
     ...
    

    這項輸出內容顯示,叢集內部署的閘道具有負載平衡器和公開 IP 位址。閘道沒有任何路由,因此無法將流量傳送至後端。如果沒有路徑,所有流量都會傳送至預設後端,並傳回 HTTP 404 回應。在下一節中,您將部署路由,指示閘道將流量傳送至後端。

部署試用版應用程式

您可以獨立部署應用程式和路徑,不受閘道部署作業影響。

如要進一步瞭解如何部署試用版應用程式,請參閱「部署試用版應用程式」。

建立 HTTPRoute

您必須建立 HTTPRoute,才能比對及篩選 HTTP 和 HTTPS 流量。

將流量傳送至應用程式

部署應用程式並建立 HTTPRoute 後,即可將流量傳遞至應用程式。

如要進一步瞭解如何將流量傳送至應用程式,請參閱「將流量傳送至應用程式」。

部署區域性外部閘道

以下範例說明如何使用自行管理的憑證和 HTTPRoute,公開附加多個憑證至區域性外部閘道的商店應用程式。

為區域性閘道建立 Proxy 子網路

您必須先設定僅限 Proxy 的子網路,才能建立使用區域性外部應用程式負載平衡器的閘道。在您使用區域性外部應用程式負載平衡器的虛擬私有雲中,每個區域都必須有 external_managed_proxy 子網路。這個子網路會為負載平衡器 Proxy 提供內部 IP 位址。

建立憑證,保護用戶端流量

您可以使用憑證授權單位 (CA) 核發及驗證的憑證,也可以建立自行簽署的憑證。如要進一步瞭解如何建立憑證,請參閱「將憑證儲存在 Kubernetes Secret 中」。

如要保護用戶端與區域閘道之間的流量,可以採用下列方法:

  • Google 代管或自行管理的 Certificate Manager 憑證
  • 自行管理的區域性 SSL 憑證
  • Kubernetes Secret

區域性閘道不支援 CertificateMap 或 Google 代管的 SSL 憑證。

詳情請參閱「憑證和 Google Cloud 負載平衡器」

建立區域性外部 HTTP(S) 閘道

  1. 為外部負載平衡器建立區域性靜態 IP 位址。

    gcloud compute addresses create IP_ADDRESS_NAME \
      --region=COMPUTE_REGION \
      --network-tier=STANDARD
    

    更改下列內容:

    • IP_ADDRESS_NAME:新靜態 IP 位址的名稱。
    • COMPUTE_REGION:叢集執行的 Compute Engine 區域。
  2. 使用自行管理的憑證建立區域性外部應用程式負載平衡器閘道,如下所示,並將資訊清單儲存為 regional-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: external-regional-http
      spec:
        # Name of an existing GatewayClass.
        gatewayClassName: gke-l7-regional-external-managed
        # Listen for HTTPS traffic on port 443
        listeners:
        - name: https
          protocol: HTTPS
          port: 443
          tls:
            # Terminate the TLS session with the client at the Gateway.
            mode: Terminate
            # Certificates for the Gateway to use to create a new TLS session.
            certificateRefs:
            - name: store-example-com
        # The name of the static IP address of the external load balancer.
        # You can also use the `IPAddress` type to specify the actual IP address.
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
    
  3. 套用 regional-gateway 資訊清單:

      kubectl apply -f regional-gateway.yaml
    
  4. 驗證設定。

      kubectl get gateway
    

    輸出結果會與下列內容相似:

    NAME            CLASS                              ADDRESS         READY   AGE
    external-http   gke-l7-regional-external-managed   35.118.32.224   True    49s
    

    如要查看更多詳細資料,請使用 describe 指令:

    kubectl describe gateway
    

    輸出結果會與下列內容相似:

    Name:         external-regional-http
    Namespace:    default
    Labels:       <none>
    ...
    Spec:
      Gateway Class Name:  gke-l7-regional-external-managed
      Listeners:
        Allowed Routes:
          Namespaces:
            From:  Same
        Name:      https
        Port:      443
        Protocol:  HTTPS
        Tls:
          Certificate Refs:
            Group:
            Kind:   Secret
            Name:   store-example-com
          Mode:     Terminate
      ...
    

部署試用版應用程式

您可以獨立部署應用程式和路徑,不受閘道部署作業影響。

如要進一步瞭解如何部署試用版應用程式,請參閱「部署試用版應用程式」。

建立 HTTPRoute

您必須建立 HTTPRoute,才能比對及篩選 HTTP 和 HTTPS 流量。

將流量傳送至應用程式

部署應用程式並建立 HTTPRoute 後,即可將流量傳遞至應用程式。

如要進一步瞭解如何將流量傳送至應用程式,請參閱「將流量傳送至應用程式」。

使用共用閘道

Gateway API 會使用獨立的資源「閘道」和「路由資源」,部署負載平衡器和路由規則。這與將所有內容合併至單一資源的 Ingress 不同。Gateway 會將責任分配給不同資源,因此可分別部署負載平衡器和其路由規則,並由不同使用者或團隊部署。這樣一來,閘道就能成為共用閘道,附加許多不同的路徑,並由獨立團隊完全擁有及管理,甚至可以跨不同命名空間。

針對共用閘道部署路由

這個範例是以部署內部閘道中部署的 internal-http 閘道為基礎。

在這個範例中,網站團隊部署了應用程式、服務和 HTTPRoute,以便將閘道的流量與這些服務進行比對。

  1. 部署範例應用程式:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yaml
    
  2. 將下列資訊清單儲存至名為 site-route-internal.yaml 的檔案:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: site-internal
    spec:
      # Attach the HTTPRoute to the `internal-http` Gateway.
      parentRefs:
      - kind: Gateway
        name: internal-http
      # Route requests that have `site.example.com` in the Host header.
      hostnames:
      - "site.example.com"
      # Send all requests to the `site-v1` Service.
      rules:
      - backendRefs:
        - name: site-v1
          port: 8080
    

    這個資訊清單描述的 HTTPRoute 會比對 site.example.com 的所有流量,並將其轉送至 site-v1 服務。

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

    kubectl apply -f site-route-internal.yaml
    
  4. 確認 HTTPRoute 已附加至閘道:

    kubectl describe httproute.gateway.networking.k8s.io site-internal
    

    輸出結果會與下列內容相似:

    Status:
      Parents:
        Conditions:
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                Accepted
          Status:                True
          Type:                  Accepted
          Last Transition Time:  2023-01-09T15:05:43Z
          Message:
          Reason:                ReconciliationSucceeded
          Status:                True
          Type:                  Reconciled
        Controller Name:         networking.gke.io/gateway
        Parent Ref:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   internal-http
          ...
    

    如果閘道的 Accepted 條件為 True,表示 HTTPRoute 已成功繫結至閘道。如要進一步瞭解「Status」(狀態) 欄位,請參閱「路徑狀態」。

  5. 確認傳送至閘道的流量是否正確轉送:

    curl -H "host: site.example.com" GATEWAY_IP_ADDRESS
    curl -H "host: store.example.com" GATEWAY_IP_ADDRESS
    

    將 GATEWAY_IP_ADDRESS 替換為內部閘道的 IP 位址。

    您必須使用與閘道位於相同虛擬私有雲的虛擬機器 (VM)。

    輸出結果會與下列內容相似:

    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "site.example.com",
      "metadata": "site-v1",
      "pod_name": "site-v1-5d64fc4d7d-fz6f6",
      "pod_name_emoji": "👩🏼‍🍳",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    ...
    {
      "cluster_name": "CLUSTER_NAME",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-6d8d58d78-vz8pn",
      "pod_name_emoji": "🧝🏻‍♂️",
      "project_id": "PROJECT_ID",
      "timestamp": "2022-11-02T19:07:01",
      "zone": "ZONE_NAME"
    }
    

    這項輸出內容表示,含有 site.example.com 主機標頭的要求會傳送至 site-v1 服務,而含有 store.example.com 主機標頭的要求則會傳送至 store-v1 服務。

設定網路級別

您可以在閘道定義的 addresses[] 陣列中使用 type 欄位,指定區域性外部應用程式負載平衡器監聽器位址的網路級別。如未指定網路級別,閘道預設會使用標準級暫時 IP 位址。

type 欄位請使用下列值:

  • networking.gke.io/premium-ephemeral-ipv4-address:指派進階級 IP 位址。
  • networking.gke.io/standard-ephemeral-ipv4-address:指派標準級 IP 位址。

如要從兩個網路級別指派 IP 位址,請在 addresses 欄位中指定這兩種類型。

以下範例說明如何讓 Google Cloud 將進階級 IP 位址指派給閘道。如要佈建標準級 IP 位址,請使用 networking.gke.io/standard-ephemeral-ipv4-address。

  1. 將下列資訊清單範例儲存為 external-regional-http.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-regional-http
    spec:
      # Name of an existing GatewayClass.
      gatewayClassName: gke-l7-regional-external-managed
      # Listen for HTTPS traffic on port 443.
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          # Terminate the TLS session with the client at the Gateway.
          mode: Terminate
          # Certificates for the Gateway to use to create a new TLS session.
          certificateRefs:
          - name: store-example-com
        addresses:
        # Request a Premium Tier ephemeral IPv4 address for the Gateway.
        - type: networking.gke.io/premium-ephemeral-ipv4-address
    
  2. 套用範例資訊清單:

    kubectl apply -f external-regional-http.yaml
    

設定閘道預設後端

所有 gke-l7-* GatewayClass 都會針對不相符的流量傳回 HTTP 404。您可以設定預設後端,方法是使用明確的預設路徑,將不相符的流量傳送至使用者提供的服務。

即使沒有明確的後端定義,閘道也會設定為處理 404 (找不到) 和 500 (伺服器錯誤) 等錯誤代碼。預設行為可能會因閘道實作方式而異。如要進一步控管錯誤處理,建議您設定自訂後端。

以下 HTTPRoute 範例說明如何自訂預設後端。如果套用類似下列的 HTTPRoute,其優先順序會高於隱含的預設後端:

kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: custom-default-backend
spec:
  parentRefs:
  - kind: Gateway
    name: my-internal-gateway
  # Omit the `hostnames` field to route all unmatched traffic from the
  # attached Gateway.
  rules:
  - backendRefs:
    - name: my-custom-default-backend-service
      port: 8080

這個 HTTPRoute 會比對來自特定閘道的所有流量。每個閘道只能有一項這類規則,否則規則會發生衝突,並套用優先順序。

您可以使用預設後端,防止使用者建立轉送所有閘道流量的預設路徑後端。明確的 HTTPRoute 一律優先於具有衝突路由規則的新 HTTPRoute。

為閘道設定靜態 IP 位址

每個閘道都有一個 IP 位址,用於監聽流量。如未在閘道指定 IP 位址,閘道控制器會自動提供 IP 位址。您也可以建立靜態 IP 位址,讓 IP 位址獨立於閘道生命週期存在。

部署閘道後,其 IP 位址會顯示在狀態欄位中:

kind: Gateway
...
status:
  addresses:
    - value: 10.15.32.3

視 GatewayClass 而定,IP 位址會從下列子網路分配:

GatewayClasses 預設 IP 位址集區
  • gke-l7-rilb
  • gke-l7-rilb-mc
  • 主要節點 IPv4/IPv6 位址範圍中的區域性私人 IP 位址
  • gke-l7-regional-external-managed
  • gke-l7-regional-external-managed-mc
  • Google 區域性外部 IPv4/IPv6 範圍中的區域性公開 IP 位址
  • gke-l7-global-external-managed
  • gke-l7-global-external-managed-mc
  • gke-l7-gxlb
  • gke-l7-gxlb-mc
  • Google 全域外部 IPv4/IPv6 範圍的全域公開 IP 位址

    addresses.NamedAddress 欄位可讓您指定與閘道無關的 IP 位址。您可以在部署閘道前建立靜態 IP 位址資源,並由 NamedAddress 參照該資源。即使刪除閘道,您仍可重複使用靜態 IP 位址。

    使用已命名的 IP 位址

    您可以指定 NamedAddress,設定 IPv4 或 IPv6 位址。建立閘道前,請務必先佈建靜態 IP 位址。

    1. 建立靜態 IP 位址資源:

      gcloud compute addresses create IP_ADDRESS_NAME \
          --purpose=SHARED_LOADBALANCER_VIP \
          --region=COMPUTE_REGION \
          --subnet=SUBNET \
          --project=PROJECT_ID
      

      更改下列內容:

      • IP_ADDRESS_NAME:新靜態 IP 位址的名稱
      • COMPUTE_REGION:如果是區域性閘道,則為叢集執行的 Compute Engine 區域。全域外部閘道不需要這個旗標。
      • SUBNET:IP 位址的子網路。全域外部閘道不需要這個旗標。
      • PROJECT_ID:GKE 叢集運作中的專案。
    2. 將下列資訊清單儲存至名為 named-ip-gateway.yaml 的檔案:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: internal-http
      spec:
        gatewayClassName: gke-l7-rilb
        listeners:
        - name: http
          protocol: HTTP
          port: 80
        addresses:
        - type: NamedAddress
          value: IP_ADDRESS_NAME
      

      這個資訊清單描述的閘道會參照具名 IP 位址。

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

      kubectl apply -f named-ip-gateway.yaml
      
    4. 驗證閘道 IP 位址:

      kubectl describe gateway internal-http
      

      輸出結果會與下列內容相似:

      Name:         internal-http
      Namespace:    default
      Labels:       <none>
      ...
      Spec:
        Addresses:
          Type:              NamedAddress
          Value:             IP_ADDRESS_NAME
        Gateway Class Name:  gke-l7-rilb
        Listeners:
          Allowed Routes:
            Namespaces:
              From:  Same
          Name:      http
          Port:      80
          Protocol:  HTTP
      Status:
        Addresses:
          Type:   IPAddress
          Value:  10.15.32.103
      

    設定從 HTTP 重新導向至 HTTPS

    Cloud Load Balancing 提供從 HTTP 重新導向至 HTTPS 的功能。外部應用程式負載平衡器會將未加密的 HTTP 要求,重新導向至使用相同 IP 位址的 HTTPS 負載平衡器。建立閘道並啟用 HTTP 至 HTTPS 重新導向功能時,系統會自動建立這兩個負載平衡器。傳送至閘道外部 IP 位址 (通訊埠 80) 的要求,會自動重新導向至相同的外部 IP 位址 (通訊埠 443)。

    根據預設,閘道不會定義從 HTTP 重新導向至 HTTPS。

    如要將 HTTP 流量重新導向至 HTTPS,請設定閘道來處理 HTTP 和 HTTPS 流量。如果停用 HTTP 或 HTTPS,閘道就不會重新導向流量。

    以下範例說明如何使用 HTTP 到 HTTPS 重新導向,確保用戶端傳送至網頁應用程式的流量一律重新導向至安全網頁。

    gke-l7-gxlb 和 gke-l7-gxlb-mc GatewayClass 不支援從 HTTP 重新導向至 HTTPS。如要進一步瞭解各 GatewayClass 支援的不同功能,請參閱「GatewayClass 功能」。

    請注意,HTTPRoute 中的 hostnames 區段為選用。您可以省略 hostnames 部分,為特定 HTTP 通訊埠上的所有主機名稱建立 catch-all 重新導向。此外,您也可以使用萬用字元重新導向,例如:

    ...
    hostnames:
    - "*.example.com" # Matches all subdomains of example.com
    ...
    

    重新導向來自基礎架構命名空間的 HTTP 流量

    在某些情況下,基礎架構或平台管理員團隊與應用程式團隊之間沒有明確區別,因此可能難以防止 Gateway 遭到濫用。

    以下範例進一步限制 HTTP 監聽器的使用,防止應用程式團隊不小心使用不安全的通訊協定。這個範例會設定閘道,只有在 HTTPRoute 位於具有 otherInfra: httpToHttps 標籤的命名空間時,才允許 HTTPRoute 使用 HTTP 監聽器。不過,閘道允許任何命名空間中的 HTTPRoute 使用 HTTPS 監聽器。您可以使用 Kubernetes RBAC 限制 http-redirect 命名空間,以免應用程式團隊誤在這個命名空間中建立 HTTPRoute。

    1. 建立閘道的命名空間。將資訊清單儲存為 gateway-namespace.yaml:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: gateway-infra
      
    2. 套用資訊清單:

      kubectl apply -f gateway-namespace.yaml
      
    3. 建立閘道的命名空間,並將資訊清單儲存為 redirect-namespace.yaml:

      apiVersion: v1
      kind: Namespace
      metadata:
        name: http-redirect
        labels:
          otherInfra: httpToHttps
      

      這個 http-redirect 命名空間具有 otherInfra: httpToHttps 標籤。

    4. 套用資訊清單:

      kubectl apply -f redirect-namespace.yaml
      
    5. 如要限制 HTTP 監聽器的使用,請使用下列資訊清單建立閘道。將資訊清單儲存為 external-gateway.yaml:

      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: external-http
        namespace: gateway-infra
      spec:
        # Name of an existing GatewayClass.
        gatewayClassName: gke-l7-global-external-managed
        listeners:
        - name: http
          protocol: HTTP
          port: 80
          #  Allow only HTTPRoutes from namespaces that have the
          # `otherInfra: httpToHttps` label to use this listener.
          allowedRoutes:
            kinds:
            - kind: HTTPRoute
            namespaces:
              from: Selector
              selector:
                matchLabels:
                  otherInfra: httpToHttps
        - name: https
          protocol: HTTPS
          port: 443
          # Allow HTTPRoutes from any namespace to use this listener.
          allowedRoutes:
            kinds:
            - kind: HTTPRoute
            namespaces:
              from: All
          tls:
            mode: Terminate
            options:
              networking.gke.io/pre-shared-certs: store-example-com
      
      • namespace 欄位指定在 gateway-infra 命名空間中建立閘道。

      • allowedRoutes 區段中的 namespaces 欄位會將 HTTP 監聽器限制在與標籤 otherInfra: httpToHttps 相符的命名空間。

    6. 套用資訊清單:

      kubectl apply -f external-gateway.yaml
      
    7. 如要強制執行 HTTPS 重新導向,請使用下列資訊清單建立預設 HTTPRoute。將資訊清單儲存為 http-redirect.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: redirect
        # Create the HTTPRoute in the `http-redirect` namespace.
        namespace: http-redirect
      spec:
        # Attach the HTTPRoute to the `http` listener in the `external-http`
        # Gateway.
        parentRefs:
        - namespace: gateway-infra
          name: external-http
          sectionName: http
        rules:
        # Respond to the request with an HTTPS redirection.
        - filters:
          - type: RequestRedirect
            requestRedirect:
              scheme: https
      
      • sectionName 欄位會指示閘道僅比對 HTTP 監聽器。RequestRedirect 篩選器會強制重新導向至 HTTPS 監聽器。
    8. 套用資訊清單:

      kubectl apply -f http-redirect.yaml
      
    9. 使用下列資訊清單為應用程式建立 Service。將資訊清單儲存為 service-deployment.yaml:

      apiVersion: v1
      kind: Service
      metadata:
        name: store-v1
      spec:
        selector:
          app: store
          version: v1
        ports:
        - port: 8080
          targetPort: 8080
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: store-v1
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: store
            version: v1
        template:
          metadata:
            labels:
              app: store
              version: v1
          spec:
            containers:
            - name: whereami
              image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
              ports:
              - containerPort: 8080
              env:
              - name: METADATA
                value: "store-v1"
      
    10. 套用資訊清單:

      kubectl apply -f service-deployment.yaml
      
    11. 使用下列資訊清單,為僅允許 HTTPS 的應用程式建立 HTTPRoute。將資訊清單儲存為 http-route.yaml:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store-external
        labels:
          gateway: external-http
      spec:
        # Attach the HTTPRoute to the HTTPS listener in the `external-http`
        # Gateway.
        parentRefs:
        - name: external-http
          namespace: gateway-infra
          sectionName: https
        # Match requests that have the `store.example.com` Host header.
        hostnames:
        - "store.example.com"
        # Route requests to the `store-v1` Service.
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
      
    12. 套用資訊清單:

      kubectl apply -f http-route.yaml
      

    設定路徑重新導向和網址重寫

    路徑重新導向是指將傳入要求從一個網址路徑重新導向至另一個網址路徑。路徑重新導向可讓您在需要處理過時或已淘汰的網址時,變更網址結構。

    網址重寫:在伺服器處理傳入的網址前,先修改網址。您可以變更網址的結構或格式,而不必實際變更基礎內容或檔案結構。網址重寫有助於建立容易使用、有利於搜尋引擎最佳化 (SEO) 的網址,方便使用者記憶和理解。根據預設,系統不會設定路徑重新導向和網址重寫,您必須使用 HTTPRoute 中的篩選器,明確設定這些重新導向或重寫。

    GKE Gateway 支援路徑重新導向和網址重寫。詳情請參閱「HTTP 路徑重新導向和重寫」。

    設定路徑重新導向

    您可以設定路徑重新導向,取代整個路徑或僅取代網址中的前置字串。

    取代整個路徑

    1. 如要取代整個路徑,請在 HTTPRoute 中設定篩選器,將網址路徑中包含前置字串 /any-path 的任何網址,替換為嚴格值 /new-path。

    2. 建立 HTTPRoute 資訊清單,並命名為 store.yaml:

        apiVersion: gateway.networking.k8s.io/v1
        kind: HTTPRoute
        metadata:
          name: store
        spec:
          parentRefs:
          - kind: Gateway
            name: external-http
          hostnames:
          - store.example.com
          rules:
          - matches:
            - path:
                # Match requests by a prefix, like `/any-path` and `/any-path/home`.
                type: PathPrefix
                value: /any-path
            filters:
            - type: RequestRedirect
              requestRedirect:
                path:
                  # Replace the full path with `/new-path`. For example, both
                  # `/any-path/home` and `/any-path` become `/new-path`.
                  type: ReplaceFullPath
                  replaceFullPath: /new-path
                statusCode: 302
      

      舉例來說,這個資訊清單會為 HTTPRoute 設定路由規則,如下所示:任何連往網址 https://store.example.com/any-path/... 的路徑都應重新導向至新位置 https://store.example.com/new-path/ (嚴格)。

    3. 套用資訊清單:

      kubectl apply -f store.yaml
      

    這項路由規則遵循嚴格的重新導向規則,也就是說,瀏覽器不會嘗試快取重新導向,而是重新導向至最新版本。

    僅取代前置字串

    1. 如要僅取代前置字串,請在 HTTPRoute 中設定篩選器,將網址路徑中包含前置字串 /any-prefix 的任何網址,替換為嚴格值 /new-prefix。

    2. 建立 HTTPRoute 資訊清單,並命名為 store.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
        - matches:
            - path:
                # Match requests by prefix, like `/any-prefix` and
                # `/any-prefix/home`.
                type: PathPrefix
                value: /any-prefix
          filters:
          - type: RequestRedirect
            requestRedirect:
              path:
                # Replace the matched prefix with `/new-prefix`. For example,
                # `/any-prefix` becomes `/new-prefix` and `/any-prefix/home`
                # becomes `/new-prefix/home`.
                type: ReplacePrefixMatch
                replacePrefixMatch: /new-prefix
              statusCode: 302
      

      舉例來說,這個資訊清單會為 HTTPRoute 設定路由規則,如下所示:任何連往網址 https://store.example.com/any-path/v1/... 的路由都應重新導向至新位置 https://store.example.com/new-path/v1/... (僅限)。

    3. 套用資訊清單:

        kubectl apply -f store.yaml
      

    這項路由規則遵循唯一的重新導向規則,有助於確保瀏覽器一律將您重新導向至相同的預期頁面。

    設定網址重寫

    設定網址重寫,變更網址向使用者顯示的方式。您可以使用網址重寫功能,讓網址更容易使用、改善搜尋引擎最佳化 (SEO),或將使用者重新導向至新網頁。

    重新編寫整個主機名稱

    如要重寫整個主機名稱:

    1. 在 HTTPRoute 中設定篩選器,指示閘道在將要求轉送至後端服務之前,將要求標頭中的 Host 資訊從 www.example.com 替換為 store.example.com。

    2. 建立 HTTPRoute 資訊清單,並命名為 www.yaml:

        apiVersion: gateway.networking.k8s.io/v1
        kind: HTTPRoute
        metadata:
          name: www
        spec:
          parentRefs:
            - kind: Gateway
              name: external-http
          hostnames:
          - www.example.com
          rules:
          - filters:
            - type: URLRewrite
              # Replace the hostname in the URL with `store.example.com`.
              urlRewrite:
                hostname: store.example.com
            backendRefs:
            - name: store-v1
              port: 8080
      

      舉例來說,在上述設定中,任何傳送至 https://www.example.com 的要求都會轉送至具有 Host: store.example.com 標頭的後端服務,而不是 Host: www.example.com。

    3. 套用資訊清單:

        kubectl apply -f www.yaml
      

    使用路徑修飾符重新編寫

    您可以將重寫與路徑修飾符結合,在將要求轉送至後端服務之前,提供進階網址和路徑修改。

    如要使用路徑修飾符重新編寫,請按照下列步驟操作:

    1. 在 HTTPRoute 中設定篩選器,指示閘道將要求標頭中的「Host」資訊從 www.example.comto store.example.com 替換,並將值 /store 替換為 /,然後再將要求轉送至後端服務。

    2. 建立 HTTPRoute 資訊清單,並命名為 www.yaml:

        apiVersion: gateway.networking.k8s.io/v1
        kind: HTTPRoute
        metadata:
          name: www
        spec:
          parentRefs:
            - kind: Gateway
              name: external-http
          hostnames:
          - www.example.com
          rules:
          - matches:
            - path:
                type: PathPrefix
                value: /store
            filters:
            - type: URLRewrite
              # For URLs that have `/store` in the path, replace the hostname with
              # store.example.com and replace the `/store` prefix with `/de`.
              urlRewrite:
                hostname: store.example.com
                path:
                  type: ReplacePrefixMatch
                  replacePrefixMatch: /de
            backendRefs:
            - name: store-german
              port: 8080
      

      舉例來說,在上述設定中,任何傳送至 https://www.example.com/store/... 的要求都會轉送至後端服務,要求標頭中會包含 Host: store.example.com (而非 Host: www.example.com),且 /store 會重寫為 /de。

    3. 套用資訊清單:

      kubectl apply -f www.yaml
      

    使用規則運算式重寫

    您可以使用 GCPHTTPFilter 資源搭配 spec.urlRewrite.regexModifier,在將要求轉送至後端服務前,使用規則運算式重寫網址路徑。

    如要使用規則運算式重寫網址路徑,請按照下列步驟操作:

    1. 將下列資訊清單儲存為 store-regex-rewrite-filter.yaml:

      apiVersion: networking.gke.io/v1
      kind: GCPHTTPFilter
      metadata:
        name: store-regex-rewrite-filter
      spec:
        urlRewrite:
          regexModifier:
            pathPattern: /service1/
            pathSubstitution: /service2/
      

      這份資訊清單描述 GCPHTTPFilter,並包含下列屬性:

      • urlRewrite.regexModifier:使用規則運算式設定網址路徑重寫。
      • pathPattern:指定與要求網址路徑相符的 RE2 規則運算式,例如 /service1/([a-zA-Z0-9]+)。
      • pathSubstitution:指定用於取代相符網址路徑的替換字串,可參照 pathPattern 中的編號擷取群組,例如 /service2/\1。
    2. 將資訊清單套用至叢集:

      kubectl apply -f store-regex-rewrite-filter.yaml
      
    3. 將下列資訊清單儲存為 www-regex-rewrite.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: www-regex-rewrite
      spec:
        parentRefs:
        - kind: Gateway
          name: external-http
        hostnames:
        - www.example.com
        rules:
        - matches:
          - path:
              type: PathPrefix
              value: /service1/
          filters:
          - type: ExtensionRef
            extensionRef:
              group: networking.gke.io
              kind: GCPHTTPFilter
              name: store-regex-rewrite-filter
          backendRefs:
          - name: store-v1
            port: 8080
      

      這份資訊清單描述的 HTTPRoute 具有下列屬性:

      • extensionRef:參照上一步建立的 store-regex-rewrite-filter GCPHTTPFilter。
      • backendRefs:將重寫的要求轉送至 store-v1 服務。舉例來說,對 https://www.example.com/service1/item123 的要求會先重寫為 /service2/item123,再轉送至 store-v1 後端服務。
    4. 將資訊清單套用至叢集:

      kubectl apply -f www-regex-rewrite.yaml
      

    驗證您的設定

    如要確認篩選器是否已套用,請在使用網址重寫或路徑重新導向篩選器建立 HTTPRoute 後,執行下列操作:

    kubectl get httproute www -o yaml
    

    輸出結果會與下列內容相似:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        annotations:
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"gateway.networking.k8s.io/v1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
        creationTimestamp: "2023-06-22T01:00:42Z"
        generation: 3
        name: www
        namespace: default
        resourceVersion: "51268631"
        uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
      spec:
        hostnames:
        - www.example.com
        parentRefs:
        - group: gateway.networking.k8s.io
          kind: Gateway
          name: external-http
        rules:
        - backendRefs:
          - group: ""
            kind: Service
            name: store-german
            port: 8080
            weight: 1
          filters:
          - type: URLRewrite
            urlRewrite:
              hostname: store.example.com
              path:
                replacePrefixMatch: /de
                type: ReplacePrefixMatch
          matches:
          - path:
              type: PathPrefix
              value: /store
      status:
        parents:
        - conditions:
          - lastTransitionTime: "2023-06-22T01:11:26Z"
            message: ""
            observedGeneration: 2
            reason: Accepted
            status: "True"
            type: Accepted
          - lastTransitionTime: "2023-06-22T01:11:26Z"
            message: ""
            observedGeneration: 2
            reason: ReconciliationSucceeded
            status: "True"
            type: Reconciled
          controllerName: networking.gke.io/gateway
          parentRef:
            group: gateway.networking.k8s.io
            kind: Gateway
            name: external-http
    
    

    如要取得更多詳細資料,請使用 describe 指令:

    kubectl describe httproute
    

    設定跨源資源共享 (CORS)

    跨源資源共享 (CORS) 是一種安全機制,可協助在某個來源 (網域) 執行的網頁應用程式,安全存取託管於其他來源的資源。

    您可以使用 CORS 篩選器,直接在 HTTPRoute 資源中設定 CORS 政策。這種做法可讓負載平衡器插入適當的 CORS 回應標頭,並處理 CORS 預檢 (OPTIONS) 要求,減輕後端服務的負擔。

    設定 CORS 政策

    以下範例顯示 HTTPRoute 設有 CORS 篩選器,允許來自 https://www.example.com 的跨源要求使用特定方法和標頭:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: route-with-cors
      namespace: default
    spec:
      parentRefs:
      - name: my-gateway
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /api
        backendRefs:
        - name: my-backend
          port: 8080
        filters:
        - type: CORS
          cors:
            allowOrigins:
            - "https://www.example.com"
            allowMethods:
            - GET
            - POST
            - DELETE
            allowHeaders:
            - "x-request-header-1"
            - "x-request-header-2"
            exposeHeaders:
            - "x-response-header-a"
            - "x-response-header-b"
            allowCredentials: true
            maxAge: 3600
    

    cors 設定區塊支援下列欄位:

    • allowOrigins:允許的來源清單。支援 http 和 https 通訊協定。您可以使用下列任一格式指定這些來源:
      • 明確來源 (例如 https://www.example.com)。
      • 單一萬用字元 (*) 可允許所有來源。如果使用這個萬用字元,就無法指定其他來源。基於安全考量,我們強烈建議不要將 catch-all 萬用字元與 allowCredentials 設定結合 (詳情請參閱下方的欄位定義)。
      • 萬用字元模式 (例如 https://*.domain.com)。* 萬用字元必須緊接在配置 (http:// 或 https://) 後方,且後方必須接點 (例如 http://*.domain.com)、通訊埠 (例如 https://*:4433),或做為最後一個字元 (例如 http://*)。
    • allowMethods:CORS 要求允許的 HTTP 方法。支援萬用字元 (*),可允許所有方法。如果使用萬用字元,則無法指定其他方法。
    • allowHeaders:用戶端可傳送的 HTTP 標頭。支援萬用字元 (*),允許所有標頭。如果使用萬用字元,則無法指定其他標頭。
    • exposeHeaders:可安全向用戶端指令碼公開的 HTTP 標頭。支援萬用字元 (*),可公開所有標頭。
    • allowCredentials:控制瀏覽器是否能分享以憑證模式傳送的要求 (例如包含 Cookie 或 HTTP 驗證的要求) 的伺服器回應。預設為 false。設定這項功能時,請考量下列安全性層面:
      • 如果您將 * 萬用字元指定為 allowMethods、allowHeaders 或 exposeHeaders 欄位的值,瀏覽器會封鎖對憑證模式要求的任何回應。基於安全考量,即使 allowCredentials 欄位的值設為 true,系統仍會封鎖。
      • 如果 allowOrigins 包含 * 萬用字元,GKE Gateway 控制器不會將 * 萬用字元從 allowOrigins 欄位複製到回應標頭。因此,瀏覽器「不會」封鎖這類對憑證模式要求的回應,允許任何可能惡意的網站存取使用者資料。因此,我們強烈不建議使用下列設定:allowCredentials: true 和 allowOrigins 搭配萬用字元 *。
    • maxAge:指定瀏覽器可快取預檢回應的時間長度 (以秒為單位)。預設為 5 秒。值必須大於或等於 1。

    限制

    • 僅限單一叢集閘道:多叢集閘道不支援 CORS。
    • 與 RequestRedirect 不相容:您無法在同一路由規則中使用 CORS 篩選器和 RequestRedirect 篩選器。
    • 規則運算式限制:GKE Gateway 控制器會在內部將 allowOrigins 欄位值中的萬用字元模式表示為規則運算式。規則運算式的使用有限制,會影響 GatewayClass,如下所示:
      • 對於 gke-l7-global-external-managed GatewayClass,每個閘道監聽器只能使用一個規則運算式 (與其他功能共用)。這項限制適用於重複計算規則,也就是說,不支援將萬用字元模式與 PathPrefix 比對結合。
      • 如果是 gke-l7-regional-external-managed 和 gke-l7-rilb GatewayClass,每個主機名稱最多可以使用五個規則運算式 (與其他功能共用)。
      • 萬用字元 (*) 不計入這些限制。
      • CORS 篩選器中的單一萬用字元模式,可能會多次計入規則運算式限制。GKE Gateway 控制器會將 HTTPRoute 規則中的 CORS 篩選器,乘以該規則中的比對數量。此外,除非路徑為 /,否則 PathPrefix 類型的比對會計為兩次。

    如要進一步瞭解 Gateway API 中的標準 CORS 行為,請參閱上游 CORS 使用手冊。

    設定自訂要求和回應標頭

    您可以透過自訂要求和回應標頭,為 HTTP(S) 要求和回應指定其他標頭。視負載平衡器偵測到的資訊而定,這些標頭可能包含下列資訊:

    • 用戶端延遲時間
    • 用戶端 IP 位址的地理位置
    • TLS 連線參數

    根據預設,傳送至後端服務或從後端服務接收的要求不會新增自訂標頭,您必須使用 HTTPRoute 中的篩選器,明確設定自訂標頭。

    如要設定自訂標頭,請在 HTTPRoute 規則中新增篩選器部分,如下所示:

    設定自訂要求標頭

    建立含有 RequestHeaderModifier 篩選器的 HTTPRoute 資訊清單,並儲存為 http-route-request.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        <...>
        rules:
            filters:
              - type: RequestHeaderModifier
                requestHeaderModifier:
                  <...>
    

    套用資訊清單:

      kubectl apply -f http-route-request.yaml
    

    設定自訂回應標頭

    建立含有 ResponseHeaderModifier 篩選器的 HTTPRoute 資訊清單,並儲存為 http-route-response.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store
    spec:
      <...>
      rules:
          filters:
            - type: ResponseHeaderModifier
              responseHeaderModifier:
                <...>
    

    套用資訊清單:

      kubectl apply -f http-route-response.yaml
    

    您可以按照「Gateway API 實作」中的說明,新增、設定及移除標頭。您可以使用Google Cloud 支援的變數,為 HTTPRoute 設定自訂標頭。

    範例 1:

    如要設定 HTTPRoute,在將 HTTP 要求傳送至後端服務之前,先將用戶端位置資訊新增至 HTTP 要求,請建立 HTTPRoute 資訊清單,並命名為 external-http-request.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
          - matches:
            - path:
                type: PathPrefix
                value: /fr
            filters:
              # Add custom headers to requests that have `/fr` in the path.
              - type: RequestHeaderModifier
                requestHeaderModifier:
                  add:
                    - name: X-Client-Geo-Location
                      value: "{client_region},{client_city}"
            backendRefs:
              - name: store-french
                port: 8080
    

    舉例來說,如果用戶端位於法國史特拉斯堡,閘道會新增 X-Client-Geo-Location:FR,Strasbourg 標頭。

    範例 2:

    如要設定 HTTPRoute,新增自訂回應標頭來支援 HTTP 嚴格傳輸安全性,請建立 HTTPRoute 資訊清單,並命名為 external-http-response.yaml:

      apiVersion: gateway.networking.k8s.io/v1
      kind: HTTPRoute
      metadata:
        name: store
      spec:
        parentRefs:
          - kind: Gateway
            name: external-http
        hostnames:
        - store.example.com
        rules:
          - matches:
            - path:
                type: PathPrefix
                value: /de
            filters:
              # Add custom headers to responses to requests that have `/de` in the
              # path.
              - type: ResponseHeaderModifier
                responseHeaderModifier:
                  add:
                    - name: Strict-Transport-Security
                      value: max-age=63072000
            backendRefs:
              - name: store-german
                port: 8080
    

    驗證您的設定

    1. 設定自訂要求和回應標頭後,請按照下列步驟驗證設定:

        kubectl get httproute
      

      輸出結果會與下列內容相似:

        NAME    HOSTNAMES               AGE
        store   ["store.example.com"]   4d23h
      
    2. 如要取得更多詳細資料,請使用 describe 指令:

        kubectl describe httproute
      

      輸出結果會與下列內容相似:

        Name:         store
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  gateway.networking.k8s.io/v1
        Kind:         HTTPRoute
        Metadata:
          Creation Timestamp:  2023-05-27T00:51:01Z
          Generation:          5
          Resource Version:    25418887
          UID:                 2e07a1b8-420b-41b4-acd1-cecbfcd39f42
        Spec:
          Hostnames:
            store.example.com
          Parent Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   external-http
          Rules:
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-v1
              Port:    8080
              Weight:  1
            Matches:
              Path:
                Type:   PathPrefix
                Value:  /
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-v2
              Port:    8080
              Weight:  1
            Matches:
              Headers:
                Name:   env
                Type:   Exact
                Value:  canary
              Path:
                Type:   PathPrefix
                Value:  /
            Backend Refs:
              Group:
              Kind:    Service
              Name:    store-german
              Port:    8080
              Weight:  1
            Filters:
              Request Header Modifier:
                Add:
                  Name:   X-Client-Geo-Location
                  Value:  {client_region},{client_city}
              Type:       RequestHeaderModifier
            Matches:
              Path:
                Type:   PathPrefix
                Value:  /de
        Status:
          <...>
      

    設定規則運算式比對

    GKE Gateway 支援 HTTPRoute 路徑、查詢參數和標頭的規則運算式比對。您可以使用規則運算式定義彈性的路由規則。

    下列 GatewayClass 支援規則運算式比對:

    • gke-l7-global-external-managed
    • gke-l7-global-external-managed-mc
    • gke-l7-regional-external-managed
    • gke-l7-regional-external-managed-mc
    • gke-l7-rilb
    • gke-l7-rilb-mc
    • gke-l7-cross-regional-internal-managed-mc

    限制

    • RE2 語法:僅支援 RE2 語法。RE2 不支援前瞻、後顧或反向參照。
    • 配額與限制:
      • 規則運算式比對數量上限:每個路徑比對器 (HTTPRoute) 最多可設定五個規則運算式比對。
      • 長度上限:規則運算式的長度上限為 250 個半形字元。
    • 成效影響:規則運算式比對需要耗費大量運算資源。使用規則運算式比對器可能會增加要求延遲時間:
      • 一個規則運算式比對器:每個要求的延遲時間增加約 100 微秒。
      • 五個規則運算式比對器:每項要求的延遲時間增加約 200 微秒。

    設定路徑規則運算式比對

    如要使用規則運算式設定路徑比對,請在 path 比對規則中,將 type 欄位的值設為 RegularExpression。

    以下範例會將路徑與 /videos/hd.* 規則運算式相符 (例如 /videos/hd-123 或 /videos/hd-promo.mp4) 的要求轉送至 store-videos-hd 服務:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store-path-regex
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - path:
            type: RegularExpression
            value: /videos/hd.*
        backendRefs:
        - name: store-videos-hd
          port: 8080
    

    設定查詢參數規則運算式比對

    如要使用規則運算式比對查詢參數,請在 queryParams 比對規則中,將 type 欄位的值設為 RegularExpression。

    以下範例會將 param1 查詢參數與 .*param_value.*-hd 規則運算式相符的要求轉送至 android-hd 服務:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store-query-regex
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - queryParams:
          - name: param1
            type: RegularExpression
            value: .*param_value.*-hd
        backendRefs:
        - name: android-hd
          port: 8080
    

    設定標頭規則運算式比對

    如要使用規則運算式比對 HTTP 標頭,請在 headers 比對規則中,將 type 欄位的值設為 RegularExpression。

    以下範例會將 User-Agent 標頭與 .*Android.*-hd 規則運算式相符的要求轉送至 android-hd 服務:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store-header-regex
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - headers:
          - name: User-Agent
            type: RegularExpression
            value: .*Android.*-hd
        backendRefs:
        - name: android-hd
          port: 8080
    

    設定前端 mTLS

    為啟用用戶端憑證驗證,Google 應用程式負載平衡器提供前端 mTLS。如果是 GKE Gateway,您可以透過前端 mTLS,為所有支援的 GatewayClass 資源 (無論是全域或區域性) 設定及套用用戶端憑證驗證。詳情請參閱「設定閘道的前端 mTLS」。

    設定後端 TLS

    後端驗證 TLS 是一項安全防護功能,可讓 GKE Gateway 負載平衡器驗證連線後端的身分。如果是 GKE Gateway,這項功能可讓您設定後端憑證驗證,並套用至支援的 GatewayClass,例如全域或區域性外部代管負載平衡器,以及區域性內部負載平衡器。

    詳情請參閱「保護閘道」。

    如要要求閘道也向後端驗證自身身分 (mTLS),請在閘道資源上使用用戶端憑證。如需操作說明,請參閱「為閘道設定後端雙向傳輸層安全標準 (mTLS)」。

    路徑狀態

    HTTPRoute 資源會發出條件和事件,協助使用者瞭解 HTTPRoute 是否已成功繫結至一或多個閘道,或是否遭到拒絕。

    HTTPRoute 條件

    HTTPRoute 條件會指出路徑和繫結閘道的狀態。由於路徑可以繫結至多個閘道,因此這份清單會列出閘道,以及路徑與各閘道之間的個別條件。

    • Accepted=True 表示 HTTPRoute 已成功繫結至閘道。
    • Accepted=False 表示 HTTPRoute 已遭拒絕,無法與這個閘道繫結。

    如果 Gateway bindings 標題下方未列出任何閘道,表示 HTTPRoute 標籤和閘道標籤選取器可能不相符。如果沒有任何閘道選取路徑,就可能發生這種情況。

    HTTPRoute 事件

    HTTPRoute 事件會提供 HTTPRoute 狀態的詳細資料。事件會依下列原因分組:

    • 新增資源會觸發 ADD 事件。
    • UPDATE 事件是由資源更新觸發。
    • SYNC 事件是由定期對帳觸發。

    路徑合併、優先順序和驗證

    路由優先順序

    Gateway API 定義了嚴格的優先順序規則,用於決定路由規則重疊的路由如何比對流量。兩個重疊 HTTPRoute 之間的優先順序如下:

    1. 主機名稱合併:最長/最明確的主機名稱比對。
    2. 路徑合併:最長/最明確的路徑比對。
    3. 標頭合併:相符的 HTTP 標頭數量最多。
    4. 衝突:如果前三項規則無法建立優先順序,則優先順序會由時間戳記最舊的 HTTPRoute 資源取得。

    路徑合併

    如果是 gke-l7 GatewayClass,特定閘道的所有 HTTPRoute 都會合併至同一個網址對應資源。HTTPRoute 的合併方式取決於 HTTPRoute 之間的重疊類型。先前範例中的 HTTPRoute 可拆分為三個獨立的 HTTPRoute,以說明路由合併和優先順序:

    1. 路由合併:三個 HTTPRoute 都附加至同一個 internal-http 閘道,因此會合併在一起。
    2. 主機名稱合併:store.example.com 的三個路徑都相符,因此主機名稱規則會合併。
    3. 路徑合併:store-german-route 有更具體的路徑 /de,因此不會進一步合併。store-v1-route 和 store-v2-route 也都與相同的 /* 路徑相符,因此會合併到該路徑。
    4. 標頭合併:store-v2-route 的 HTTP 標頭比對條件比 store-v1-route 更具體,因此不會進一步合併。
    5. 衝突:由於路由可以依主機名稱、路徑和標頭合併,因此不會發生衝突,且所有路由規則都會套用至流量。

    先前範例中使用的單一 HTTPRoute 相當於下列三個獨立路徑:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-v1-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - kind: Service
          name: store-v1
          port: 8080
    ---
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-v2-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - headers:
          - type: Exact
            name: env
            value: canary
        backendRefs:
        - kind: Service
          name: store-v2
          port: 8080
    ---
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-german-route
    spec:
      parentRefs:
      - kind: Gateway
        name: internal-http
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /de
        backendRefs:
        - kind: Service
          name: store-german
          port: 8080
    

    Kubernetes 閘道和 Istio 閘道

    請注意,Kubernetes Gateway API 和 Istio API 都有名為 Gateway 的資源。雖然兩者執行的功能類似,但並非相同資源。如果您在同一個 Kubernetes 叢集中使用 Istio 和 Gateway API,在指令列上使用 kubectl 時,這些名稱會重疊。kubectl get gateway 可能會傳回 Kubernetes 閘道資源,而非 Istio 閘道資源,反之亦然。

    $ kubectl api-resources
    NAME       SHORTNAMES   APIGROUP                       NAMESPACED   KIND
    gateways   gw           networking.istio.io/v1beta1    true         Gateway
    gateways   gtw          networking.k8s.io/v1beta1      true         Gateway
    

    如果您使用 Istio 並升級至 GKE 1.20 以上版本,建議您開始使用閘道資源簡稱或指定 API 群組。Kubernetes 閘道的簡稱是 gtw,Istio 閘道的簡稱是 gw。下列指令會分別傳回 Kubernetes Gateway 和 Istio Gateway 資源。

    # Kubernetes Gateway
    $ kubectl get gtw
    NAME                        CLASS
    multi-cluster-gateway       gke-l7-global-external-managed-mc
    
    $ kubectl get gateway.networking.x-k8s.io
    NAME                        CLASS
    multi-cluster-gateway       gke-l7-global-external-managed-mc
    
    # Istio Gateway
    $ kubectl get gw
    NAME               AGE
    bookinfo-gateway   64m
    
    $ kubectl get gateway.networking.istio.io
    NAME               AGE
    bookinfo-gateway   64m
    

    疑難排解

    區域中缺少 Proxy 專用子網路

    問題:

    建立區域性閘道 (內部或外部) 時,可能會發生下列問題:

    generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.
    

    原因:

    這則錯誤訊息表示閘道所在區域沒有 Proxy 專用子網路。

    解決方法:

    如要解決這個問題,請設定僅限 Proxy 的子網路。

    該區域已有 Proxy 專用子網路,但用途不正確

    問題:

    為區域性閘道 (內部或外部) 建立 Proxy 專用子網路時,可能會發生下列問題:

    ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
     - The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists
    

    原因:

    這則錯誤訊息表示,您嘗試在已有僅限 Proxy 子網路的區域中,建立區域性僅限 Proxy 子網路。

    解決方法:

    如要解決這個問題,請按照下列步驟操作:

    1. 確認該區域中已有 Proxy 專用子網路,且用途正確:

      1. 列出子網路,找出該區域中的 Proxy 專用子網路:

        gcloud compute networks subnets list --regions=COMPUTE_REGION
        

        將 COMPUTE_REGION 替換為要建立區域性閘道的 Compute Engine 區域。

      2. 描述該區域中的 Proxy 專用子網路,找出其用途:

        gcloud compute networks subnets describe PROXY_ONLY_SUBNET \
            --region COMPUTE_REGION | grep -E 'name|purpose'
        

        將 PROXY_ONLY_SUBNET 替換為 Proxy 專用子網路。

      GKE Gateway 僅支援區域性閘道 (內部或區域性) 的 REGIONAL_MANAGED_PROXY 僅限 Proxy 子網路。

    2. 如果該區域現有的 Proxy 專用子網路是以 INTERNAL_HTTPS_LOAD_BALANCER 用途建立,請將用途遷移至 REGIONAL_MANAGED_PROXY。

    沒有健康狀態良好的上游

    問題:

    建立閘道時,可能會發生下列問題,導致無法存取後端服務 (503 回應代碼):

    no healthy upstream
    

    原因:

    這則錯誤訊息表示健康狀態檢查探測器找不到健康的後端服務。後端服務可能健康狀態良好,但您可能需要自訂健康狀態檢查。

    解決方法:

    如要解決這個問題,請使用 HealthCheckPolicy,根據應用程式的需求 (例如 /health) 自訂健康狀態檢查。

    叢集刪除後,閘道資源成為孤立資源

    問題:

    嘗試重新建立閘道時,GKE 代管的負載平衡器資源仍會顯示在 Google Cloud 控制台中,但無法透過使用者介面刪除,並會顯示類似下列的訊息:

    This load balancing service is read-only. It is managed by GKE and can be modified only by GKE.
    

    原因:

    在刪除及重新建立叢集或閘道時,如果閘道控制器無法清除過時的基礎 Google Cloud 資源,就會發生這個問題。

    解決方法:

    如要解決這個問題,請使用 Google Cloud CLI 指令刪除孤立的負載平衡資源,如下所示:

    
    gcloud compute forwarding-rules delete FORWARDING_RULE_NAME
    
    # For HTTP proxies
    gcloud compute target-http-proxies delete PROXY_NAME
    
    # For HTTPS proxies
    gcloud compute target-https-proxies delete PROXY_NAME
    
    gcloud compute url-maps delete URL_MAP_NAME
    
    # For global backend services
    gcloud compute backend-services delete BACKEND_SERVICE_NAME --global
    
    # For regional backend services
    gcloud compute backend-services delete BACKEND_SERVICE_NAME --region=REGION
    
    gcloud compute health-checks delete HEALTH_CHECK_NAME
    
    gcloud compute network-endpoint-groups delete NEG_NAME --zone=ZONE
    
    

    更改下列內容:

    • FORWARDING_RULE_NAME:轉送規則的名稱。
    • PROXY_NAME:目標 Proxy 的名稱。
    • URL_MAP_NAME:網址對應的名稱。
    • BACKEND_SERVICE_NAME:後端服務的名稱。
    • HEALTH_CHECK_NAME:健康狀態檢查的名稱。
    • NEG_NAME:網路端點群組的名稱。
    • REGION:區域性後端服務的區域。
    • ZONE:網路端點群組的可用區。

    後續步驟