本文說明如何在 GKE 中建立 Google Cloud 外部直通式網路負載平衡器和內部直通式網路負載平衡器資源,將多網路 Pod 公開給內部或外部用戶端。說明多重網路LoadBalancer服務的必要設定、功能和限制。
如果將工作負載連線至多個 VPC 網路,請使用 LoadBalancer 類型的 Kubernetes 服務,將流量轉送至特定次要網路上的 Pod。建立 Service 時,GKE 會建立直通式網路負載平衡器來管理這類流量。
如要進一步瞭解 GKE 中的多重網路,請參閱「關於 Pod 的多重網路支援」。
多重網路 LoadBalancer 服務的運作方式
如要公開多網路工作負載,請建立 Service 的 type: LoadBalancer。
Service 必須包含特殊選取器,根據次要介面的網路指定 Pod。新增註解,指定要建立內部或外部負載平衡器。
選取器中的 networking.gke.io/network 標籤會依網路篩選端點。這個標籤可確保負載平衡器只會將流量傳送到連線至指定網路的 Pod 介面。
限制
多重網路負載平衡器有下列限制:
- 不支援使用
externalTrafficPolicy: Cluster的服務。 - 系統不支援以
hostNetworkPod 為目標的服務。 - 不支援 IPv6 和雙重堆疊網路。
- 您無法變更現有服務的網路。
- 僅支援第 3 層網路。
- 系統不支援以目標集區或執行個體群組後端為基礎的負載平衡器。
- 次要 (非預設) 網路不支援 ClusterIP 和 NodePort 服務。
事前準備
開始之前,請先完成下列工作:
- 按照「為 Pod 設定多網路支援功能」中的步驟,準備虛擬私有雲網路,並建立具有額外網路的 GKE 叢集。
- 確認叢集已啟用第 4 層內部負載平衡器的子設定。如要啟用這項功能,請在建立或更新叢集時使用
--enable-l4-ilb-subsetting旗標。 - 確認叢集執行的是 GKE 1.37 以上版本。
部署多網路 Pod
如要將 Pod 附加至其他網路,請使用 networking.gke.io/interfaces 註解建立 Deployment。這項註解會指定 Pod 的網路和介面。
將下列資訊清單儲存為
web-app-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: web-app labels: app: web-app spec: replicas: 3 selector: matchLabels: app: web-app template: metadata: labels: app: web-app annotations: networking.gke.io/default-interface: 'eth1' networking.gke.io/interfaces: '[ {"interfaceName":"eth0","network":"default"}, {"interfaceName": "eth1","network": "dmz"} ]' spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080這份資訊清單會建立名為
web-app的 Deployment,當中包含三個 Pod。Pod 有兩個介面:eth0連線至default網路,以及eth1連線至dmz網路。networking.gke.io/default-interface註解會將eth1設為 Pod 的預設介面。將資訊清單套用至叢集:
kubectl apply -f web-app-deployment.yaml
如果服務使用非預設介面,您必須在 Pod 中設定路由。如要設定路由,請在 Pod 規格中新增 initContainer,該規格具備 NET_ADMIN 功能。
以下範例顯示 initContainer,可為 eth1 介面新增預設路徑:
initContainers:
- name: init-routes-busybox
image: busybox
command: ['sh', '-c', 'ip route add default dev eth1 table 200 && ip rule add from 172.16.1.0/24 table 200']
securityContext:
capabilities:
add: ["NET_ADMIN"]
在 initContainer 指令中,將 172.16.1.0/24 替換為 Pod 網路的次要 IP 位址範圍。
部署內部 LoadBalancer 服務
如要在 dmz 網路中公開 web-app Deployment,請建立內部 LoadBalancer 服務。
將下列資訊清單儲存為
internal-lb-service.yaml:apiVersion: v1 kind: Service metadata: name: web-app-internal-lb namespace: default annotations: networking.gke.io/load-balancer-type: "Internal" spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 8080 selector: networking.gke.io/network: dmz app: web-app type: LoadBalancer這份資訊清單會建立具備下列屬性的 Service:
networking.gke.io/load-balancer-type: "Internal":指定內部直通式網路負載平衡器。selector:選取具有app: web-app標籤且連線至dmz網路的 Pod。
將資訊清單套用至叢集:
kubectl apply -f internal-lb-service.yaml
部署外部 LoadBalancer 服務
如要向外部用戶端公開 web-app Deployment,請建立外部 LoadBalancer Service。
將下列資訊清單儲存為
external-lb-service.yaml:apiVersion: v1 kind: Service metadata: name: web-app-external-lb namespace: default annotations: cloud.google.com/l4-rbs: "enabled" spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 8080 selector: networking.gke.io/network: dmz app: web-app type: LoadBalancer這份資訊清單會建立具備下列屬性的 Service:
cloud.google.com/l4-rbs: "enabled":指定以後端服務為基礎的外部直通式網路負載平衡器。selector:選取具有app: web-app標籤且連線至dmz網路的 Pod。
將資訊清單套用至叢集:
kubectl apply -f external-lb-service.yaml
驗證服務
部署服務後,請確認負載平衡器已建立並正確設定。
檢查服務狀態:
kubectl get services輸出結果會與下列內容相似:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE web-app-external-lb LoadBalancer 10.8.47.77 35.239.57.231 80:31550/TCP 5m web-app-internal-lb LoadBalancer 10.8.43.251 172.16.0.43 80:32628/TCP 6m kubernetes ClusterIP 10.8.32.1 <none> 443/TCP 43h內部負載平衡器的
EXTERNAL-IP位址屬於dmz網路。列出專案中的轉送規則:
gcloud compute forwarding-rules list輸出結果會與下列內容相似:
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET af901673cc0f24907a6aa8c3ce4afc21 us-central1 35.239.57.231 TCP us-central1/backendServices/k8s2-xhvzqabw-default-web-app-external-lb-u4xbs4ot k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a us-central1 172.16.0.43 TCP us-central1/backendServices/k8s2-xhvzqabw-default-web-app-internal-lb-vp1x1d6a說明內部負載平衡器的轉送規則,確認該規則已附加至正確的網路:
gcloud compute forwarding-rules describe k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a --region=$REGION將
REGION替換為叢集所在區域。輸出結果大致如下。確認
network和subnetwork欄位與dmz網路的詳細資料相符。IPAddress: 172.16.0.43 IPProtocol: TCP ... loadBalancingScheme: INTERNAL name: k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a network: https://www.googleapis.com/compute/v1/projects/projectId/global/networks/dmz-vpc ... subnetwork: https://www.googleapis.com/compute/v1/projects/projectId/regions/us-central1/subnetworks/dmz-subnet
測試負載平衡器
如要測試外部負載平衡器,請將要求傳送至其外部 IP 位址:
curl EXTERNAL_LB_IP:80將
EXTERNAL_LB_IP替換為web-app-external-lb服務的外部 IP 位址。如要測試內部負載平衡器,請從與負載平衡器位於相同 VPC 的主機傳送要求:
curl INTERNAL_LB_IP:80將
INTERNAL_LB_IP替換為web-app-internal-lb服務的 IP 位址。
疑難排解
本節說明如何排解多重網路負載平衡器的問題。
無法建立負載平衡器
如果無法建立負載平衡器,請檢查服務事件中的錯誤訊息:
kubectl describe service SERVICE_NAME
將 SERVICE_NAME 改為您的服務名稱。
如果出現 network some-other-network does not exist 等錯誤訊息,表示叢集未定義服務選取器中指定的網路。確認網路是否存在:
kubectl get networks
如果網路存在,請確認 Network 物件是否正確參照有效的 GKENetworkParamSet 資源。如要檢查設定錯誤,請檢查 Network 資源狀態:
kubectl get networks NETWORK_NAME -o yaml
請將 NETWORK_NAME 替換成您網路的名稱。
在有效設定中,ParamsReady 和 Ready 條件都是 True。如果 ParamsReady 不是 True,請確認 Network 規格中的 parametersRef 與現有 GKENetworkParamSet 資源的名稱、種類和群組正確相符。
如果 Network 資源正確,但仍未準備就緒,請檢查參照 GKENetworkParamSet 的狀態是否有錯誤,例如缺少子網路:
kubectl get gkenetworkparamsets GNP_NAME -o yaml
將 GNP_NAME 替換為 GKENetworkParamSet 的名稱。
負載平衡器沒有後端
如果負載平衡器已佈建,但沒有健康狀態良好的後端,請執行下列操作:
- 確認節點集區存在於服務使用的網路中,且具有網路介面。
- 確認服務選取的 Pod 正在執行。
檢查服務的端點:
kubectl describe endpointslice -l kubernetes.io/service-name=SERVICE_NAMEmultinet-endpointslice-controller.gke.io控制器會建立多重網路端點。EndpointSlice 中列出的 Pod IP 位址屬於 Service 使用的網路。如果 EndpointSlice 沒有端點,請確認服務選取器標籤與正在執行的 Pod 相符,且網路選取器與 Pod 的網路相符。
後續步驟
- 瞭解 Pod 的多網路支援功能。
- 瞭解多重網路服務。