使用 Ingress 設定外部應用程式負載平衡器

本教學課程說明如何設定 Ingress 資源,執行使用外部應用程式負載平衡器的網頁應用程式。

本頁面適用於網路專家,他們負責為組織設計網路架構,以及安裝、設定和支援網路設備。如要進一步瞭解我們在Google Cloud 內容中提及的常見角色和範例工作,請參閱「常見的 GKE 使用者角色和工作」。

背景

Google Kubernetes Engine (GKE) 整合支援兩種 Cloud Load Balancing,可供公開存取的應用程式使用:

  1. 輸入流量

  2. 區域性外部直通式網路負載平衡器

在本教學課程中,您會使用 Ingress。

輸入

在資源資訊清單中指定 kind: Ingress 時,您會指示 GKE 建立 Ingress 資源。只要加入註解並支援工作負載和服務,即可建立自訂 Ingress 控制器。否則,GKE 會發出適當的 Google Cloud API 呼叫,建立外部應用程式負載平衡器。負載平衡器的網址對應主機規則和路徑比對器會參照一或多個後端服務,其中每個後端服務都對應至 Ingress 中參照的 NodePort 類型 GKE Service。每項後端服務的後端都是執行個體群組或網路端點群組 (NEG)。設定容器原生負載平衡做為 Ingress 設定的一部分時,系統會建立 NEG。針對每個後端服務,GKE 會根據對應 GKE Service 所參照工作負載的就緒探測設定,建立 Google Cloud 健康狀態檢查。

如果您要公開在 GKE 上託管的 HTTP(S) 服務,建議您使用 HTTP(S) 負載平衡這個方法進行負載平衡。

目標

  • 建立 GKE 叢集。
  • 將範例網頁應用程式部署至叢集。
  • 將範例應用程式公開發布到網際網路,並放在外部應用程式負載平衡器後端。

費用

在本文件中,您將使用下列 Google Cloud計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator。

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」。

事前準備

請按照下列步驟啟用 Kubernetes Engine API:
  1. 前往 Google Cloud 控制台的 Kubernetes Engine 頁面。
  2. 建立或選取專案。
  3. 等待 API 和相關服務完成啟用。 這可能需要幾分鐘的時間。
  4. 確認 Google Cloud 專案已啟用計費功能。

請安裝下列指令列工具,我們將在本教學課程中使用這些工具:

  • gcloud 可用來建立和刪除 Kubernetes Engine 叢集。gcloud 包含在 gcloud CLI 中。
  • kubectl 可用於管理 Kubernetes,這是 Kubernetes Engine 使用的叢集自動化調度管理系統。您可以使用 gcloud 安裝 kubectl:
    gcloud components install kubectl

從 GitHub 複製程式碼範例:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/networking/load-balancing

設定 gcloud 指令列工具的預設設定

如要節省在 gcloud 指令列工具中輸入專案 ID 和 Compute Engine 區域選項的時間,可以採用預設設定:
gcloud config set project project-id
gcloud config set compute/zone compute-zone

建立 GKE 叢集

建立 GKE Autopilot 叢集:

gcloud container clusters create-auto loadbalancedcluster

部署網頁應用程式

下列資訊清單描述的部署作業,會在通訊埠 8080 的 HTTP 伺服器上,執行範例網頁應用程式容器映像檔:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  selector:
    matchLabels:
      run: web
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
        imagePullPolicy: IfNotPresent
        name: web
        ports:
        - containerPort: 8080
          protocol: TCP

將資源套用至叢集:

kubectl apply -f web-deployment.yaml

在叢集內公開 Deployment

以下資訊清單說明 Service,可讓容器叢集存取 web 部署作業:

