部署橫跨多個叢集的 Ingress

本頁說明如何部署 Ingress,在多個 GKE 叢集中為應用程式提供服務。如要進一步瞭解多叢集 Ingress,請參閱多叢集 Ingress。

如要詳細比較多叢集 Ingress (MCI)、多叢集閘道 (MCG) 和具備獨立網路端點群組的負載平衡器 (LB 和獨立 NEG),請參閱「為 GKE 選擇多叢集負載平衡 API」。

事前準備

本文假設您已在機群中建立叢集,並按照「設定多叢集 Ingress」一文所述,將 gke-us 叢集設為多叢集 Ingress 的設定叢集。如要驗證這個叢集設定,請按照下列步驟操作:

  1. 確認專案有兩個叢集,且這兩個叢集是機群的成員:

    gcloud container clusters list \
        --format="table(name, location, fleet.project:label=FLEET, status)" \
        --project=FLEET_HOST_PROJECT
    

    將 FLEET_HOST_PROJECT 替換為機群主專案的專案 ID。

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

    NAME      LOCATION          FLEET                                   STATUS
    gke-eu    europe-west1      FLEET_NAME   RUNNING
    gke-us    us-central1       FLEET_NAME   RUNNING
    

    在這個輸出內容中,FLEET_NAME 是車隊的名稱。

  2. 連線至 gke-us 設定叢集:

    gcloud container clusters get-credentials gke-us \
        --location=us-central1 \
        --project=CLUSTER_PROJECT
    

    將 CLUSTER_PROJECT 替換為包含 gke-us 叢集的專案 ID。

  3. 確認多叢集 Ingress 的 Kubernetes CustomResourceDefinitions 已安裝在 gke-us 叢集中:

    kubectl get crds | grep multicluster
    

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

    multiclusteringresses.networking.gke.io       2026-05-12T16:39:52Z
    multiclusterservices.networking.gke.io        2026-05-12T16:39:53Z
    

    如果輸出內容空白,請停用並啟用機群的多叢集 Ingress:

    1. 停用多叢集 Ingress:

      gcloud container fleet ingress disable \
          --project=FLEET_HOST_PROJECT
      
    2. 為機群啟用多叢集 Ingress,並將 gke-us 叢集指定為設定叢集:

      gcloud container fleet ingress enable \
          --config-membership=gke-us \
          --location=us-central1 \
          --project=CLUSTER_PROJECT
      

      啟用多叢集 Ingress 後,請執行 kubectl get crds 指令,確認 CustomResourceDefinitions 已安裝在 gke-us 叢集中。

部署教學課程

在下列工作中,您會在兩個叢集中部署名為 whereami 的虛構應用程式和 MultiClusterIngress。Ingress 會為應用程式部署作業提供共用的虛擬 IP (VIP) 位址。

建立命名空間

由於機群具有命名空間相同的屬性,建議您協調叢集間的命名空間建立和管理作業,確保相同的命名空間由同一群組擁有及管理。您可以依團隊、環境、應用程式或應用程式元件建立命名空間。命名空間可以視需要精細,只要一個叢集中的命名空間 ns1 與另一個叢集中的 ns1 具有相同的意義和用途即可。

在本範例中,您會為每個叢集中的每個應用程式建立 whereami 命名空間。

  1. 建立名為 namespace.yaml 的檔案,並加入以下內容:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: whereami
    
  2. 切換至 gke-us 環境:

    kubectl config use-context gke-us
    
  3. 建立命名空間:

    kubectl apply -f namespace.yaml
    
  4. 切換至 gke-eu 環境:

    kubectl config use-context gke-eu
    
  5. 建立命名空間:

    kubectl apply -f namespace.yaml
    

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

    namespace/whereami created
    

部署應用程式

  1. 建立名為 deploy.yaml 的檔案,並加入以下內容:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: whereami-deployment
      namespace: whereami
      labels:
        app: whereami
    spec:
      selector:
        matchLabels:
          app: whereami
      template:
        metadata:
          labels:
            app: whereami
        spec:
          containers:
          - name: frontend
            image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            ports:
            - containerPort: 8080
    
  2. 切換至 gke-us 情境:

    kubectl config use-context gke-us
    
  3. 部署 whereami 應用程式:

    kubectl apply -f deploy.yaml
    
  4. 切換至 gke-eu 環境:

    kubectl config use-context gke-eu
    
  5. 部署 whereami 應用程式:

    kubectl apply -f deploy.yaml
    
  6. 確認 whereami 應用程式已成功部署至各個叢集:

    kubectl get deployment --namespace whereami
    

    兩個叢集的輸出內容應大致如下:

    NAME           READY   UP-TO-DATE   AVAILABLE   AGE
    whereami-deployment   1/1     1            1           12m
    

