本文件說明如何部署設定為 TLS 傳遞的 Kubernetes Gateway 資源,在 Google Kubernetes Engine (GKE) 中啟用伺服器名稱指示 (SNI) 轉送功能。這種方法可保留用戶端與後端 Pod 之間的端對端加密和相互傳輸層安全標準 (mTLS),支援非 HTTP TLS 通訊協定,並節省 IP 位址。
本文適用對象為 Cloud 架構師、網路專家和開發人員,負責為容器化工作負載設計、部署及管理加密網路。如要進一步瞭解常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。
總覽
除了第 7 層 HTTP 和 HTTPS 應用程式負載平衡器之外,GKE Gateway 控制器也支援設定 TLS 轉送的第 4 層 Proxy 網路負載平衡器 (TCP Proxy 負載平衡器)。
使用 TLS 直通時,負載平衡器不會終止或解密 TLS 工作階段。相反地,當用戶端啟動 TLS 握手時,負載平衡器會檢查未加密的 ClientHello 訊息,讀取伺服器名稱指示 (SNI) 主機名稱。負載平衡器會根據這個 SNI 主機名稱,將原始加密 TCP 串流轉送至適當的後端 Kubernetes Service,由應用程式 Pod 直接終止 TLS。
透過 Gateway API 使用 TLS 直通時,您可以執行下列操作:
- 維持端對端加密,並支援零信任法規遵循:將用戶端到後端 Pod 的流量完全加密,不讓負載平衡器存取私密金鑰或明文資料。
- 使用 mTLS 驗證:直接在後端應用程式層驗證用戶端。
- 節省 IPv4 位址:使用單一閘道 IP 位址和通訊埠 (例如
443),在不同網域或子網域中多工處理多個獨立 TLS 服務。 - 支援非 HTTP TLS 通訊協定:為有狀態工作負載、資料庫、自訂 gRPC 服務,或透過 TLS 執行的專屬通訊協定轉送加密流量。
支援的 GatewayClass
下列 GKE GatewayClass 支援 TLS 傳遞事件監聽器和 TLSRoute 資源:
gke-l7-regional-external-managedgke-l7-regional-external-managed-mcgke-l7-rilbgke-l7-rilb-mcgke-l7-cross-regional-internal-managed-mc
如要完整比較 GatewayClass 功能,請參閱「GatewayClass 功能」。
事前準備
開始之前,請確認您已執行下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文中的指令。
- 確認您有現有的 Autopilot 或 Standard 叢集,且該叢集執行 GKE 1.35 以上版本,並已啟用 Gateway API。如要建立叢集,請參閱「建立 Autopilot 叢集」。如要在現有叢集上啟用 Gateway API,請參閱「在叢集中啟用 Gateway API」。
- 確認您已安裝 OpenSSL 指令列工具。您可以使用這項工具,為範例應用程式產生自行簽署的 TLS 憑證。
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 服務帳戶。
規定與限制
部署 TLS 直通閘道和 TLSRoute 資源時,請注意下列限制:
- 在監聽器上設定
protocol: TLS時,必須明確將tls.mode欄位設為Passthrough值。GKE 不支援TLS監聽器的預設Terminate模式。 - 如果是
TLS監聽器,請勿設定certificateRefs欄位。閘道層級用戶端憑證驗證 (spec.tls.frontendValidation欄位) 不適用於TLS監聽器。如要使用 mTLS,請在後端驗證用戶端憑證。 TLS監聽器只能與其他TLS監聽器共用通訊埠。您無法在與TLS監聽器相同的通訊埠上設定HTTP或HTTPS監聽器。- 在
TLSRoute.spec.hostnames欄位中,您必須指定 1 到 1,024 個 SNI 主機名稱 (確切主機名稱或萬用字元前置字串,例如*.example.com)。每個項目不得超過 253 個字元,且不得為 IP 位址。 - 在
TLSRoute.spec.rules欄位中,最多可以設定一項規則。 - 每項規則僅支援一個
backendRef項目。第 4 層 Proxy 後端不支援在多個後端之間進行加權流量拆分。 - 單一叢集 GatewayClass 僅支援 Service 後端,多叢集 GatewayClass 則僅支援 ServiceImport 後端。
- 在
TLSRoute.spec.rules.backendRefs欄位中,將port欄位設為目標 Service 或 ServiceImport 資源宣告的通訊埠,而非容器通訊埠。 - TLSRoute 資源參照的後端 Kubernetes Service (包括匯出為 ServiceImport 的 Service),其通訊埠通訊協定必須使用
TCP值。 - 您無法將 BackendTLSPolicy 資源、Identity-Aware Proxy 或 Google Cloud Armor 安全性政策附加至 TLSRoute 後端,因為控制器會拒絕這類設定。
- 將 GCPBackendPolicy 資源附加至 TLSRoute 資源參照的 Service 或 ServiceImport 時,必須將
spec.protocol欄位設為TCP值 (省略spec.protocol欄位會預設為HTTP值,僅適用於 HTTPRoute 後端)。一項 Service 或 ServiceImport 可同時附加一項HTTP政策和一項TCP政策;如果有多項政策具有相同的spec.protocol值,且指定相同的 Service 或 ServiceImport,則會優先採用最舊的政策,不會附加較新的政策。 如果 GCPBackendPolicy 資源的
spec.protocol欄位設為TCP,則spec.default欄位僅支援下列欄位 (如果指定 ServiceImport 資源,則可改為在spec.default.scopes欄位中,為每個叢集、可用區或區域設定最後三個欄位):timeoutSecconnectionDraininglogging.enabled和logging.sampleRatesessionAffinity.type(有效值為CLIENT_IP或NONE)capacityScalerPercentbalancingMode: CONNECTIONmaxConnectionsPerEndpoint
您無法建立包含任何其他欄位的
TCP政策,也無法建立包含僅限TCP欄位 (balancingMode: CONNECTION和maxConnectionsPerEndpoint) 的HTTP政策;Kubernetes API 伺服器會在建立時拒絕政策。詳情請參閱「使用政策設定閘道資源」。如果 HTTPRoute 和 TLSRoute 資源都參照相同的 Service 或 ServiceImport,將 HealthCheckPolicy 資源附加至該目標,會取代個別的預設健康狀態檢查,並將相同的健康狀態檢查設定套用至這兩項路由的後端。如要獨立設定健康狀態檢查 (例如 HTTPRoute 後端的
HTTP健康狀態檢查,以及 TLSRoute 後端的SSL或TCP健康狀態檢查),請為每條路由建立獨立的 Service,並將 HealthCheckPolicy 資源附加至各個 Service。兩個 Service 可以選取相同的 Pod。第 7 層功能 (例如網址重寫、路徑式轉送和 HTTP 標頭轉換) 不適用於第 4 層 TCP Proxy 負載平衡器。
設定 Proxy 專用子網路
區域性閘道在部署的每個區域中,都需要 Proxy 專用子網路 (purpose=REGIONAL_MANAGED_PROXY)。一個僅限 Proxy 的子網路,可為該區域中所有區域性 Envoy 型負載平衡器提供服務。如果您的區域尚未建立,請參閱「設定僅限 Proxy 的子網路」。
保留靜態 IP 位址
部署閘道前,請先保留區域靜態 IP 位址,確保閘道位址不會變更,並將範例主機名稱解析至該位址。如需建立靜態 IP 位址的操作說明,請參閱「建立區域性外部 HTTP(S) 閘道」。
部署具有 TLS 直通式監聽器的閘道
本節中的閘道會設定兩個共用通訊埠 443 的 TLS 監聽器。每個監聽器都會比對不同的 SNI 主機名稱,並以直通模式將連線轉送至附加的 TLSRoute 資源。
將下列資訊清單儲存為
store-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-tls spec: gatewayClassName: gke-l7-regional-external-managed listeners: # Accept TLS connections for store.example.com without decrypting them. - name: store protocol: TLS port: 443 hostname: "store.example.com" tls: mode: Passthrough allowedRoutes: kinds: - kind: TLSRoute # A second listener on the same port, selected by a different SNI name. - name: store-german protocol: TLS port: 443 hostname: "store-de.example.com" tls: mode: Passthrough allowedRoutes: kinds: - kind: TLSRoute addresses: - type: NamedAddress value: IP_ADDRESS_NAME將 IP_ADDRESS_NAME 替換為您預留的靜態 IP 位址名稱。
請注意,
tls區塊沒有certificateRefs欄位。在Passthrough模式中,TLS 憑證會位於後端 Pod,而非負載平衡器。套用閘道資訊清單:
kubectl apply -f store-gateway.yaml確認閘道已設定:
kubectl get gateway store-tls佈建負載平衡器需要幾分鐘的時間。輸出內容大致如下:
NAME CLASS ADDRESS PROGRAMMED AGE store-tls gke-l7-regional-external-managed 35.118.32.224 True 53s
使用內部閘道
如要將流量保留在虛擬私有雲網路中,請將 gatewayClassName 欄位的值變更為 gke-l7-rilb,並從閘道資訊清單中移除 addresses 欄位。接著,GKE 會建立區域性內部 Proxy 網路負載平衡器,並從叢集子網路指派內部 IP 位址。本頁其餘步驟不變。請從相同虛擬私有雲網路中的 Compute Engine 執行個體傳送測試要求,因為無法從網際網路連上內部 IP 位址。
部署範例 TLS 應用程式
在本節中,您將部署兩個 NGINX Deployment (store-v1 和 store-german),在通訊埠 8443 終止 TLS。每個 Deployment 都會提供不同的 TLS 憑證,並回報收到的 SNI 主機名稱,讓您確認是否根據 SNI 進行轉送。
為每個主機名稱產生自行簽署的 TLS 憑證和私密金鑰:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -days 365 \ -keyout store.key -out store.crt \ -subj '/CN=store.example.com' \ -addext 'subjectAltName=DNS:store.example.com' openssl req -x509 -newkey rsa:2048 -nodes -sha256 -days 365 \ -keyout store-de.key -out store-de.crt \ -subj '/CN=store-de.example.com' \ -addext 'subjectAltName=DNS:store-de.example.com'在正式環境中,請使用憑證授權單位提供的憑證。自行簽署的憑證可讓這個範例保持獨立。
執行下列指令,將各個憑證和金鑰儲存在 Kubernetes Secret:
kubectl create secret tls store-cert \ --cert=store.crt --key=store.key kubectl create secret tls store-de-cert \ --cert=store-de.crt --key=store-de.key將下列資訊清單儲存為
store-tls-app.yaml:apiVersion: v1 kind: ConfigMap metadata: name: store-nginx data: default.conf: | server { listen 8443 ssl; ssl_certificate /etc/nginx/ssl/tls.crt; ssl_certificate_key /etc/nginx/ssl/tls.key; default_type text/plain; # Report which Pod answered and which SNI name it received. return 200 "backend: $hostname\nsni: $ssl_server_name\n"; } --- apiVersion: apps/v1 kind: Deployment metadata: name: store-v1 spec: replicas: 2 selector: matchLabels: app: store-v1 template: metadata: labels: app: store-v1 spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 8443 volumeMounts: - name: config mountPath: /etc/nginx/conf.d - name: cert mountPath: /etc/nginx/ssl readOnly: true volumes: - name: config configMap: name: store-nginx - name: cert secret: secretName: store-cert --- apiVersion: v1 kind: Service metadata: name: store-v1 spec: selector: app: store-v1 ports: - port: 443 targetPort: 8443 --- apiVersion: apps/v1 kind: Deployment metadata: name: store-german spec: replicas: 2 selector: matchLabels: app: store-german template: metadata: labels: app: store-german spec: containers: - name: nginx image: nginx:1.27 ports: - containerPort: 8443 volumeMounts: - name: config mountPath: /etc/nginx/conf.d - name: cert mountPath: /etc/nginx/ssl readOnly: true volumes: - name: config configMap: name: store-nginx - name: cert secret: secretName: store-de-cert --- apiVersion: v1 kind: Service metadata: name: store-german spec: selector: app: store-german ports: - port: 443 targetPort: 8443服務不需要
appProtocol欄位。GKE 會將 TLSRoute 流量以 TCP 形式轉送至後端,因此這個欄位不會產生任何作用。將資訊清單套用至叢集:
kubectl apply -f store-tls-app.yaml確認 Pod 正在執行:
kubectl get pods -l 'app in (store-v1,store-german)'輸出結果會與下列內容相似:
NAME READY STATUS RESTARTS AGE store-german-7d9f8c5b47-2xqkd 1/1 Running 0 41s store-german-7d9f8c5b47-h6tzn 1/1 Running 0 41s store-v1-6c4b9d8f65-kp8vr 1/1 Running 0 41s store-v1-6c4b9d8f65-wm2ls 1/1 Running 0 41s
部署 TLSRoute 資源,以便根據 SNI 轉送
TLSRoute 資源會附加至閘道監聽器,並將符合其主機名稱的連線轉送至單一後端服務。
將下列資訊清單儲存為
store-tls-routes.yaml:kind: TLSRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store spec: parentRefs: - kind: Gateway name: store-tls sectionName: store hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 443 --- kind: TLSRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-german spec: parentRefs: - kind: Gateway name: store-tls sectionName: store-german hostnames: - "store-de.example.com" rules: - backendRefs: - name: store-german port: 443sectionName欄位會選取閘道上的目標監聽器。port欄位指定的是 Service 通訊埠 (443),而非容器通訊埠。套用 TLSRoute 資訊清單:
kubectl apply -f store-tls-routes.yaml確認閘道控制器已接受路由:
kubectl get tlsroute store -o yamlstatus欄位大致如下:status: parents: - controllerName: networking.gke.io/gateway parentRef: name: store-tls sectionName: store conditions: - type: ResolvedRefs status: "True" reason: ResolvedRefs - type: Accepted status: "True" reason: Accepted - type: Reconciled status: "True" reason: ReconciliationSucceededReconciled條件是 GKE 專屬的狀態條件,會回報閘道控制器是否已建立基礎Google Cloud 資源。確認閘道監聽器已接受路徑:
kubectl get gateway store-tls -o yamlstatus.listeners欄位中的每個項目都類似於以下內容:- name: store supportedKinds: - group: gateway.networking.k8s.io kind: TLSRoute attachedRoutes: 1 conditions: - type: ResolvedRefs status: "True" reason: ResolvedRefs - type: Accepted status: "True" reason: Accepted - type: Programmed status: "True" reason: Programmed
驗證流量轉送
GKE 會與 TLS 直通後端完成 TLS 握手,藉此檢查後端的健康狀態。Pod 可能需要幾分鐘才能通過初始健康狀態檢查。
擷取閘道 IP 位址:
kubectl get gateway store-tls -o jsonpath='{.status.addresses[0].value}'將要求傳送至各個主機名稱,並將 GATEWAY_IP 替換為上一個步驟中的 IP 位址:
curl --resolve store.example.com:443:GATEWAY_IP \ --cacert store.crt https://store.example.com curl --resolve store-de.example.com:443:GATEWAY_IP \ --cacert store-de.crt https://store-de.example.com每則回覆都會指出回答的 Pod,並回應到達該 Pod 的 SNI 主機名稱:
backend: store-v1-6c4b9d8f65-kp8vr sni: store.example.com backend: store-german-7d9f8c5b47-2xqkd sni: store-de.example.com由於每項要求都使用不同的憑證授權單位檔案,且兩者都成功,因此每個後端都提供自己的憑證。負載平衡器會轉送加密連線,不會終止連線。
確認轉送作業是在 TLS 握手期間進行,也就是在用戶端傳送任何 HTTP 要求之前:
openssl s_client -connect GATEWAY_IP:443 \ -servername store-de.example.com </dev/null 2>/dev/null \ | openssl x509 -noout -subject輸出內容會顯示
store-german後端的憑證:subject=CN=store-de.example.com只要變更
-servername旗標的值,傳回的憑證就會變更,這表示負載平衡器僅根據 SNI 選取後端。傳送要求,並指定沒有任何監聽器相符的 SNI 主機名稱:
curl --resolve other.example.com:443:GATEWAY_IP \ https://other.example.com通訊埠
443沒有與 SNI 主機名稱other.example.com相符的監聽器,因此連線會關閉。
設定後端連線容量
對於 TLSRoute 資源參照的 GKE 服務,GKE Gateway 控制器會使用 CONNECTION 平衡模式設定 TCP 後端服務,並將 maxConnectionsPerEndpoint 欄位的預設值設為 100,000,000 (1e8)。
由於閘道控制器無法自動判斷容器的並行連線限制,您可以使用 GCPBackendPolicy 資源覆寫 maxConnectionsPerEndpoint 欄位的預設值 (從 1 變更為 1,000,000,000)。如要判斷後端 Pod 的最佳連線限制,請評估下列事項:
- 軟體限制:檢查伺服器或應用程式設定,例如 Apache
MaxRequestWorkers指令、NGINXworker_processes * worker_connections設定、TomcatmaxConnections屬性或資料庫連線集區限制。 - 負載測試:逐步增加與獨立 Pod 的並行連線數,同時監控 CPU、記憶體、延遲時間,以及通訊端或檔案描述元限制。
套用自訂 GCPBackendPolicy
如要覆寫 TLSRoute 後端服務上 maxConnectionsPerEndpoint 欄位的預設值,請附加 GCPBackendPolicy 資源,並將 spec.protocol 欄位設為 TCP,balancingMode 欄位設為 CONNECTION:
將下列資訊清單儲存為
backend-policy.yaml:apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: store-v1-backend-policy spec: protocol: TCP default: balancingMode: CONNECTION maxConnectionsPerEndpoint: 1000 targetRef: group: "" kind: Service name: store-v1套用政策:
kubectl apply -f backend-policy.yaml
如要進一步瞭解如何設定後端政策,請參閱「使用政策設定閘道資源」。
設定 TLS 直通的健康狀態檢查
根據預設,對於與 TLS 轉送 TLSRoute 資源相關聯的後端服務,GKE Gateway Controller 會自動佈建 SSL 類型的健康狀態檢查。
處理探測器缺少 SNI 擴充功能的情況
為 TLS 傳遞後端設定健康狀態檢查時,您必須考量 Google Cloud 健康狀態檢查探測器與 TLS 端點的互動方式。
如果後端應用程式需要有效的 SNI 主機名稱才能完成 TLS 握手,預設 SSL 健康狀態檢查就會失敗。如要解決這個問題,請採取下列其中一種方法:
- 設定備用憑證:設定後端伺服器或 Pod,在 TLS 連線不含 SNI 擴充功能時,提供預設備用 TLS 憑證。
- 搭配使用 TCP 健康狀態檢查和 HealthCheckPolicy:將 HealthCheckPolicy 資源 (
config.type欄位設為TCP) 附加至 Service,檢查原始 TCP 通訊埠連線能力,並避免 TLS 握手。
套用自訂 HealthCheckPolicy
如要設定自訂健康狀態檢查參數,或改用 TCP 健康狀態檢查,請使用 HealthCheckPolicy 資源:
將下列資訊清單儲存為
health-check-policy.yaml:apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: store-health-check spec: default: checkIntervalSec: 10 timeoutSec: 5 healthyThreshold: 2 unhealthyThreshold: 3 config: type: TCP tcpHealthCheck: port: 8443 targetRef: group: "" kind: Service name: store-service套用政策:
kubectl apply -f health-check-policy.yaml
如要進一步瞭解如何設定健康狀態檢查,請參閱「使用政策設定閘道資源」。
進階設定
本節說明 TLS 直通閘道和 TLSRoute 資源支援的進階轉送模式、多租戶設定和多叢集部署。
萬用字元主機名稱比對
TLSRoute 資源支援主機名稱的萬用字元前置字元比對,並在多個路徑與相同傳入流量相符時,遵循確定性優先順序規則。
儲存下列資訊清單,定義萬用字元 TLSRoute:
apiVersion: gateway.networking.k8s.io/v1
kind: TLSRoute
metadata:
name: wildcard-tls-route
spec:
parentRefs:
- name: store-tls
sectionName: store
hostnames:
- "*.example.com"
rules:
- backendRefs:
- name: store-v1
port: 443
優先順序和衝突解決規則
如果多個 TLSRoute 資源附加至同一個閘道監聽器,且宣告的主機名稱重疊或相同,GKE Gateway 控制器會使用與其他閘道路由相同的主機名稱特異性和建立時間戳記規則,解決衝突:
- 主機名稱完全相符 (例如
store.example.com) 的優先順序高於萬用字元相符 (例如*.example.com),而較長的萬用字元相符優先順序高於較廣泛的萬用字元相符 (例如*.com)。 - 如果兩個以上的 TLSRoute 資源宣告完全相同的主機名稱,則以建立時間戳記 (
metadata.creationTimestamp) 最早的路由為準。如果建立時間戳記相符,則以字典順序較小的<namespace>/<name>ID 為準。閘道控制器不接受衝突的路由,這類路由會回報Accepted: False條件和Conflicted原因。
如要進一步瞭解路徑優先順序,請參閱「路徑合併、優先順序和驗證」。
使用 ReferenceGrant 進行跨命名空間轉送
在多租戶環境中,集中式平台團隊可以在基礎架構命名空間 (例如 gateway-infra) 中管理閘道,而應用程式團隊則在開發人員命名空間 (例如 store-ns) 中管理 TLSRoute 和 Service 資源。
在閘道監聽器中,允許來自所有命名空間 (或所選命名空間) 的路徑:
apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: shared-tls-gateway namespace: gateway-infra spec: gatewayClassName: gke-l7-regional-external-managed listeners: - name: tls-passthrough protocol: TLS port: 443 tls: mode: Passthrough allowedRoutes: namespaces: from: All kinds: - kind: TLSRoute在應用程式命名空間 (
store-ns) 中,建立 ReferenceGrant 資源,允許gateway-infra命名空間中的閘道參照 TLSRoute 或 Service 資源:apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: allow-gateway-infra namespace: store-ns spec: from: - group: gateway.networking.k8s.io kind: Gateway namespace: gateway-infra to: - group: "" kind: Service在應用程式命名空間 (
store-ns) 中,建立參照共用閘道的 TLSRoute 資源:apiVersion: gateway.networking.k8s.io/v1 kind: TLSRoute metadata: name: store-tls-route namespace: store-ns spec: parentRefs: - name: shared-tls-gateway namespace: gateway-infra sectionName: tls-passthrough hostnames: - "store.example.com" rules: - backendRefs: - name: store-service port: 443
多叢集 TLS 直通閘道
您可以在機群中的多個 GKE 叢集,部署具備 TLS 直通功能的多叢集閘道:
- 使用支援的多叢集 GatewayClass (
gke-l7-regional-external-managed-mc、gke-l7-rilb-mc或gke-l7-cross-regional-internal-managed-mc)。 - 使用 ServiceExport 資源,在整個機群中匯出後端服務。
在 TLSRoute 資源中,使用 ServiceImport 資源參照多叢集後端:
apiVersion: gateway.networking.k8s.io/v1 kind: TLSRoute metadata: name: mc-store-tls-route spec: parentRefs: - name: mc-tls-gateway sectionName: tls-passthrough hostnames: - "store.example.com" rules: - backendRefs: - group: net.gke.io kind: ServiceImport name: store-service port: 443
多叢集閘道中的多個 IP 位址
部署跨區域多叢集閘道時 (例如使用 gke-l7-cross-regional-internal-managed-mc GatewayClass),您可以在 spec.addresses 欄位中定義多個 IP 位址,在不同區域公開內部 VIP。
在單一閘道中設定多個 IP 位址時,GKE Gateway 控制器會將每個 IP 位址轉譯為個別的轉送規則。同時,控制器會參照共用的目標 Proxy,並重複使用相同的基礎轉送設定。控制器不會將基礎 TLSRoute 資源乘以 IP 位址數量,有助於避免路徑重複和配額用盡。
以下範例顯示多叢集閘道,設定了兩個區域的臨時 IP 位址:
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: internal-cross-region-tls-gateway
spec:
gatewayClassName: gke-l7-cross-regional-internal-managed-mc
addresses:
- type: networking.gke.io/ephemeral-ipv4-address/us-west1
value: "us-west1"
- type: networking.gke.io/ephemeral-ipv4-address/us-east1
value: "us-east1"
listeners:
- name: tls-passthrough
protocol: TLS
port: 443
tls:
mode: Passthrough
allowedRoutes:
kinds:
- kind: TLSRoute
如要進一步瞭解如何部署內部多叢集閘道,請參閱「部署內部多叢集閘道」。
HTTP 連線合併
根據 RFC 7540 (第 9.1.1 節),如果符合下列兩項條件,網路瀏覽器和 HTTP/2 用戶端可以重複使用已建立的 TLS 連線,處理多個要求:
- 目標主機名稱會解析為相同的 IP 位址。
- 伺服器提供的 TLS 憑證對這兩個主機名稱都具有授權。舉例來說,如果使用萬用字元憑證 (例如
*.example.com) 或多網域主體別名 (SAN),憑證可以涵蓋多個主機名稱。
由於第 4 層 TCP Proxy 負載平衡器不會在初始 TLS 握手後檢查 HTTP 要求標頭,因此負載平衡器會透過現有連線,將聯合要求轉送至初始比對的後端 Pod。
為避免連線合併問題,請採取下列做法:
- 使用不重複、不重疊的 TLS 憑證:請勿在同一個閘道 IP 位址後方多工處理的不同後端服務之間,共用萬用字元憑證或常見的 SAN 身分。
- 傳回 HTTP 421 錯誤導向要求:設定後端 HTTPS 伺服器,檢查 HTTP
:authority(或Host) 標頭。如果要求的主機與伺服器預期的網域不符,請傳回HTTP 421 Misdirected Request狀態碼,提示用戶端開啟新連線。 - 啟用 HTTP/2 ORIGIN 框架:在原始伺服器上採用 RFC 8336 ORIGIN 框架支援,並明確宣告哪些主機名稱適用於連線重複使用。
清除所用資源
為避免系統向您的 Google Cloud 帳戶收取本頁面所用資源的費用,請刪除這些資源:
刪除 TLSRoute 資源:
kubectl delete tlsroute store store-german刪除閘道資源:
kubectl delete gateway store-tls刪除 Deployment、Service 和 Secret 範例資源:
kubectl delete -f store-tls-app.yaml kubectl delete secret store-cert store-de-cert
後續步驟
- 瞭解 GatewayClass 功能。
- 瞭解閘道安全性。
- 瞭解如何使用政策設定閘道資源。