apiVersion: v1
kind: Service
metadata:
  name: web
  namespace: default
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    run: web
  type: NodePort
  1. 將資源套用至叢集:

    kubectl apply -f web-service.yaml
    

    使用這項指令建立 NodePort 類型的 Service 時,GKE 會在叢集的所有節點上,隨機選取高通訊埠編號 (例如 32640),讓 Service 可供使用。

  2. 確認 Service 已建立,且已分配節點通訊埠:

    kubectl get service web
    
    輸出內容:
    NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    web       NodePort   10.35.245.219   <none>        8080:32640/TCP   5m
    

    在範例輸出內容中,web 服務的節點通訊埠為 32640。 另請注意,系統不會為這項服務分配外部 IP。根據預設,GKE 節點無法從外部存取,因此建立這項 Service 並不會讓應用程式可從網際網路存取。

如要讓大眾存取 HTTP(S) 網路伺服器應用程式,您必須建立 Ingress 資源。

建立 Ingress 資源

Ingress 是 Kubernetes 資源,封裝了一組規則和設定,可將外部 HTTP(S) 流量轉送至內部服務。

在 GKE 上,Ingress 會透過 Cloud Load Balancing 實作。在叢集中建立 Ingress 時,GKE 會建立 HTTP(S) 負載平衡器,並設定將流量轉送至您的應用程式。

以下資訊清單說明 Ingress 資源,該資源會將流量導向 web 服務:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: basic-ingress
spec:
  defaultBackend:
    service:
      name: web
      port:
        number: 8080

將資源套用至叢集:

kubectl apply -f basic-ingress.yaml

部署這個資訊清單後,Kubernetes 會在叢集上建立 Ingress 資源。GKE Ingress 控制器會根據 Ingress 中的資訊建立及設定 HTTP(S) 負載平衡器,將所有外部 HTTP 流量 (透過通訊埠 80) 轉送至您公開的 web NodePort Service。

查看應用程式

請執行下列指令,找出為您的應用程式提供服務的負載平衡器外部 IP 位址:

kubectl get ingress basic-ingress
輸出內容:
NAME            HOSTS     ADDRESS         PORTS     AGE
basic-ingress   *         203.0.113.12    80        2m

在瀏覽器中開啟應用程式的外部 IP 位址,您會看到類似下方的純文字 HTTP 回應:

Hello, world!
Version: 1.0.0
Hostname: web-6498765b79-fq5q5

您可以前往 Google Cloud 控制台的「Load Balancing」(負載平衡) ,檢查 GKE Ingress 控制器建立的網路資源。

(選用) 設定靜態 IP 位址

在網域名稱上公開網路伺服器時,您必須將應用程式的外部 IP 位址設為不會變動的靜態 IP。

根據預設,GKE 會為透過 Ingress 公開的 HTTP 應用程式分配臨時外部 IP 位址。暫時性地址可能會變更。如果您打算長時間執行應用程式,就必須使用靜態外部 IP 位址。

請注意,為 Ingress 資源設定靜態 IP 後,刪除 Ingress 並不會刪除與其相關聯的靜態 IP 位址。如果您不再打算使用靜態 IP 位址,請務必清除您設定的靜態 IP 位址。

如要設定靜態 IP 位址,請完成下列步驟:

  1. 保留名為 web-static-ip 的靜態外部 IP 位址:

    gcloud

    gcloud compute addresses create web-static-ip --global
    

    Config Connector

    注意:這個步驟需要 Config Connector。按照安裝操作說明,在叢集上安裝 Config Connector。

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: web-static-ip
    spec:
      location: global
    如要部署這份資訊清單,請將其下載至機器,並命名為 compute-address.yaml,然後執行:
    kubectl apply -f compute-address.yaml

  2. basic-ingress-static.yaml 資訊清單會在 Ingress 上新增註解,以使用名為 web-static-ip 的靜態 IP 資源:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: basic-ingress
      annotations:
        kubernetes.io/ingress.global-static-ip-name: "web-static-ip"
    spec:
      defaultBackend:
        service:
          name: web
          port:
            number: 8080

    查看資訊清單:

    cat basic-ingress-static.yaml
    
  3. 將資源套用至叢集:

    kubectl apply -f basic-ingress-static.yaml
    
  4. 檢查外部 IP 位址:

    kubectl get ingress basic-ingress
    

    等待應用程式的 IP 位址變更,改用 web-static-ip 資源的預留 IP 位址。

    更新現有 Ingress 資源、重新設定負載平衡器,以及在全球傳播負載平衡規則,可能需要幾分鐘時間。這項作業完成後,GKE 會釋出先前分配給應用程式的臨時 IP 位址。