透過設定叢集部署

應用程式已部署至 gke-us 和 gke-eu,接著您將在設定叢集中部署 MultiClusterIngress 和 MultiClusterService 資源,藉此部署負載平衡器。這些是 Ingress 和 Service 資源的多叢集對等項目。

在設定指南中,您已將 gke-us 叢集設定為設定叢集。設定叢集用於在所有叢集部署及設定 Ingress。

  1. 將環境設為設定叢集。

    kubectl config use-context gke-us
    

MultiClusterService

  1. 建立名為 mcs.yaml 的檔案,並加入下列內容:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    
  2. 部署與 whereami 應用程式相符的 MultiClusterService 資源:

    kubectl apply -f mcs.yaml
    
  3. 確認 whereami-mcs 資源已成功部署至設定叢集:

    kubectl get mcs -n whereami
    

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

    NAME       AGE
    whereami-mcs   9m26s
    

    這項操作會在每個叢集中建立衍生無頭 Service,並將 Pod 與 app: whereami 相符。MultiClusterService您可以看到 gke-us 叢集 kubectl get service -n whereami 中有一個。

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

    NAME                                TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
    mci-whereami-mcs-svc-lgq966x5mxwwvvum   ClusterIP   None          <none>        8080/TCP         4m59s
    

gke-eu 中也會有類似的無頭 Service。這些本機 Service 可用於動態選取 Pod 端點,以便透過後端設定全域 Ingress 負載平衡器。

MultiClusterIngress

  1. 建立名為 mci.yaml 的檔案,並加入以下內容:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
    

    請注意,這項設定會將所有流量轉送至 whereami 命名空間中名為 MultiClusterService 的 whereami-mcs。

  2. 部署參照 whereami-mcs 做為後端的 MultiClusterIngress 資源:

    kubectl apply -f mci.yaml
    

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

    multiclusteringress.networking.gke.io/whereami-ingress created
    

    請注意,MultiClusterIngress 的結構定義與 Kubernetes Ingress 相同。 除了 backend.serviceName 欄位外,Ingress 資源語意也相同。

MultiClusterIngress 中的 backend.serviceName 欄位會參照 Fleet API 中的 MultiClusterService,而不是 Kubernetes 叢集中的 Service。也就是說,您可以使用相同方式設定 Ingress 的任何設定,例如 TLS 終止設定。

驗證部署狀態是否成功

