本頁面說明如何在 Google Kubernetes Engine (GKE) 跨虛擬私有雲網路建立內部直通式網路負載平衡器。
閱讀本頁面前,請確認您已熟悉下列概念:
事前準備
開始之前,請確認您已執行下列工作:
- 啟用 Google Kubernetes Engine API。 啟用 Google Kubernetes Engine API
- 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行
gcloud components update指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文中的指令。
建立採用 Private Service Connect 的內部負載平衡器
服務生產者可以使用服務連結,透過 Private Service Connect,將服務提供給其他虛擬私有雲網路中的服務消費者。您可以使用 ServiceAttachment 自訂資源建立、管理及刪除服務連結。GKE Private Service Connect 控制器會監控 ServiceAttachment 資源,並自動在 Compute Engine 中建立、更新或刪除對應的 ServiceAttachment 資源。
需求條件和限制
- 適用 Private Service Connect 的限制。
- 您可以在 GKE 1.21.4-gke.300 以上版本中建立服務連結。
- 叢集必須啟用
HttpLoadBalancing外掛程式。新的 GKE 叢集預設會啟用HttpLoadBalancing外掛程式。 - 您無法在多項服務連結設定中使用同一個子網路。
- 您必須建立使用內部直通式網路負載平衡器的 GKE 服務。
- GKE 服務只能使用單一通訊協定。不支援混合通訊協定的 GKE 服務。
- 如果 GKE 版本早於 1.22.4-gke.100,則無法指定其他專案 (Shared VPC) 中的子網路。如果是 Shared VPC,請確保符合所有 Shared VPC 需求。
- 建立服務連結後,您就無法更新內部負載平衡器。如要變更負載平衡器設定,您必須刪除並重新建立服務連結。
Service 和 NAT 子網路的 IP 版本相容性
建立 ServiceAttachment 資源時,GKE Private Service Connect 控制器會建立單一 Compute Engine 服務連結,並與供應商轉送規則建立關聯。供應商轉送規則會使用 IPv4 位址或 IPv6 位址。下表說明控制器如何根據參照的 Kubernetes Service IP 系列設定 (spec.ipFamilies 欄位),以及 spec.natSubnets 欄位中指定的所有子網路堆疊類型,選取轉送規則:
| Kubernetes Service (轉送規則) | natSubnets 欄位中子網路的堆疊類型 |
Compute Engine 服務連結轉送規則 | 附註 |
|---|---|---|---|
| 單一堆疊 IPv4 | IPV4_ONLY、IPV4_IPV6或兩者 |
IPv4 位址 | 支援。 |
包含任何 IPV6_ONLY 子網路 |
無 (錯誤) | 設定錯誤。所有網路位址轉譯子網路都必須支援 IPv4 位址。 | |
| 雙重堆疊 (IPv4 和 IPv6 位址) | IPV4_ONLY、IPV4_IPV6 或兩者 (無 IPV6_ONLY 子網路) |
IPv4 位址 | 支援。使用 IPv4 轉送規則。IPv4 服務連結可接受來自 IPv4 和 IPv6 用戶端點的連線。 |
IPV6_ONLY,或 IPV6_ONLY 和 IPV4_IPV6 的組合 (不含 IPV4_ONLY 子網路) |
IPv6 位址 | 支援。由於有 IPV6_ONLY 子網路,因此會使用 IPv6 轉送規則。IPv6 服務連結僅接受來自 IPv6 用戶端點的連線。 |
|
同時包含 IPV4_ONLY 和 IPV6_ONLY 子網路 |
無 (錯誤) | 設定錯誤。所有網路位址轉譯子網路都必須共用相同的 IP 版本。 | |
| 單一堆疊 IPv6 | IPV6_ONLY、IPV4_IPV6或兩者 |
IPv6 位址 | 支援。 |
包含任何 IPV4_ONLY 子網路 |
無 (錯誤) | 設定錯誤。所有網路位址轉譯子網路都必須支援 IPv6 位址。 |
如要進一步瞭解用戶端點如何連線至 IPv4 和 IPv6 服務連結,請參閱「IP 版本轉譯」。
建立 ServiceAttachment
建立子網路。
您必須為每個
ServiceAttachment建立新的子網路。gcloud compute networks subnets create SUBNET_NAME \ --project PROJECT_ID \ --network NETWORK_NAME \ --region REGION \ --range SUBNET_RANGE \ --purpose PRIVATE_SERVICE_CONNECT更改下列內容:
SUBNET_NAME:新子網路的名稱。在 GKE 1.22.4-gke.100 以上版本中,您可以使用這個欄位的完整資源網址,指定其他專案中的子網路。您可以使用gcloud compute networks subnets describe指令,取得完整的資源網址。PROJECT_ID: Google Cloud專案的 ID。NETWORK_NAME:子網路的虛擬私有雲網路名稱。REGION:新子網路的區域。您必須使用與所建立服務相同的區域。SUBNET_RANGE:子網路要使用的 IPv4 位址範圍。
如要建立雙重堆疊或僅限 IPv6 的 Private Service Connect 子網路,請加入
--stack-type=IPV4_IPV6和--ipv6-access-type=INTERNAL旗標,或--stack-type=IPV6_ONLY和--ipv6-access-type=INTERNAL旗標 (使用IPV6_ONLY堆疊類型時,請省略--range旗標)。請確保子網路堆疊類型與 Service 的 IP 系列相容,詳情請參閱「Service 和 NAT 子網路的 IP 版本相容性」。部署工作負載。
下列資訊清單說明執行範例網頁應用程式容器映像檔的 Deployment。將資訊清單儲存為
my-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: psc-ilb spec: replicas: 3 selector: matchLabels: app: psc-ilb template: metadata: labels: app: psc-ilb spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - name: http containerPort: 8080 readinessProbe: httpGet: path: /healthz port: 8080 scheme: HTTP initialDelaySeconds: 5 timeoutSeconds: 1將資訊清單套用至叢集:
kubectl apply -f my-deployment.yaml建立服務。 下列資訊清單描述的服務會在 TCP 通訊埠 8080 建立內部直通式網路負載平衡器。將資訊清單儲存為
my-service.yaml:apiVersion: v1 kind: Service metadata: name: SERVICE_NAME annotations: networking.gke.io/load-balancer-type: "Internal" spec: type: LoadBalancer selector: app: psc-ilb ports: - port: 80 targetPort: 8080 protocol: TCP更改下列內容:
SERVICE_NAME:新服務的名稱。
將資訊清單套用至叢集:
kubectl apply -f my-service.yaml建立
ServiceAttachment。下列資訊清單說明
ServiceAttachment,可向服務消費者公開您建立的服務。將資訊清單儲存為my-psc.yaml:apiVersion: networking.gke.io/v1 kind: ServiceAttachment metadata: name: SERVICE_ATTACHMENT_NAME namespace: default spec: connectionPreference: ACCEPT_AUTOMATIC natSubnets: - SUBNET_NAME proxyProtocol: false reconcileConnections: false # set to true to enable connection reconciliation resourceRef: kind: Service name: SERVICE_NAME更改下列內容:
SERVICE_ATTACHMENT_NAME:新服務連結的名稱。SUBNET_NAME:新子網路的名稱。在 GKE 1.22.4-gke.100 以上版本中,您可以使用這個欄位的完整資源網址,指定其他專案中的子網路。您可以使用gcloud compute networks subnets describe指令,取得完整的資源網址。如為 Shared VPC 設定,請使用下列格式:projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/SUBNET_NAME。
如要進一步瞭解資訊清單欄位,請參閱服務連結欄位。
將資訊清單套用至叢集:
kubectl apply -f my-psc.yaml確認 Private Service Connect 控制器已建立服務連結:
gcloud compute service-attachments list輸出內容會顯示自動產生名稱的服務連結:
NAME REGION PRODUCER_FORWARDING_RULE CONNECTION_PREFERENCE k8s1-sa-... REGION_NAME a3fea439c870148bdba5e59c9ea9451a ACCEPT_AUTOMATIC
查看ServiceAttachment
您可以使用下列指令查看 ServiceAttachment 的詳細資料:
kubectl describe serviceattachment SERVICE_ATTACHMENT_NAME
輸出結果會與下列內容相似:
Name: <sa-name>
Namespace: default
Labels: <none>
Annotations: <none>
API Version: networking.gke.io/v1beta1
Kind: ServiceAttachment
Metadata:
...
Status:
Forwarding Rule URL: https://www.googleapis.com/compute/beta/projects/<project>/regions/<region>/forwardingRules/<fr-name>
Last Modified Timestamp: 2021-07-08T01:32:39Z
Service Attachment URL: https://www.googleapis.com/compute/beta/projects/<projects>/regions/<region>/serviceAttachments/<gce-service-attachment-name>
Events: <none>
使用ServiceAttachment
如要從其他專案使用服務,請按照下列步驟操作:
取得
ServiceAttachment的網址:kubectl get serviceattachment SERVICE_ATTACHMENT_NAME -o=jsonpath="{.status.serviceAttachmentURL}"輸出結果會與下列內容相似:
serviceAttachmentURL: https://www.googleapis.com/compute/alpha/projects/<project>/region/<region>/serviceAttachments/k8s1-...my-sa使用
ServiceAttachment的網址建立 Private Service Connect 端點。在用戶專案的 VM 中使用
curl指令,確認可以連線至供應商專案中部署的 Service:curl PSC_IP_ADDRESS將
PSC_IP_ADDRESS替換為用戶專案中轉送規則的 IP 位址。輸出結果會與下列內容相似:
{ "cluster_name":"cluster", "host_header":"10.128.15.200", "node_name":"gke-psc-default-pool-be9b6e0e-dvxg.c.gke_project.internal", "pod_name":"foo-7bf648dcfd-l5jf8", "pod_name_emoji":"👚", "project_id":"gke_project", "timestamp":"2021-06-29T21:32:03", "zone":"ZONE_NAME" }
更新ServiceAttachment
您可以按照下列步驟更新 ServiceAttachment:
編輯
my-psc.yaml中的ServiceAttachment資訊清單:apiVersion: networking.gke.io/v1 kind: ServiceAttachment metadata: name: my-sa namespace: default spec: connectionPreference: ACCEPT_AUTOMATIC natSubnets: - my-nat-subnet proxyProtocol: false resourceRef: kind: Service name: ilb-service將資訊清單套用至叢集:
kubectl apply -f my-psc.yaml
刪除ServiceAttachment
您無法刪除已連結至服務連結的內部直通式網路負載平衡器。您必須分別刪除服務連結和 GKE 服務。
刪除服務連結:
kubectl delete serviceattachment SERVICE_ATTACHMENT_NAME --wait=false這個指令會將服務連結標示為待刪除,但資源仍會存在。您也可以省略
--wait旗標,等待刪除作業完成。刪除 Service:
kubectl delete svc SERVICE_NAME刪除子網路:
gcloud compute networks subnets delete SUBNET_NAME
ServiceAttachment 個欄位
ServiceAttachment 包含下列欄位:
connectionPreference:連線偏好設定,決定客戶連線至服務的方式。您可以使用ACCEPT_AUTOMATIC自動核准專案,或使用ACCEPT_MANUAL明確核准專案。詳情請參閱「使用 Private Service Connect 發布服務」。natSubnets:要用於服務連結的子網路資源名稱清單。proxyProtocol:設為 true 時,要求中會提供用戶來源 IP 和 Private Service Connect 連線 ID。這是選填欄位,如未提供,預設值為 false。reconcileConnections(預先發布版):設為 true 時,如果服務消費者接受或拒絕清單有所變更,系統會自動終止現有的未授權連線。如果設為 false,變更只會影響新連線。這個欄位為選填,預設值為 false。GKE 1.36.0-gke.2459000 以上版本支援這個欄位。consumerAllowList:允許連線至ServiceAttachment的用戶端專案清單。只有在connectionPreference為ACCEPT_MANUAL時,才能使用這個欄位。如要進一步瞭解這個欄位,請參閱「使用 Private Service Connect 發布服務」。project:用戶專案的專案 ID 或編號。connectionLimit:用戶專案的連線限制。這是選填欄位。forceSendFields:要納入 API 要求的欄位名稱。這是選填欄位。nullFields:API 要求中要包含空值的欄位名稱。這是選填欄位。
consumerRejectList:不允許連線至ServiceAttachment的用戶專案 ID 或編號清單。只有在connectionPreference為ACCEPT_MANUAL時,才能使用這個欄位。如要進一步瞭解這個欄位,請參閱「使用 Private Service Connect 發布服務」。resourceRef:Kubernetes 資源的參照。kind:Kubernetes 資源類型。必須使用Service。name:Kubernetes 資源名稱,必須與內部直通式網路負載平衡器位於相同命名空間。
疑難排解
您可以使用下列指令查看錯誤訊息:
kubectl get events -n NAMESPACE
將 NAMESPACE 替換為內部直通式網路負載平衡器的命名空間。
刪除內部直通式網路負載平衡器時發生錯誤
如果嘗試刪除服務連結使用的內部直通式網路負載平衡器,系統會顯示類似下方的錯誤訊息。您必須先刪除 ServiceAttachment,才能刪除內部直通式網路負載平衡器。
Error syncing load balancer: failed to ensure load balancer: googleapi:
Error 400: The forwarding_rule resource '<fwd-rule-URL>' is already being used
by '<svc-attachment-URL>', resourceInUseByAnotherResource.
啟用全域存取權時發生錯誤
如果內部直通式網路負載平衡器使用 Private Service Connect 服務連結,您在啟用全域存取權時可能會遇到錯誤。
問題:
如果您透過更新 GKE Service 資訊清單並設定 networking.gke.io/internal-load-balancer-allow-global-access: "true" 註解來啟用全域存取權,則套用資訊清單時,更新作業會失敗。執行 kubectl get events 指令時,會看到下列錯誤訊息:
Error syncing load balancer: failed to ensure load balancer: googleapi: Error 400: The forwarding_rule resource '...' is already being used by '...', resourceInUseByAnotherResource
原因:
發生這項錯誤的原因是 GKE 控制層嘗試重新建立負載平衡器的轉送規則,以啟用全域存取權。不過,由於轉送規則正由 ServiceAttachment 使用,因此無法刪除及重新建立,導致發生錯誤。
解決方法:
如要在負載平衡器上啟用全域存取權,同時盡可能縮短停機時間,您必須更新 GKE 服務設定,並手動更新轉送規則:
更新 GKE Service 資訊清單:更新 GKE Service 資訊清單,加入
networking.gke.io/internal-load-balancer-allow-global-access: "true"註解。手動啟用轉送規則的全域存取權:按照「啟用全域存取權」中的步驟,使用Google Cloud 控制台、Google Cloud CLI 或 Compute Engine API 更新負載平衡器的轉送規則。
未同步處理的「ReconcileConnections」欄位
如果您手動啟用 Compute Engine ServiceAttachment 資源上的 ReconcileConnections 欄位,但省略 Kubernetes 資訊清單中的欄位,則該欄位會預設為 false。GKE 控制器就不會覆寫該欄位的值。
問題:
Kubernetes ServiceAttachment 資源具有 networking.gke.io/unsynced-field: ReconcileConnections 註解。執行 kubectl get events 指令時,您會看到類似下列的警告事件:
Field "ReconcileConnections" is not specified in the ServiceAttachment CR but has a value in GCE. The controller will not overwrite this field until it is explicitly set in the CR.
解決方法:
如要解決這項警告並同步處理值,請採取下列任一做法:
- 更新 GKE ServiceAttachment 資源:更新 GKE ServiceAttachment 資訊清單,加入
reconcileConnections: true(如要停用,則加入false)。 - 更新 Compute Engine ServiceAttachment 資源:手動將
reconcileConnections欄位設為false。