本頁說明如何建立 Kubernetes Ingress 物件,以便設定外部應用程式負載平衡器。
閱讀本頁面之前,請先熟悉 GKE 網路概念。
事前準備
開始之前,請確認你已完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update
,取得最新版本。
啟用 HttpLoadBalancing
外掛程式
叢集必須啟用 HttpLoadBalancing
外掛程式。這項外掛程式預設為啟用。在 Autopilot 叢集中,您無法停用這個外掛程式。
您可以使用 Google Cloud 控制台或 Google Cloud CLI 啟用 HttpLoadBalancing
外掛程式。
控制台
前往 Google Cloud 控制台的「Google Kubernetes Engine」頁面。
按一下您要修改的叢集名稱。
在「Networking」(網路) 下方的「HTTP Load Balancing」(HTTP 負載平衡) 欄位中,按一下「Edit HTTP Load Balancing」(編輯 HTTP 負載平衡)edit。
勾選「啟用 HTTP 負載平衡」核取方塊。
按一下 [儲存變更]。
gcloud
gcloud container clusters update CLUSTER_NAME --update-addons=HttpLoadBalancing=ENABLED
將 CLUSTER_NAME
替換為叢集名稱。
建立靜態 IP 位址
外部應用程式負載平衡器提供穩定的 IP 位址,用來將要求轉送到一或多個服務。如要使用永久 IP 位址,請先保留全域靜態外部 IP 位址,再建立 Ingress。
如果您修改現有 Ingress,改為使用靜態 IP 位址而非臨時 IP 位址,GKE 重新建立負載平衡器的轉送規則時,可能會變更負載平衡器的 IP 位址。
建立外部應用程式負載平衡器
在本練習中,您將設定外部應用程式負載平衡器,根據網址路徑將要求轉送至不同的服務。
如要直接在 Google Cloud 控制台按照逐步指南操作,請按一下「Guide me」(逐步引導):
建立 Deployment 和服務
建立兩個 Deployment 物件,並將 Service 命名為 hello-world-1
和 hello-world-2
:
將下列資訊清單儲存為
hello-world-deployment-1.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: hello-world-deployment-1 spec: selector: matchLabels: greeting: hello version: one replicas: 3 template: metadata: labels: greeting: hello version: one spec: containers: - name: hello-app-1 image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0" env: - name: "PORT" value: "50000"
這個資訊清單說明含有三個備用資源的範例部署。
將資訊清單套用至叢集:
kubectl apply -f hello-world-deployment-1.yaml
將下列資訊清單儲存為
hello-world-service-1.yaml
:apiVersion: v1 kind: Service metadata: name: hello-world-1 spec: type: NodePort selector: greeting: hello version: one ports: - protocol: TCP port: 60000 targetPort: 50000
這份資訊清單說明具有下列屬性的 Service:
- 任何具有
greeting: hello
標籤和version: one
標籤的 Pod 都是 Service 的成員。 - 當要求傳送至 TCP 通訊埠 60000 上的 Service 時,GKE 會將其轉送至 TCP 通訊埠 50000 上的其中一個成員 Pod。
- Service 類型為
NodePort
,除非使用容器原生負載平衡,否則必須使用這個類型。如果使用容器原生負載平衡,服務類型則不受限制。建議使用type: ClusterIP
。
- 任何具有
將資訊清單套用至叢集:
kubectl apply -f hello-world-service-1.yaml
將下列資訊清單儲存為
hello-world-deployment-2.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: hello-world-deployment-2 spec: selector: matchLabels: greeting: hello version: two replicas: 3 template: metadata: labels: greeting: hello version: two spec: containers: - name: hello-app-2 image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0" env: - name: "PORT" value: "8080"
這個資訊清單說明含有三個備用資源的範例部署。
將資訊清單套用至叢集:
kubectl apply -f hello-world-deployment-2.yaml
將下列資訊清單儲存為
hello-world-service-2.yaml
:apiVersion: v1 kind: Service metadata: name: hello-world-2 spec: type: NodePort selector: greeting: hello version: two ports: - protocol: TCP port: 80 targetPort: 8080
這份資訊清單說明具有下列屬性的 Service:
- 任何具有
greeting: hello
標籤和version: two
標籤的 Pod 都是 Service 的成員。 - 當要求傳送至 TCP 通訊埠 80 上的 Service 時,GKE 會將其轉送至 TCP 通訊埠 8080 上的其中一個成員 Pod。
- 任何具有
將資訊清單套用至叢集:
kubectl apply -f hello-world-service-2.yaml
建立 Ingress
建立 Ingress,指定根據要求中的網址路徑轉送要求的規則。建立 Ingress 時,GKE Ingress 控制器會建立並設定外部應用程式負載平衡器。
將下列資訊清單儲存為
my-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: # If the class annotation is not specified it defaults to "gce". kubernetes.io/ingress.class: "gce" spec: rules: - http: paths: - path: /* pathType: ImplementationSpecific backend: service: name: hello-world-1 port: number: 60000 - path: /v2 pathType: ImplementationSpecific backend: service: name: hello-world-2 port: number: 80
這份資訊清單說明具有下列屬性的 Ingress:
GKE Ingress 類別有兩種。如要指定 Ingress 類別,請使用
kubernetes.io/ingress.class
註解。您無法使用spec.ingressClassName
指定 GKE Ingress。gce
類別會部署外部應用程式負載平衡器。gce-internal
類別會部署內部應用程式負載平衡器。部署 Ingress 資源時,如果沒有
spec.ingressClassName
和kubernetes.io/ingress.class
註解,GKE 會建立外部應用程式負載平衡器。如果您指定kubernetes.io/ingress.class: gce
註解,也會發生相同行為。詳情請參閱「GKE Ingress 控制器行為」。GKE 會為每個
backend.service
建立Google Cloud 後端服務。每個後端服務都對應至 Kubernetes 服務,且每個後端服務都必須參照Google Cloud 健康狀態檢查。這項健康狀態檢查與 Kubernetes 執行中或已就緒探測器不同,因為健康狀態檢查是在叢集外部實作。詳情請參閱健康狀態檢查當用戶端傳送要求至網址路徑為
/
的負載平衡器時,GKE 會將要求轉送至通訊埠 60000 上的hello-world-1
Service。當用戶端使用網址路徑/v2
向負載平衡器發送要求時,GKE 會將要求轉送至通訊埠 80 上的hello-world-2
Service。如要進一步瞭解path
和pathType
屬性,請參閱「網址路徑」。
將資訊清單套用至叢集:
kubectl apply -f my-ingress.yaml
測試外部應用程式負載平衡器
請稍候大約五分鐘,讓負載平衡器進行設定,然後測試外部應用程式負載平衡器:
檢視 Ingress:
kubectl get ingress my-ingress --output yaml
輸出內容會顯示外部應用程式負載平衡器的 IP 位址:
status: loadBalancer: ingress: - ip: 203.0.113.1
測試
/
路徑:curl LOAD_BALANCER_IP_ADDRESS/
將
LOAD_BALANCER_IP_ADDRESS
改成負載平衡器的外部 IP 位址。輸出結果會與下列內容相似:
Hello, world! Version: 1.0.0 Hostname: ...
如果輸出內容包含 404 錯誤,請稍待幾分鐘。
測試
/v2
路徑:curl load-balancer-ip/v2
輸出結果會與下列內容相似:
Hello, world! Version: 2.0.0 Hostname: ...
外部負載平衡 Ingress 的運作方式
外部應用程式負載平衡器是用戶端與應用程式間的 Proxy。如果要接受來自用戶端的 HTTPS 要求,負載平衡器必須要有憑證,以向用戶端證明其身分。 負載平衡器還必須要有私密金鑰才能完成 HTTPS 握手。 如需詳細資訊,請參閱:
網址路徑
Ingress 的 path
欄位僅支援 *
字元做為萬用字元。*
字元必須在正斜線 (/
) 之後,並且必須是模式中的最後一個字元。例如,/*
、/foo/*
和 /foo/bar/*
是有效模式,但 *
、/foo/bar*
和 /foo/*/bar
則不是。
較明確的模式會優先於較不明確的模式。如果您同時有 /foo/*
和 /foo/bar/*
,系統會使用 /foo/bar/bat
來比對 /foo/bar/*
。如要進一步瞭解路徑限制和模式比對,請參閱網址對應說明文件。
如果 GKE 叢集執行的版本早於 1.21.3-gke.1600,pathType
欄位只支援 ImplementationSpecific
值。如果叢集執行 1.21.3-gke.1600 以上版本,pathType
也支援 Prefix
和 Exact
值。
停用 HTTP
如果您希望所有用戶端和負載平衡器之間的流量使用 HTTPS,則您可以停用 HTTP。如需更多資訊,請參閱停用 HTTP。
負載平衡器與應用程式之間的 HTTPS
如果您在 GKE pod 中執行的應用程式能接收 HTTPS 要求,您可以將負載平衡器設為將要求轉送到您的應用程式時使用 HTTPS。若須更多訊息,請參閱負載平衡器和應用程式之間的 HTTPS (TLS)。
用戶端和負載平衡器之間的 HTTP/2
用戶端可以使用 HTTP/2 向負載平衡器傳送要求,您無需再進行設定。
負載平衡器和應用程式之間的 HTTP/2
如果您在 GKE pod 中執行的應用程式能接收 HTTP/2 要求,您可以將負載平衡器設為將要求轉送到您的應用程式時使用 HTTP/2。詳情請參閱用於與 Ingress 進行負載平衡的 HTTP/2 一文。
網路端點群組
如果叢集支援容器原生負載平衡,建議使用網路端點群組 (NEG)。對於 1.17 以上版本的 GKE 叢集,以及符合特定條件的叢集,系統會預設使用容器原生負載平衡,且不需要明確的 cloud.google.com/neg: '{"ingress": true}'
服務註解。
共用虛擬私有雲
如果您要部署 Ingress 資源的 GKE 叢集位於服務專案中,且希望 GKE 控制平面管理主專案中的防火牆資源,則必須按照「管理共用 VPC 叢集的防火牆資源」一文所述,在主專案中授予服務專案的 GKE 服務帳戶適當的 IAM 權限。這可讓 Ingress 控制器建立防火牆規則,允許輸入流量和 Google Cloud 健康狀態檢查流量。
以下是 Ingress 資源記錄中可能出現的事件範例。如果權限設定不正確,Ingress 控制器就無法建立防火牆規則,允許 Google Cloud 健康狀態檢查的 Ingress 流量,因此會發生這個錯誤。
Firewall change required by security admin: `gcloud compute firewall-rules update <RULE_NAME> --description "GCE L7 firewall rule" --allow tcp:<PORT> --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags <TARGET_TAG> --project <HOST_PROJECT>
如果偏好從主機專案手動佈建防火牆規則,可以將 networking.gke.io/suppress-firewall-xpn-error: "true"
註解新增至 Ingress 資源,將 firewallXPNError
事件設為忽略項目。
外部 Ingress 註解摘要
Ingress 註解
註解 | 說明 |
---|---|
kubernetes.io/ingress.allow-http | 指定是否允許用戶端與 HTTP(S) 負載平衡器之間的 HTTP 通訊。可能的值為「true」和「false」,預設值為「true」。請參閱「停用 HTTP」。 |
ingress.gcp.kubernetes.io/pre-shared-cert | 使用這個註解將憑證資源附加至 GKE Ingress 資源。詳情請參閱使用外部應用程式負載平衡器時使用多個 SSL 憑證。 |
kubernetes.io/ingress.global-static-ip-name | 使用此註解來指定負載平衡器應使用之前建立的靜態外部 IP 地址。請參閱「HTTP(S) 負載平衡器的靜態 IP 位址」。 |
networking.gke.io/v1beta1.FrontendConfig | 使用此註解自訂負載平衡器的用戶端設定。詳情請參閱輸入設定。 |
networking.gke.io/suppress-firewall-xpn-error | 至於 Ingress 負載平衡器,如果 Kubernetes 因權限不足而無法變更防火牆規則,則每幾分鐘就會建立一次 firewallXPNError 事件。在 GLBC 1.4 以上版本中,可以將 firewallXPNError 事件設為忽略項目,方法是將 networking.gke.io/suppress-firewall-xpn-error: "true" 註解新增到輸入資源。移除該註解即可取消設為忽略項目。可能的值為 true 和 false 。
預設值為 false 。 |
與 Ingress 相關的 Service 註解
註解 | 說明 |
---|---|
cloud.google.com/app-protocols | 使用此註解可設定負載平衡器與應用程式之間的通訊協定。可能的通訊協定為 HTTP、HTTPS 和 HTTP2。 請參閱「負載平衡器與您應用程式之間的 HTTPS」和「用於與 Ingress 進行負載平衡的 HTTP/2」。 |
cloud.google.com/backend-config | 使用此註解設定與服務相關聯的後端服務。詳情請參閱輸入設定。 |
cloud.google.com/neg | 使用此註解指定負載平衡器應使用網路端點群組。請參閱「使用容器原生負載平衡功能」。 |
後續步驟
閱讀 GKE 中的外部應用程式負載平衡器 Ingress 概念總覽。
完成使用 Ingress 設定外部應用程式負載平衡器的教學課程。
閱讀 GKE 中的 Services 概念總覽。
實作基本外部 Ingress。