本頁說明如何在 Google Kubernetes Engine (GKE) 上建立內部直通式網路負載平衡器或內部負載平衡器。如要建立外部直通式網路負載平衡器,請參閱「建立 LoadBalancer 類型的服務」。
閱讀本頁面之前,請務必熟悉下列概念:
使用內部直通式網路負載平衡器
內部直通網路負載平衡器可讓位於叢集虛擬私有雲網路的用戶端,以及連線至叢集虛擬私有雲網路的網路中的用戶端,存取叢集的服務。叢集虛擬私有雲網路中的用戶端可以是叢集的節點或 Pod,也可以是叢集外部的 VM。如要進一步瞭解已連線網路中用戶端的連線,請參閱內部直通網路負載平衡器和已連線的網路。
使用 GKE 子設定
GKE 子集會使用GCE_VM_IP
網路端點群組 (NEG) 做為後端,而非執行個體群組,因此可提升內部 LoadBalancer 服務的擴充性。啟用 GKE 子集後,GKE 會為每個內部 LoadBalancer Service,在每個運算區域中建立一個 NEG。
Service 的 externalTrafficPolicy
會控管 GCE_VM_IP
NEG 後端的節點成員資格。詳情請參閱「節點在 GCE_VM_IP
NEG 後端的成員資格」。
需求條件和限制
以下是內部負載平衡器的規定和限制。
需求條件
GKE 子集有下列限制和規定:
- 您可以在 GKE 1.18.19-gke.1400 以上版本的 GKE 標準叢集啟用子設定。GKE 子集啟用後即無法停用。
- Autopilot 叢集預設會停用 GKE 子集化功能。不過,您可以在建立叢集後啟用這項功能。
- 如要使用 GKE 子設定,必須啟用
HttpLoadBalancing
外掛程式。這項外掛程式預設為啟用。在 Autopilot 叢集中,您無法停用這個必要的外掛程式。 - 適用網路端點群組配額。 Google Cloud 會為每個可用區的每個內部 LoadBalancer Service 建立一個
GCE_VM_IP
NEG。 - 適用於轉送規則、後端服務和健康狀態檢查的配額。詳情請參閱配額與限制。
- 使用註解在多個負載平衡器之間共用後端服務時,無法使用 GKE 子集,
alpha.cloud.google.com/load-balancer-backend-share
。 - 您必須使用 Google Cloud CLI 345.0.0 以上版本。
限制
內部直通式網路負載平衡器
- 對於執行 Kubernetes 1.7.4 以上版本的叢集,您可以使用內部負載平衡器搭配自動模式子網路或自訂模式子網路。
- 如果使用
--purpose
旗標將SHARED_LOADBALANCER_VIP
設為保留 IP 位址,則執行 Kubernetes 1.7.X 以上版本的叢集,支援將保留 IP 位址用於內部直通式網路負載平衡器。如需逐步操作說明,請參閱「啟用共用 IP」。只有在 Service 參照內部 IP 位址時,GKE 才會保留內部直通式網路負載平衡器的 IP 位址。否則,如果更新 Service (例如變更通訊埠),GKE 可能會變更負載平衡器的 IP 位址 (spec.loadBalancerIP
)。 - 即使負載平衡器的 IP 位址變更 (請參閱上一個重點),
spec.clusterIP
仍會維持不變。 - 內部 UDP 負載平衡器不支援使用
sessionAffinity: ClientIP
。
事前準備
開始之前,請確認你已完成下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update
,取得最新版本。
- 確認您有現有的 Autopilot 或 Standard 叢集。如要建立新叢集,請參閱「建立 Autopilot 叢集」。
在叢集中啟用 GKE 子集化功能
您可以使用 gcloud CLI 或 Google Cloud console,為現有叢集啟用 GKE 子集。啟用 GKE 子集後,就無法停用這項功能。
控制台
在 Google Cloud 控制台中,前往「Google Kubernetes Engine」頁面。
在叢集清單中,按一下您要修改的叢集名稱。
在「Networking」(網路) 下方,點選「Subsetting for L4 Internal Load Balancers」(L4 內部負載平衡器的子設定) 欄位旁的 edit「Enable subsetting for L4 internal load balancers」(啟用 L4 內部負載平衡器的子設定)。
勾選「啟用 L4 內部負載平衡器的子設定」核取方塊。
按一下 [儲存變更]。
gcloud
gcloud container clusters update CLUSTER_NAME \
--enable-l4-ilb-subsetting
更改下列內容:
CLUSTER_NAME
:叢集名稱。
啟用 GKE 子集化功能不會中斷現有的內部 LoadBalancer 服務。如要遷移現有的內部 LoadBalancer 服務,改為使用以 GCE_VM_IP
NEG 做為後端的後端服務,您必須部署替代服務資訊清單。詳情請參閱 LoadBalancer Service 概念說明文件中的節點分組。
部署工作負載
下列資訊清單說明執行範例網路應用程式容器映像檔的部署。
將資訊清單儲存為
ilb-deployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: ilb-deployment spec: replicas: 3 selector: matchLabels: app: ilb-deployment template: metadata: labels: app: ilb-deployment spec: containers: - name: hello-app image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
將資訊清單套用至叢集:
kubectl apply -f ilb-deployment.yaml
建立內部 LoadBalancer 服務
(選用) 停用自動建立虛擬私有雲防火牆規則:
GKE 會自動建立虛擬私有雲防火牆規則,允許流量傳送至內部負載平衡器,但您可以選擇停用自動建立虛擬私有雲防火牆規則的功能,自行管理防火牆規則。只有在為內部 LoadBalancer Service 啟用 GKE 子設定時,才能停用虛擬私有雲防火牆規則。不過,管理虛擬私有雲防火牆規則是選用功能,您也可以使用自動規則。
停用自動建立虛擬私有雲防火牆規則前,請務必定義允許規則,允許流量傳送至負載平衡器和應用程式 Pod。
如要進一步瞭解如何管理虛擬私有雲防火牆規則,請參閱「管理自動建立的防火牆規則」一文。如要瞭解如何停用自動建立防火牆規則的功能,請參閱「GKE LoadBalancer Service 的使用者管理防火牆規則」一文。
下列範例會使用 TCP 連接埠
80
建立內部 LoadBalancer 服務。GKE 會部署內部直通式網路負載平衡器,其轉送規則使用通訊埠80
,但會將流量轉送至通訊埠8080
的後端 Pod:將資訊清單儲存為
ilb-svc.yaml
:apiVersion: v1 kind: Service metadata: name: ilb-svc annotations: networking.gke.io/load-balancer-type: "Internal" spec: type: LoadBalancer externalTrafficPolicy: Cluster selector: app: ilb-deployment ports: - name: tcp-port protocol: TCP port: 80 targetPort: 8080
資訊清單必須包含下列內容:
- 內部 LoadBalancer 服務的
name
,在本例中為ilb-svc
。 - 指定您需要內部 LoadBalancer 服務的註解。如果是 GKE 1.17 以上版本,請使用
networking.gke.io/load-balancer-type: "Internal"
註解,如範例資訊清單所示。如為舊版,請改用cloud.google.com/load-balancer-type: "Internal"
。 type: LoadBalancer
。spec: selector
欄位,用於指定服務應指向的 Pod,例如app: hello
。- 通訊埠資訊:
port
代表目的地通訊埠,內部直通式網路負載平衡器的轉送規則會透過該通訊埠接收封包。targetPort
必須與每個服務 Pod 上定義的containerPort
相符。port
和targetPort
的值不必相同。節點一律會執行目的地 NAT,將目的地負載平衡器轉送規則 IP 位址和port
變更為目的地 Pod IP 位址和targetPort
。詳情請參閱 LoadBalancer 服務概念說明文件中的「節點上的目的地網路位址轉譯」。
資訊清單可包含下列項目:
spec.ipFamilyPolicy
和ipFamilies
,定義 GKE 如何將 IP 位址分配給 Service。GKE 支援單一堆疊 (僅限 IPv4 或 IPv6),或雙重堆疊 IP LoadBalancer 服務。雙重堆疊 LoadBalancer 服務會透過兩個不同的內部直通網路負載平衡器轉送規則實作:一個用於 IPv4 流量,另一個用於 IPv6 流量。GKE 雙堆疊 LoadBalancer 服務適用於 1.29 以上版本。詳情請參閱「IPv4/IPv6 雙重堆疊服務」。
詳情請參閱「LoadBalancer 服務參數」
- 內部 LoadBalancer 服務的
將資訊清單套用至叢集:
kubectl apply -f ilb-svc.yaml
取得服務的詳細資訊:
kubectl get service ilb-svc --output yaml
輸出結果會與下列內容相似:
apiVersion: v1 kind: Service metadata: annotations: cloud.google.com/neg: '{"ingress":true}' cloud.google.com/neg-status: '{"network_endpoint_groups":{"0":"k8s2-pn2h9n5f-default-ilb-svc-3bei4n1r"},"zones":["ZONE_NAME","ZONE_NAME","ZONE_NAME"]}' kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"networking.gke.io/load-balancer-type":"Internal"},"name":"ilb-svc","namespace":"default"},"spec":{"externalTrafficPolicy":"Cluster","ports":[{"name":"tcp-port","port":80,"protocol":"TCP","targetPort":8080}],"selector":{"app":"ilb-deployment"},"type":"LoadBalancer"}} networking.gke.io/load-balancer-type: Internal service.kubernetes.io/backend-service: k8s2-pn2h9n5f-default-ilb-svc-3bei4n1r service.kubernetes.io/firewall-rule: k8s2-pn2h9n5f-default-ilb-svc-3bei4n1r service.kubernetes.io/firewall-rule-for-hc: k8s2-pn2h9n5f-l4-shared-hc-fw service.kubernetes.io/healthcheck: k8s2-pn2h9n5f-l4-shared-hc service.kubernetes.io/tcp-forwarding-rule: k8s2-tcp-pn2h9n5f-default-ilb-svc-3bei4n1r creationTimestamp: "2022-07-22T17:26:04Z" finalizers: - gke.networking.io/l4-ilb-v2 - service.kubernetes.io/load-balancer-cleanup name: ilb-svc namespace: default resourceVersion: "51666" uid: d7a1a865-7972-44e1-aa9e-db5be23d6567 spec: allocateLoadBalancerNodePorts: true clusterIP: 10.88.2.141 clusterIPs: - 10.88.2.141 externalTrafficPolicy: Cluster internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - name: tcp-port nodePort: 30521 port: 80 protocol: TCP targetPort: 8080 selector: app: ilb-deployment sessionAffinity: None type: LoadBalancer status: loadBalancer: ingress: - ip: 10.128.15.245
輸出內容具有下列屬性:
- 內部直通式網路負載平衡器轉送規則的 IP 位址會納入
status.loadBalancer.ingress
。這個 IP 位址與clusterIP
的值不同。在本範例中,負載平衡器的轉送規則 IP 位址為10.128.15.245
。 - 任何具有
app: ilb-deployment
標籤的 Pod 都是這個 Service 的服務 Pod。這些是接收內部直通式網路負載平衡器所轉送封包的 Pod。 - 用戶端會使用這個
loadBalancer
IP 位址,以及 Service 資訊清單的port
欄位中指定的 TCP 目的地通訊埠來呼叫 Service。如要瞭解節點收到封包後如何轉送,請參閱封包處理。 - GKE 為服務指派了
nodePort
;在本範例中,指派的通訊埠為30521
。nodePort
與內部直通式網路負載平衡器無關。
- 內部直通式網路負載平衡器轉送規則的 IP 位址會納入
檢查服務網路端點群組:
kubectl get svc ilb-svc -o=jsonpath="{.metadata.annotations.cloud\.google\.com/neg-status}"
輸出結果會與下列內容相似:
{"network_endpoint_groups":{"0":"k8s2-knlc4c77-default-ilb-svc-ua5ugas0"},"zones":["ZONE_NAME"]}
回應指出 GKE 已建立名為
k8s2-knlc4c77-default-ilb-svc-ua5ugas0
的網路端點群組。使用 GKE 子集的LoadBalancer
類型服務會顯示這項註解,未使用 GKE 子集的服務則不會顯示。
驗證內部直通式網路負載平衡器元件
在「建立內部 LoadBalancer 服務」一節的範例中,內部直通式網路負載平衡器的轉送規則 IP 位址為 10.128.15.245
。您可以使用 Google Cloud CLI,查看這個轉送規則是否已納入叢集專案的轉送規則清單:
gcloud compute forwarding-rules list --filter="loadBalancingScheme=INTERNAL"
輸出內容會包含相關的內部直通式網路負載平衡器轉送規則、其 IP 位址,以及轉送規則參照的後端服務 (本例中為 k8s2-pn2h9n5f-default-ilb-svc-3bei4n1r
)。
NAME ... IP_ADDRESS ... TARGET
...
k8s2-tcp-pn2h9n5f-default-ilb-svc-3bei4n1r 10.128.15.245 ZONE_NAME/backendServices/k8s2-pn2h9n5f-default-ilb-svc-3bei4n1r
您可以使用 Google Cloud CLI 說明負載平衡器的後端服務:
gcloud compute backend-services describe k8s2-tcp-pn2h9n5f-default-ilb-svc-3bei4n1r --region=COMPUTE_REGION
將 COMPUTE_REGION
替換為後端服務的 Compute 區域。
輸出內容包含服務的後端 GCE_VM_IP
NEG 或 NEG (本例中為 k8s2-pn2h9n5f-default-ilb-svc-3bei4n1r
):
backends:
- balancingMode: CONNECTION
group: .../ZONE_NAME/networkEndpointGroups/k8s2-pn2h9n5f-default-ilb-svc-3bei4n1r
...
kind: compute#backendService
loadBalancingScheme: INTERNAL
name: aae3e263abe0911e9b32a42010a80008
...
如要判斷服務子集中的節點清單,請使用下列指令:
gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME \
--zone=COMPUTE_ZONE
更改下列內容:
NEG_NAME
:由 GKE 控制器建立的網路端點群組名稱。COMPUTE_ZONE
:要執行的網路端點群組的運算區域。
如要判斷內部直通式網路負載平衡器的健康節點清單,請使用下列指令:
gcloud compute backend-services get-health SERVICE_NAME \
--region=COMPUTE_REGION
更改下列內容:
SERVICE_NAME
:後端服務的名稱。這個值與 GKE 控制器建立的網路端點群組名稱相同。COMPUTE_REGION
:要執行的後端服務運算區域。
測試與內部直通式網路負載平衡器之間的連線
在與叢集相同的區域中執行下列指令:
curl LOAD_BALANCER_IP:80
將 LOAD_BALANCER_IP
替換為負載平衡器的轉送規則 IP 位址。
回應會顯示 ilb-deployment
的輸出:
Hello, world!
Version: 1.0.0
Hostname: ilb-deployment-77b45987f7-pw54n
內部直通式網路負載平衡器只能在同一個 VPC 網路 (或已連線的網路) 內存取。 根據預設,負載平衡器的轉送規則會停用全域存取權,因此用戶端 VM、Cloud VPN 通道或 Cloud Interconnect 連結 (VLAN) 必須與內部直通式網路負載平衡器位於相同地區。如要支援所有區域的用戶端,您可以在服務資訊清單中加入 global access 註解,在負載平衡器的轉送規則中啟用全域存取權。
刪除內部 LoadBalancer Service 和負載平衡器資源
您可以使用 kubectl delete
或Google Cloud 控制台刪除 Deployment 和 Service。
kubectl
刪除部署作業
如要刪除 Deployment,請執行下列指令:
kubectl delete deployment ilb-deployment
刪除服務
如要刪除 Service,請執行下列指令:
kubectl delete service ilb-svc
控制台
刪除部署作業
如要刪除 Deployment,請執行下列步驟:
前往 Google Cloud 控制台的「Workloads」(工作負載) 頁面。
選取要刪除的部署作業,然後按一下 delete「刪除」。
系統提示您確認時,請選取「Delete Horizontal Pod Autoscaler associated with selected Deployment」(刪除與所選 Deployment 相關聯的水平 Pod 自動配置器) 核取方塊,然後按一下「Delete」(刪除)。
刪除服務
如要刪除服務,請執行下列步驟:
前往 Google Cloud 控制台的「Services & Ingress」(服務與 Ingress) 頁面。
選取要刪除的服務,然後按一下 delete「刪除」。
當系統提示時,按一下「Delete」(刪除)。
共用 IP
內部直通式網路負載平衡器可讓多個轉送規則共用虛擬 IP 位址。這項功能有助於擴充同一 IP 上的並行通訊埠數量,或在同一 IP 上接受 UDP 和 TCP 流量。每個 IP 位址最多可公開 50 個通訊埠。在具有內部 LoadBalancer 服務的 GKE 叢集上,系統會原生支援共用 IP。部署時,系統會使用「服務」的 loadBalancerIP
欄位,指出應在「服務」之間共用的 IP。
限制
多個負載平衡器共用 IP 時,有以下限制和功能:
- 每個轉送規則最多可以有五個通訊埠 (連續或不連續皆可),也可以設定為比對並轉送所有通訊埠的流量。如果 Internal LoadBalancer Service 定義超過五個通訊埠,轉送規則會自動設為比對所有通訊埠。
- 最多十個服務 (轉送規則) 可以共用一個 IP 位址。因此每個共用 IP 最多只能有 50 個通訊埠。
- 共用相同 IP 位址的每個轉送規則,都必須使用不重複的通訊協定和通訊埠組合。因此,每個內部 LoadBalancer 服務都必須使用一組不重複的通訊協定和連接埠。
- 在同一個共用 IP 上,系統支援僅限 TCP 和僅限 UDP 的服務組合,但您無法在同一個服務中公開 TCP 和 UDP 連接埠。
啟用共用 IP
如要讓內部 LoadBalancer 服務共用 IP,請按照下列步驟操作:
使用
--purpose SHARED_LOADBALANCER_VIP
建立靜態內部 IP。您必須建立專用的 IP 位址,才能啟用共用功能。如果您在共用虛擬私有雲中建立靜態內部 IP 位址,則必須在與使用該 IP 位址的執行個體相同的服務專案中建立 IP 位址,即使 IP 位址的值來自共用虛擬私有雲網路所選共用子網路的可用 IP 範圍也一樣。詳情請參閱「佈建共用虛擬私人雲端」頁面上的保留靜態內部 IP 一節。使用這個靜態 IP,在
loadBalancerIP
欄位中部署最多十個內部 LoadBalancer 服務。內部直通式網路負載平衡器會由 GKE 服務控制器進行協調,並使用相同的前端 IP 進行部署。
以下範例說明如何執行這項操作,以支援相同內部負載平衡器 IP 的多個 TCP 和 UDP 連接埠。
在與 GKE 叢集相同的地區中建立靜態 IP。子網路必須與負載平衡器使用的子網路相同,預設情況下,這與 GKE 叢集節點 IP 使用的子網路相同。
如果叢集和虛擬私有雲網路位於同一個專案:
gcloud compute addresses create IP_ADDR_NAME \ --project=PROJECT_ID \ --subnet=SUBNET \ --addresses=IP_ADDRESS \ --region=COMPUTE_REGION \ --purpose=SHARED_LOADBALANCER_VIP
如果叢集位於共用虛擬私有雲服務專案中,但使用主專案中的共用虛擬私有雲網路:
gcloud compute addresses create IP_ADDR_NAME \ --project=SERVICE_PROJECT_ID \ --subnet=projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/SUBNET \ --addresses=IP_ADDRESS \ --region=COMPUTE_REGION \ --purpose=SHARED_LOADBALANCER_VIP
更改下列內容:
IP_ADDR_NAME
:IP 位址物件的名稱。SERVICE_PROJECT_ID
:服務專案的 ID。PROJECT_ID
:專案 ID (單一專案)。HOST_PROJECT_ID
:共用虛擬私有雲主專案的 ID。COMPUTE_REGION
:包含共用子網路的運算區域。IP_ADDRESS
:所選子網路主要 IP 位址範圍中未使用的內部 IP 位址。如果省略指定 IP 位址, Google Cloud 會從所選子網路的主要 IP 位址範圍中,選取未使用的內部 IP 位址。如要判斷自動選取的地址,您需要執行gcloud compute addresses describe
。SUBNET
:共用子網路的名稱。
將下列 TCP 服務設定儲存至名為
tcp-service.yaml
的檔案,然後部署至叢集。將IP_ADDRESS
替換為您在上一個步驟中選擇的 IP 位址。apiVersion: v1 kind: Service metadata: name: tcp-service namespace: default annotations: networking.gke.io/load-balancer-type: "Internal" spec: type: LoadBalancer loadBalancerIP: IP_ADDRESS selector: app: myapp ports: - name: 8001-to-8001 protocol: TCP port: 8001 targetPort: 8001 - name: 8002-to-8002 protocol: TCP port: 8002 targetPort: 8002 - name: 8003-to-8003 protocol: TCP port: 8003 targetPort: 8003 - name: 8004-to-8004 protocol: TCP port: 8004 targetPort: 8004 - name: 8005-to-8005 protocol: TCP port: 8005 targetPort: 8005
將這個 Service 定義套用至叢集:
kubectl apply -f tcp-service.yaml
將下列 UDP 服務設定儲存到名為
udp-service.yaml
的檔案,然後部署。也會使用您在上一個步驟中指定的IP_ADDRESS
。apiVersion: v1 kind: Service metadata: name: udp-service namespace: default annotations: networking.gke.io/load-balancer-type: "Internal" spec: type: LoadBalancer loadBalancerIP: IP_ADDRESS selector: app: my-udp-app ports: - name: 9001-to-9001 protocol: UDP port: 9001 targetPort: 9001 - name: 9002-to-9002 protocol: UDP port: 9002 targetPort: 9002
將這個檔案套用至叢集:
kubectl apply -f udp-service.yaml
列出負載平衡器轉送規則並篩選靜態 IP,確認 VIP 在這些規則之間共用。這表示 UDP 和 TCP 轉送規則都在共用
IP_ADDRESS
的七個不同通訊埠上監聽,在本例中為10.128.2.98
。gcloud compute forwarding-rules list | grep 10.128.2.98 ab4d8205d655f4353a5cff5b224a0dde us-west1 10.128.2.98 UDP us-west1/backendServices/ab4d8205d655f4353a5cff5b224a0dde acd6eeaa00a35419c9530caeb6540435 us-west1 10.128.2.98 TCP us-west1/backendServices/acd6eeaa00a35419c9530caeb6540435
已知問題
每 10 分鐘連線逾時
使用子集建立的內部 LoadBalancer 服務,大約每 10 分鐘就會發生一次流量中斷。這個錯誤已在下列版本中修正:
- 1.18.19-gke.1700 以上版本
- 1.19.10-gke.1000 以上版本
- 1.20.6-gke.1000 以上版本
在 Standard 層級建立負載平衡器時發生錯誤
在專案預設網路層級設為「標準」的專案中建立內部直通式網路負載平衡器時,會顯示下列錯誤訊息:
Error syncing load balancer: failed to ensure load balancer: googleapi: Error 400: STANDARD network tier (the project's default network tier) is not supported: Network tier other than PREMIUM is not supported for loadBalancingScheme=INTERNAL., badRequest
如要在 1.23.3-gke.900 之前的 GKE 版本中解決這個問題,請將專案預設網路層級設為「進階」。
啟用 GKE 子集後,GKE 1.23.3-gke.900 以上版本已解決這個問題。
即使專案預設網路層級設為 Standard,GKE 控制器仍會在 Premium 網路層級中建立內部直通式網路負載平衡器。
後續步驟
- 閱讀 GKE 網路總覽。
- 進一步瞭解 Compute Engine 負載平衡器。
- 瞭解如何建立虛擬私有雲原生叢集。
- 排解 GKE 中的負載平衡問題。
- 瞭解 IP 偽裝代理程式。
- 瞭解如何設定授權網路。