Google Cloud 新的負載平衡器可能需要幾分鐘才能完成部署。更新現有負載平衡器時,由於不需要部署新資源,因此完成速度較快。MultiClusterIngress 資源詳細說明代表 MultiClusterIngress 建立的基礎 Compute Engine 資源。

  1. 確認部署成功:

    kubectl describe mci whereami-ingress -n whereami
    

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

    Name:         whereami-ingress
    Namespace:    whereami
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"networking.gke.io/v1","kind":"MultiClusterIngress","metadata":{"annotations":{},"name":"whereami-ingress","namespace":"whe...
    API Version:  networking.gke.io/v1
    Kind:         MultiClusterIngress
    Metadata:
      Creation Timestamp:  2020-04-10T23:35:10Z
      Finalizers:
        mci.finalizer.networking.gke.io
      Generation:        2
      Resource Version:  26458887
      Self Link:         /apis/networking.gke.io/v1/namespaces/whereami/multiclusteringresses/whereami-ingress
      UID:               62bec0a4-8a08-4cd8-86b2-d60bc2bda63d
    Spec:
      Template:
        Spec:
          Backend:
            Service Name:  whereami-mcs
            Service Port:  8080
    Status:
      Cloud Resources:
        Backend Services:
          mci-8se3df-8080-whereami-whereami-mcs
        Firewalls:
          mci-8se3df-default-l7
        Forwarding Rules:
          mci-8se3df-fw-whereami-whereami-ingress
        Health Checks:
          mci-8se3df-8080-whereami-whereami-mcs
        Network Endpoint Groups:
          zones/europe-west1-b/networkEndpointGroups/k8s1-e4adffe6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-88670678
          zones/us-central1-b/networkEndpointGroups/k8s1-a6b112b6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-609ab6c6
        Target Proxies:
          mci-8se3df-whereami-whereami-ingress
        URL Map:  mci-8se3df-whereami-whereami-ingress
      VIP:        34.98.102.37
    Events:
      Type    Reason  Age                    From                              Message
      ----    ------  ----                   ----                              -------
      Normal  ADD     3m35s                  multi-cluster-ingress-controller  whereami/whereami-ingress
      Normal  UPDATE  3m10s (x2 over 3m34s)  multi-cluster-ingress-controller  whereami/whereami-ingress
    

    有幾個欄位會指出這項 Ingress 部署作業的狀態:

    • Events 是首要查看的項目。如果發生錯誤,就會列在這裡。

    • Cloud Resource會列出由多叢集 Ingress 控制器建立的 Compute Engine 資源,例如轉送規則、後端服務和防火牆規則。如果沒有列出這些項目,表示尚未建立。您可以使用 Google Cloud 控制台或 gcloud 指令檢查個別 Compute Engine 資源,瞭解資源狀態。

    • 如果已分配 IP 位址,VIP 會列出該位址。請注意,即使 VIP 存在,負載平衡器可能尚未處理流量。如果幾分鐘後仍未看到 VIP,或負載平衡器未在 10 分鐘內提供 200 回應,請參閱「疑難排解和作業」。

    如果輸出事件為 Normal,則 MultiClusterIngress 部署作業可能成功,但要判斷完整流量路徑是否正常運作,唯一的方法是進行測試。

  2. 使用 /ping 端點,驗證應用程式是否在 VIP 上提供服務:

    curl INGRESS_VIP/ping
    

    將 INGRESS_VIP 替換為虛擬 IP (VIP) 位址。

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

    {
    "cluster_name": "gke-us",
    "host_header": "34.120.175.141",
    "pod_name": "whereami-deployment-954cbf78-mtlpf",
    "pod_name_emoji": "😎",
    "project_id": "my-project",
    "timestamp": "2021-11-29T17:01:59",
    "zone": "us-central1-b"
    }
    

    輸出內容應會指出應用程式的區域和後端。

  3. 您也可以在瀏覽器中前往 http://INGRESS_VIP URL,查看應用程式的圖形版本,瞭解應用程式的服務區域。

    系統會根據您的位置,將流量轉送至對應的叢集。GCLB 的設計宗旨是將用戶端流量轉送至距離最近且有容量的可用後端。

資源規格

MultiClusterService 規格

MultiClusterService 定義包含兩部分:

  1. template 區段,用於定義要在 Kubernetes 叢集中建立的 Service。請注意,雖然 template 區段包含一般 Service 支援的欄位,但 MultiClusterService 僅支援兩個欄位:selector 和 ports。系統會忽略其他欄位。

  2. 選用的 clusters 區段,可定義哪些叢集會接收流量,以及每個叢集的負載平衡屬性。如未指定 clusters 區段,或未列出任何叢集,系統預設會使用所有叢集。

以下資訊清單說明標準 MultiClusterService:

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      selector:
        app: POD_LABEL
      ports:
      - name: web
        protocol: TCP
        port: PORT
        targetPort: TARGET_PORT

更改下列內容:

  • NAME:MultiClusterService 的名稱。MultiClusterIngress 資源中的 serviceName 欄位會參照這個名稱。
  • NAMESPACE:部署 MultiClusterService 的 Kubernetes 命名空間。 必須與機群中所有叢集的 MultiClusterIngress 和 Pod 位於同一個命名空間。
  • POD_LABEL:這個標籤會決定要選取哪些 Pod 做為機群中所有叢集的 MultiClusterService 後端。
  • PORT:必須與參照這個 MultiClusterService 的 MultiClusterIngress 所參照的通訊埠相符。
  • TARGET_PORT:用於將流量從 GCLB 傳送至 Pod 的通訊埠。系統會在每個叢集中建立 NEG,並將這個通訊埠做為服務通訊埠。

MultiClusterIngress 規格

以下 mci.yaml 說明負載平衡器前端:

apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
  name: NAME
  namespace: NAMESPACE
spec:
  template:
    spec:
      backend:
       serviceName: DEFAULT_SERVICE
       servicePort: PORT
      rules:
        - host: HOST_HEADER
          http:
            paths:
            - path: PATH
              backend:
                serviceName: SERVICE
                servicePort: PORT

更改下列內容:

  • NAME:MultiClusterIngress 資源的名稱。
  • NAMESPACE:部署 MultiClusterIngress 的 Kubernetes 命名空間。它必須與機群中所有叢集的 MultiClusterService 和 Pod 位於同一個命名空間。
  • DEFAULT_SERVICE:對於不符合任何主機或路徑規則的所有流量,這個後端會做為預設後端。這是必填欄位,即使已設定其他主機或路徑相符項目,也必須在 MultiClusterIngress 中指定預設後端。
  • PORT:任何有效的通訊埠號碼。這必須與 MultiClusterService 資源的 port 欄位相符。
  • HOST_HEADER:依據 HTTP 主機標頭欄位比對流量。host 欄位為選填。
  • PATH:依據 HTTP 網址的路徑比對流量。path 欄位為選填欄位。
  • SERVICE:部署在與這個 MultiClusterIngress 相同命名空間和設定叢集的 MultiClusterService 名稱。

多叢集 Ingress 功能

本節說明如何設定其他多叢集 Ingress 功能。

選取叢集

根據預設,衍生自多叢集 Ingress 的服務會排定在每個成員叢集上。不過,您可能需要將輸入規則套用至特定叢集。部分用途包括:

  • 將多叢集 Ingress 套用至所有叢集,但設定叢集除外,以隔離設定叢集。
  • 以藍綠部署方式在叢集之間遷移工作負載。
  • 將流量轉送至僅存在於部分叢集的應用程式後端。
  • 使用單一 L7 VIP,將主機或路徑路由至不同叢集上的後端。

叢集選取功能可讓您在 MultiClusterService 物件中,依區域或名稱選取叢集。這會控制MultiClusterIngress指向的叢集,以及衍生服務的排程位置。同一機群和區域內的叢集名稱不得重複,這樣才能確保叢集參照的唯一性。

  1. 開啟「mcs.yaml」

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
    

    這項規格會在所有叢集中建立衍生服務,這是預設行為。

  2. 在 clusters 區段中附加下列幾行:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterService
    metadata:
      name: whereami-mcs
      namespace: whereami
    spec:
      template:
        spec:
          selector:
            app: whereami
          ports:
          - name: web
            protocol: TCP
            port: 8080
            targetPort: 8080
      clusters:
      - link: "us-central1-b/gke-us"
      - link: "europe-west1-b/gke-eu"
    

    這個範例只會在 gke-us 和 gke-eu 叢集中建立衍生服務資源。必須選取叢集,才能選擇性套用輸入規則。如果未指定 MultiClusterService 的「clusters」部分,或未列出任何叢集,系統會解讀為預設的「all」叢集。

支援 HTTPS

Kubernetes Secret 支援 HTTPS。啟用 HTTPS 支援前,必須先建立靜態 IP 位址。這個靜態 IP 可讓 HTTP 和 HTTPS 共用同一個 IP 位址。詳情請參閱「建立靜態 IP」。

建立靜態 IP 位址後,即可建立 Secret。

  1. 建立 Secret:

    kubectl -n whereami create secret tls SECRET_NAME --key PATH_TO_KEYFILE --cert PATH_TO_CERTFILE
    

    更改下列內容:

    • 將 SECRET_NAME 替換為 Secret 名稱。
    • PATH_TO_KEYFILE,並提供 TLS 金鑰檔案的路徑。
    • PATH_TO_CERTFILE,並提供 TLS 憑證檔案的路徑。
  2. 使用 Secret 名稱更新 mci.yaml 檔案:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
      annotations:
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    

    將 SECRET_NAME 替換為您的 Secret 名稱。 STATIC_IP_ADDRESS 是您在「建立靜態 IP」一節中分配的 IP 位址或完整網址。

  3. 重新部署 MultiClusterIngress 資源:

    kubectl apply -f mci.yaml
    

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

    multiclusteringress.networking.gke.io/whereami-ingress configured
    

支援 BackendConfig

您可以使用下列 BackendConfig CRD 自訂 Compute Engine BackendService 資源的設定:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: whereami-health-check-cfg
  namespace: whereami
spec:
  healthCheck:
    checkIntervalSec: [int]
    timeoutSec: [int]
    healthyThreshold: [int]
    unhealthyThreshold: [int]
    type: [HTTP | HTTPS | HTTP2 | TCP]
    port: [int]
    requestPath: [string]
  timeoutSec: [int]
  connectionDraining:
    drainingTimeoutSec: [int]
  sessionAffinity:
    affinityType: [CLIENT_IP | CLIENT_IP_PORT_PROTO | CLIENT_IP_PROTO | GENERATED_COOKIE | HEADER_FIELD | HTTP_COOKIE | NONE]
    affinityCookieTtlSec: [int]
  cdn:
    enabled: [bool]
    cachePolicy:
      includeHost: [bool]
      includeQueryString: [bool]
      includeProtocol: [bool]
      queryStringBlacklist: [string list]
      queryStringWhitelist: [string list]
  securityPolicy:
    name: ca-how-to-security-policy
  logging:
    enable: [bool]
    sampleRate: [float]
  iap:
    enabled: [bool]
    oauthclientCredentials:
      secretName: [string]

如要使用 BackendConfig,請透過註解將其附加至 MultiClusterService 資源:

apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
  name: whereami-mcs
  namespace: whereami
  annotations:
    cloud.google.com/backend-config: '{"ports": {"8080":"whereami-health-check-cfg"}}'
spec:
 template:
   spec:
     selector:
       app: whereami
     ports:
     - name: web
       protocol: TCP
       port: 8080
       targetPort: 8080

如要進一步瞭解 BackendConfig 語意,請參閱「將服務通訊埠與 BackendConfig 建立關聯」。

gRPC 支援

在多叢集 Ingress 上設定 gRPC 應用程式時,需要非常具體的設定。以下是一些訣竅,可確保負載平衡器設定正確無誤:

  1. 確認從負載平衡器傳送至應用程式的流量為 HTTP/2。如要設定這項功能,請使用應用程式通訊協定。
  2. 請確認應用程式已正確設定 SSL,因為這是 HTTP/2 的必要條件。請注意,使用自行簽署的憑證是可以接受的。
  3. 您必須關閉應用程式的 mTLS,因為 L7 外部負載平衡器不支援 mTLS。

資源生命週期

設定變更

MultiClusterIngress 和 MultiClusterService 資源的行為與標準 Kubernetes 物件相同,因此對物件所做的變更會以非同步方式反映在系統中。如果變更導致設定無效,相關聯的Google Cloud 物件會維持不變,並在物件事件串流中引發錯誤。與設定相關的錯誤會以事件形式回報。

管理 Kubernetes 資源

刪除 Ingress 物件會拆除 HTTP(S) 負載平衡器,因此流量不會再轉送至任何定義的 MultiClusterService。

刪除 MultiClusterService 會移除每個叢集中的相關衍生服務。

管理叢集

如要變更負載平衡器鎖定的叢集組合,請在機群中新增或移除叢集。

例如,如要移除 gke-eu 叢集做為 ingress 的後端,請執行:

gcloud container fleet memberships unregister CLUSTER_NAME \
  --gke-uri=URI

更改下列內容:

  • CLUSTER_NAME:叢集名稱。
  • URI:GKE 叢集的 URI。

如要在歐洲新增叢集,請執行下列指令:

gcloud container fleet memberships register europe-cluster \
  --context=europe-cluster --enable-workload-identity

如要進一步瞭解叢集註冊選項,請參閱「註冊 GKE 叢集」。

請注意,註冊或取消註冊叢集會變更所有 Ingress 的後端狀態。取消註冊 gke-eu 叢集會將其從您建立的所有 Ingress 可用後端中移除。註冊新叢集時則相反。

停用多叢集 Ingress

停用多叢集 Ingress 前,請務必先刪除 MultiClusterIngress 和 MultiClusterService 資源,並確認所有相關聯的網路資源都已刪除。

接著,如要停用多叢集 Ingress,請使用下列指令:

gcloud container fleet ingress disable

如果未先刪除 MultiClusterIngress 和 MultiClusterService 資源,就停用多叢集 Ingress,可能會發生類似下列情況的錯誤:

Feature has associated resources that should be cleaned up before deletion.

如要強制停用多叢集 Ingress,請使用下列指令:

gcloud container fleet ingress disable --force

註解

MultiClusterIngress 和 MultiClusterService 資源支援下列註解。

MultiClusterIngress 註解

註解 說明
networking.gke.io/frontend-config 參照與 MultiClusterIngress 資源位於相同命名空間的 FrontendConfig 資源。
networking.gke.io/static-ip 指全域靜態 IP 的實際 IP 位址。
networking.gke.io/pre-shared-certs 指全域 SSLCertificate 資源。

MultiClusterService 註解

註解 說明
networking.gke.io/app-protocols 使用這個註解設定負載平衡器與應用程式之間的通訊協定。可用的通訊協定包括 HTTP、HTTPS 和 HTTP/2。 請參閱「負載平衡器與應用程式之間的 HTTPS」和「使用 Ingress 進行負載平衡的 HTTP/2」。
cloud.google.com/backend-config 使用這個註解設定與 servicePort 相關聯的後端服務。詳情請參閱「輸入設定」。

SSL 政策和 HTTPS 重新導向

您可以使用 FrontendConfig 資源設定 SSL 政策和 HTTPS 重新導向。您可以透過 SSL 政策,指定負載平衡器接受的加密套件和 TLS 版本。HTTPS 重新導向可強制將 HTTP 或通訊埠 80 重新導向至 HTTPS 或通訊埠 443。下列步驟會一併設定 SSL 政策和 HTTPS 重新導向。請注意,這些設定也可以獨立設定。

  1. 建立 SSL 政策,拒絕使用低於 TLS v1.2 版本的請求。

    gcloud compute ssl-policies create tls-12-policy \
     --profile MODERN \
     --min-tls-version 1.2 \
     --project=PROJECT_ID
    

    將 PROJECT_ID 替換為 GKE 叢集執行所在的專案 ID。

  2. 查看政策,確認政策已建立完成。

    gcloud compute ssl-policies list --project=PROJECT_ID
    

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

    NAME           PROFILE  MIN_TLS_VERSION
    tls-12-policy  MODERN   TLS_1_2
    
  3. 如範例所示,為 foo.example.com 建立憑證。取得 key.pem 和 cert.pem 後,請將這些憑證儲存為 Secret,供 MultiClusterIngress 資源參照。

    kubectl -n whereami create secret tls SECRET_NAME --key key.pem --cert cert.pem
    
  4. 將下列 FrontendConfig 資源儲存為 frontendconfig.yaml。如要進一步瞭解 FrontendConfig 中支援的欄位,請參閱「設定 FrontendConfig 資源」。

    apiVersion: networking.gke.io/v1beta1
    kind: FrontendConfig
    metadata:
      name: frontend-redirect-tls-policy
      namespace: whereami
    spec:
      sslPolicy: tls-12-policy
      redirectToHttps:
        enabled: true
    

    這個 FrontendConfig 會啟用 HTTPS 重新導向,並強制執行最低 TLS 版本 1.2 的 SSL 政策。

  5. 將 frontendconfig.yaml 部署至設定叢集。

    kubectl apply -f frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    

    將 MCI_CONFIG_CLUSTER 替換為設定叢集的名稱。

  6. 將下列 MultiClusterIngress 儲存為 mci-frontendconfig.yaml。

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: foo-ingress
      namespace: whereami
      annotations:
        networking.gke.io/frontend-config: frontend-redirect-tls-policy
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: default-backend
            servicePort: 8080
          rules:
          - host: foo.example.com
            http:
              paths:
                - backend:
                    serviceName: whereami-mcs
                    servicePort: 8080
          tls:
          - secretName: SECRET_NAME
    
    • 將 STATIC_IP_ADDRESS 替換為您已佈建的靜態全域 IP 位址。
    • 將 SECRET_NAME 替換為儲存 foo.example.com 憑證的 Secret。

    啟用 HTTPS 重新導向時,必須符合兩項條件:

    • 必須透過 spec.tls 欄位或預先共用的憑證註解 networking.gke.io/pre-shared-certs 啟用 TLS。如果啟用 HTTPS 重新導向功能,但未啟用 HTTPS,系統就不會部署 MultiClusterIngress。
    • 靜態 IP 必須透過 networking.gke.io/static-ip 註解參照。在 MultiClusterIngress 上啟用 HTTPS 時,必須使用靜態 IP。
  7. 將 MultiClusterIngress 部署至設定叢集。

    kubectl apply -f mci-frontendconfig.yaml --context MCI_CONFIG_CLUSTER
    
  8. 等待一兩分鐘,然後檢查 foo-ingress。

    kubectl describe mci foo-ingress --context MCI_CONFIG_CLUSTER
    

    如果成功生成嵌入,輸出結果會與下列內容相似:

    • Cloud Resources 狀態會填入資源名稱
    • VIP 欄位會填入負載平衡器 IP 位址
    Name:         foobar-ingress
    Namespace:    whereami
    
    ...
    
    Status:
      Cloud Resources:
        Backend Services:
          mci-otn9zt-8080-whereami-bar
          mci-otn9zt-8080-whereami-default-backend
          mci-otn9zt-8080-whereami-foo
        Firewalls:
          mci-otn9zt-default-l7
        Forwarding Rules:
          mci-otn9zt-fw-whereami-foobar-ingress
          mci-otn9zt-fws-whereami-foobar-ingress
        Health Checks:
          mci-otn9zt-8080-whereami-bar
          mci-otn9zt-8080-whereami-default-backend
          mci-otn9zt-8080-whereami-foo
        Network Endpoint Groups:
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluste-mci-default-backend-svc--80-9e362e3d
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-bar-svc-067a3lzs8-808-89846515
          zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-foo-svc-820zw3izx-808-8bbcb1de
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluste-mci-default-backend-svc--80-a528cc75
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-bar-svc-067a3lzs8-808-36281739
          zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-foo-svc-820zw3izx-808-ac733579
        Target Proxies:
          mci-otn9zt-whereami-foobar-ingress
          mci-otn9zt-whereami-foobar-ingress
        URL Map:  mci-otn9zt-rm-whereami-foobar-ingress
      VIP:        34.149.29.76
    Events:
      Type     Reason  Age                From                              Message
      ----     ------  ----               ----                              -------
      Normal   UPDATE  38m (x5 over 62m)  multi-cluster-ingress-controller  whereami/foobar-ingress
    
  9. 透過 curl 傳送 HTTP 要求,確認 HTTPS 重新導向功能是否正常運作。

    curl VIP
    

    將 VIP 替換為 MultiClusterIngress IP 位址。

    輸出內容應顯示要求已重新導向至 HTTPS 通訊埠,表示重新導向功能正常運作。

  10. 使用 TLS 1.1 版傳送 HTTPS 要求,確認 TLS 政策運作正常。由於這個網域未設定 DNS,請使用 --resolve 選項,告知 curl 直接解析 IP 位址。

    curl https://foo.example.com --resolve foo.example.com:443:VIP --cacert CERT_FILE -v
    

    這個步驟需要提供用於保護 MultiClusterIngress 的憑證 PEM 檔案。如果成功,輸出內容大致如下:

    ...
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=foo.example.com
    *  start date: Sep  1 10:32:03 2021 GMT
    *  expire date: Aug 27 10:32:03 2022 GMT
    *  common name: foo.example.com (matched)
    *  issuer: O=example; CN=foo.example.com
    *  SSL certificate verify ok.
    * Using HTTP2, server supports multi-use
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * Using Stream ID: 1 (easy handle 0x7fa10f00e400)
    > GET / HTTP/2
    > Host: foo.example.com
    > User-Agent: curl/7.64.1
    > Accept: */*
    >
    * Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
    < HTTP/2 200
    < content-type: application/json
    < content-length: 308
    < access-control-allow-origin: *
    < server: Werkzeug/1.0.1 Python/3.8.6
    < date: Wed, 01 Sep 2021 11:39:06 GMT
    < via: 1.1 google
    < alt-svc: clear
    <
    {"cluster_name":"gke-us","host_header":"foo.example.com","metadata":"foo","node_name":"gke-gke-us-default-pool-22cb07b1-r5r0.c.mark-church-project.internal","pod_name":"foo-75ccd9c96d-dkg8t","pod_name_emoji":"👞","project_id":"mark-church-project","timestamp":"2021-09-01T11:39:06","zone":"us-central1-b"}
    * Connection #0 to host foo.example.com left intact
    * Closing connection 0
    

    回應代碼為 200,且使用的是 TLSv1.2,表示一切運作正常。

    接著,您可以嘗試使用 TLS 1.1 連線,確認 SSL 政策強制執行正確的 TLS 版本。您必須將 SSL 政策的最低版本設為 1.2,這個步驟才能正常運作。

  11. 傳送與上一步相同的要求,但強制使用 TLS 1.1 版。

    curl https://foo.example.com --resolve foo.example.com:443:VIP -v \
      --cacert CERT_FILE \
      --tls-max 1.1
    

    如果成功,輸出內容大致如下:

    * Added foo.example.com:443:34.149.29.76 to DNS cache
    * Hostname foo.example.com was found in DNS cache
    *   Trying 34.149.29.76...
    * TCP_NODELAY set
    * Connected to foo.example.com (34.149.29.76) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: cert.pem
      CApath: none
    * TLSv1.1 (OUT), TLS handshake, Client hello (1):
    * TLSv1.1 (IN), TLS alert, protocol version (582):
    * error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    * Closing connection 0
    curl: (35) error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
    

    如果無法完成 TLS 握手,表示 SSL 政策已成功封鎖 TLS 1.1。

建立靜態 IP

  1. 分配靜態 IP:

    gcloud compute addresses create ADDRESS_NAME --global
    

    將 ADDRESS_NAME 替換為要分配的靜態 IP 名稱。

    輸出內容會包含您建立的完整網址,類似如下:

    Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME].
    
  2. 查看您剛建立的 IP 位址:

    gcloud compute addresses list
    

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

    NAME          ADDRESS/RANGE  TYPE      STATUS
    ADDRESS_NAME  STATIC_IP_ADDRESS  EXTERNAL  RESERVED
    

    這項輸出內容包括:

    • 您定義的 ADDRESS_NAME。
    • 已分配 STATIC_IP_ADDRESS。
  3. 使用靜態 IP 更新 mci.yaml 檔案:

    apiVersion: networking.gke.io/v1
    kind: MultiClusterIngress
    metadata:
      name: whereami-ingress
      namespace: whereami
      annotations:
        networking.gke.io/static-ip: STATIC_IP_ADDRESS
    spec:
      template:
        spec:
          backend:
            serviceName: whereami-mcs
            servicePort: 8080
    

    將 STATIC_IP_ADDRESS 替換為下列任一項目:

    • 分配的 IP 位址,類似於: 34.102.201.47
    • 您建立的地址完整網址,類似於: "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME"

    STATIC_IP_ADDRESS 不是資源名稱 (ADDRESS_NAME)。

  4. 重新部署 MultiClusterIngress 資源:

    kubectl apply -f mci.yaml
    

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

    multiclusteringress.networking.gke.io/whereami-ingress configured
    
  5. 按照「驗證部署狀態是否成功」一文中的步驟操作,確認部署作業是否在 STATIC_IP_ADDRESS 上放送。

預先共用的憑證

預先共用的憑證 是上傳至 Google Cloud 的憑證,負載平衡器可使用這類憑證終止 TLS,而非使用儲存在 Kubernetes Secrets 中的憑證。這類憑證是從 GKE 頻外上傳至 Google Cloud ,並由 MultiClusterIngress 資源參照。也支援多個憑證,無論是透過預先共用憑證或 Kubernetes Secret 都可以。

如要在多叢集 Ingress 中使用憑證,必須提供 networking.gke.io/pre-shared-certs 註解和憑證名稱。如果為特定 MultiClusterIngress 指定多個憑證,系統會按照預先決定的順序,將憑證提供給用戶端。

您可以執行下列指令,列出可用的 SSL 憑證:

gcloud compute ssl-certificates list

以下範例說明用戶端流量前往其中一個指定主機,且符合預先共用憑證的通用名稱,因此系統會顯示符合網域名稱的相應憑證。

kind: MultiClusterIngress
metadata:
  name: shopping-service
  namespace: whereami
  annotations:
    networking.gke.io/pre-shared-certs: "domain1-cert, domain2-cert"
spec:
  template:
    spec:
      rules:
      - host: my-domain1.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain1-svc
              servicePort: 443
      - host: my-domain2.gcp.com
        http:
          paths:
          - backend:
              serviceName: domain2-svc
              servicePort: 443

Google 代管憑證

Google 代管憑證可透過 networking.gke.io/pre-shared-certs 註解在 MultiClusterIngress 資源上使用。多叢集 Ingress 支援將 Google 代管憑證附加至 MultiClusterIngress 資源,但與單一叢集 Ingress 不同的是,MultiClusterIngress 資源不支援以宣告方式產生 Kubernetes ManagedCertificate 資源。您必須先直接透過 compute ssl-certificates create API 建立 Google 代管憑證,才能將憑證附加至 MultiClusterIngress。步驟如下:

  1. 按照這個頁面步驟 1 的說明,建立 Google 代管的憑證。請勿前往步驟 2,因為多叢集 Ingress 會為您附加這個憑證。

    gcloud compute ssl-certificates create my-google-managed-cert \
        --domains=my-domain.gcp.com \
        --global
    
  2. 使用 networking.gke.io/pre-shared-certs 註解,在 MultiClusterIngress 中參照憑證名稱。

    kind: MultiClusterIngress
    metadata:
    name: shopping-service
    namespace: whereami
    annotations:
      networking.gke.io/pre-shared-certs: "my-google-managed-cert"
    spec:
    template:
      spec:
        rules:
        - host: my-domain.gcp.com
          http:
            paths:
            - backend:
                serviceName: my-domain-svc
                servicePort: 8080
    

上述資訊清單會將憑證附加至 MultiClusterIngress,以便終止後端 GKE 叢集的流量。Google Cloud 會在憑證到期前自動更新憑證。續約程序會自動進行,不需要更新多叢集 Ingress。

應用程式通訊協定

從負載平衡器 Proxy 到應用程式的連線預設會使用 HTTP。使用 networking.gke.io/app-protocols 註解,即可設定負載平衡器,在將要求轉送至應用程式時使用 HTTPS 或 HTTP/2。在以下範例的 annotation 欄位中,http2 是指 MultiClusterService 連接埠名稱,而 HTTP2 是指負載平衡器使用的通訊協定。

kind: MultiClusterService
metadata:
  name: shopping-service
  namespace: whereami
  annotations:
    networking.gke.io/app-protocols: '{"http2":"HTTP2"}'
spec:
  template:
    spec:
      ports:
      - port: 443
        name: http2

BackendConfig

如要瞭解如何設定註解,請參閱上方章節。

後續步驟