(選用) 在負載平衡器上放送多個應用程式

您可以在 Ingress 上設定轉送規則,以在單一負載平衡器和公開 IP 上執行多項服務。在同一個 Ingress 上代管多項服務,可避免為每個向網際網路公開的服務建立額外的負載平衡器 (這類資源會產生費用)。

下列資訊清單說明相同網頁應用程式的 Deployment,版本為 2.0:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web2
  namespace: default
spec:
  selector:
    matchLabels:
      run: web2
  template:
    metadata:
      labels:
        run: web2
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: web2
        ports:
        - containerPort: 8080
          protocol: TCP

將資源套用至叢集:

kubectl apply -f web-deployment-v2.yaml

下列資訊清單描述的 Service,會透過名為 web2 的 NodePort Service,在叢集內部公開 web2:

apiVersion: v1
kind: Service
metadata:
  name: web2
  namespace: default
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    run: web2
  type: NodePort

將資源套用至叢集:

kubectl apply -f web-service-v2.yaml

下列資訊清單說明 Ingress 資源:

  • 將路徑開頭為 /v2/ 的要求轉送至 web2 服務
  • 將所有其他要求轉送至 web 服務
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: fanout-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: web
            port:
              number: 8080
      - path: /v2/*
        pathType: ImplementationSpecific
        backend:
          service:
            name: web2
            port:
              number: 8080

將資源套用至叢集:

kubectl create -f fanout-ingress.yaml

部署 Ingress 後,請執行 kubectl get ingress fanout-ingress,找出叢集的公開 IP 位址。

接著造訪 IP 位址,看看您是否可以在同一個負載平衡器上存取兩個應用程式:

  • 前往 http://<IP_ADDRESS>/,並注意回應包含 Version: 1.0.0 (因為要求會轉送至 web 服務)
  • 前往 http://<IP_ADDRESS>/v2/,並注意回應包含 Version: 2.0.0 (因為要求會轉送至 web2 服務)

Ingress 的 path 欄位僅支援 * 字元做為萬用字元。* 字元必須接在正斜線 (/) 後方,且必須是模式中的最後一個字元。舉例來說,/*、/foo/* 和 /foo/bar/* 是有效模式,但 *、/foo/bar* 和 /foo/*/bar 則無效。

較明確的模式會優先於較不明確的模式。如果您同時有 /foo/* 和 /foo/bar/*,系統會將 /foo/bar/bat 視為與 /foo/bar/* 相符。

如要進一步瞭解路徑限制和模式比對,請參閱網址對應說明文件。

(選用) 監控服務的可用性和延遲情形

Google Cloud 正常運作時間檢查會從使用者的角度執行應用程式的黑箱監控,判斷從多個外部 IP 到負載平衡器 IP 位址的延遲和可用性。相較之下, Google Cloud 健康狀態檢查會對 Pod IP 執行內部檢查,在執行個體層級判斷可用性。這些檢查是互補的,可全面瞭解應用程式的健康狀態。

您可以使用 Google Cloud 控制台、Cloud Monitoring API 或 Cloud Monitoring 用戶端程式庫,建立運作時間檢查。詳情請參閱「管理運作時間檢查」。如要使用 Google Cloud 控制台建立運作時間檢查,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Services & Ingress」(服務和 Ingress) 頁面。

    前往「Services & Ingress」(服務與 Ingress)

  2. 按一下要建立運作時間檢查的服務名稱。

  3. 按一下「建立運作時間檢查」。

  4. 在「Create Uptime Check」(建立運作時間檢查) 窗格中,輸入運作時間檢查的標題,然後按一下「Next」(下一步),前往「Target」(目標) 設定。

    系統會使用服務負載平衡器的資訊,自動填入正常運作時間檢查的「目標」欄位。

    如需運作時間檢查中所有欄位的完整說明文件,請參閱「建立運作時間檢查」。

  5. 按一下「下一步」,前往「回應驗證」設定。

  6. 按一下「Next」(下一步),前往「Alert and Notification」(快訊與通知) 部分。

    如要監控運作時間檢查,您可以建立警告政策,或查看運作時間檢查資訊主頁。如果運作時間檢查失敗,警告政策會透過電子郵件或其他管道通知您。如需警告政策的一般資訊,請參閱「警告簡介」。

  7. 點選「建立」。

附註

根據預設,Ingress 會定期對 / 路徑提出 GET 要求,藉此執行健康狀態檢查,判斷應用程式的健康狀態,並預期會收到 HTTP 200 回應。如要檢查其他路徑或預期其他回應代碼,可以使用自訂健康檢查路徑。

Ingress 支援更多進階用途,例如:

  • 名稱對應型虛擬主機:您可以透過 Ingress 重複使用負載平衡器,託管多個網域名稱和子網域,並在單一 IP 位址和負載平衡器上公開多個服務。請參閱簡單的扇出和以名稱為準的虛擬主機範例,瞭解如何為這些工作設定 Ingress。

  • 終止 HTTPS:您可以設定 Ingress,使用 Cloud Load Balancer 終止 HTTPS 流量。

刪除 Ingress 時,GKE Ingress 控制器會自動清除相關聯的資源 (預留的靜態 IP 位址除外)。

清除所用資源

為避免因為本教學課程所用資源,導致系統向 Google Cloud 帳戶收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

  1. 刪除所有手動建立、參照 Ingress 的轉送規則和目標 Proxy:

    如果目標 Proxy 參照 GKE Ingress 控制器管理的網址對應,則在 GKE 1.15.4-gke.22 以上版本中,刪除 Ingress 會失敗。請檢查 Ingress 資源,找出類似下列錯誤訊息的事件:

     Error during GC: error running load balancer garbage collection routine: googleapi: Error 400: The url_map resource 'projects/project-id/global/urlMaps/k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82' is already being used by 'projects/project-id/global/targetHttpsProxies/k8s2-um-tlw9rhgp-default-my82-target-proxy', resourceInUseByAnotherResource
     

    在上述錯誤訊息中,k8s2-um-tlw9rhgp-default-my82-target-proxy 是手動建立的目標 HTTPS Proxy,仍參照由 Ingress 控制器建立及管理的網址對應 k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82。

    必須先刪除這些手動建立的前端資源 (轉送規則和目標 Proxy),才能刪除 Ingress。

  2. 刪除 Ingress:這個步驟會取消分配臨時外部 IP 位址,以及與應用程式相關聯的負載平衡資源:

    kubectl delete ingress basic-ingress

    如果您按照選用步驟建立了 Ingress,以便依路徑轉送要求,請刪除該 Ingress:

    kubectl delete ingress fanout-ingress

  3. 刪除靜態 IP 位址:只有在您按照選用步驟建立靜態 IP 位址時,才需要完成這個步驟。

    • 如果您按照「選項 1」將現有的臨時 IP 位址轉換為靜態 IP,請前往Google Cloud 控制台刪除靜態 IP 位址。

    • 如果您按照「做法 2」建立新的靜態 IP 位址,請執行下列指令刪除該位址:

      gcloud compute addresses delete web-static-ip --global
  4. 刪除叢集:這個步驟會刪除容器叢集的運算節點,以及叢集中的部署作業等其他資源:

    gcloud container clusters delete loadbalancedcluster

後續步驟