為 GKE 設定私人使用的公開 IP 位址


本頁說明如何將私人使用的公開 IP (PUPI) 位址套用至 Google Kubernetes Engine (GKE) Pod 位址區塊。

私用公開 IP (PUPI) 位址是指您可以在 Google Cloud 虛擬私有雲 (VPC) 網路中私下使用的位址。這些 IP 位址不屬於 Google。您不必擁有這些公開 IP 位址,即可私下使用。

總覽

GKE 叢集需要節點、Pod 和 Service 專用的 IP 位址範圍。隨著基礎架構擴大,您可能會面臨標準內部 IP 位址空間 (RFC 1918) 不足的問題。如要避免 RFC 1918 私人位址耗盡,其中一個方法是為 GKE Pod CIDR 區塊使用私人的公開 IP (PUPI) 位址。PUPI 可做為 GKE Pod 網路的替代方案,為其他叢集元件保留私有 IP 位址。

單一叢集:如果您只建立一個 GKE 叢集,可以啟用私人使用的外部 IP 位址範圍,藉此啟用 PUPI。

多個叢集:如果您使用透過 VPC 對等互連連線的多個 GKE 叢集 (服務供應商的常見情境),則需要更複雜的設定。下圖顯示一個範例,說明公司 (生產者) 如何透過虛擬私有雲對等互連,使用 PUPI 向客戶 (消費者) 提供代管服務。

GKE Pod CIDR 區塊的 PUPI 位址。

上圖涉及下列注意事項:

  • 主要 CIDR 區塊:用於節點和內部負載平衡器 (ILB) 的非 PUPI CIDR 區塊,且不得與虛擬私有雲重疊。
  • 生產者次要 CIDR 區塊:用於 Pod 的 PUPI CIDR 區塊 (例如 45.45.0.0/16)。
  • 消費者次要 CIDR 區塊:客戶端的任何其他 PUPI CIDR 區塊 (例如 5.5.0.0/16)。

服務供應商情境中 PUPI 的使用方式

服務供應商 (生產者) 會在虛擬私有雲 (vpc-producer) 內的 GKE 叢集 (gke-2) 上執行代管服務。這個叢集會使用 PUPI 範圍 45.0.0.0/8 做為 Pod IP 位址。

客戶 (消費者) 也在自己的 VPC (vpc-consumer) 中擁有 GKE 叢集 (gke-1),並使用不同的 PUPI 範圍 (5.0.0.0/8) 做為 Pod IP 位址。

這兩個 VPC 會透過 VPC 對等互連連線,但節點、服務和內部負載平衡器仍會使用標準私人 IP 位址 (RFC 1918)。

確保 VPC 之間的通訊

  • 消費者到生產者:根據預設,消費者的虛擬私有雲會自動與生產者共用 RFC 1918 路徑 (但不會共用 PUPI)。這樣一來,消費者虛擬私有雲中的資源就能存取生產者虛擬私有雲中的服務 (通常是透過內部負載平衡器)。
  • 生產者到消費者:如要讓生產者的 Pod 存取消費者虛擬私有雲中的資源,必須進行明確設定。
  • 無重疊:生產者和消費者必須確保消費者的 PUPI 範圍不會與生產者虛擬私有雲中使用的任何 IP 位址衝突。
  • 匯出/匯入:生產者必須啟用 PUPI 路徑匯出功能,消費者則必須透過對等互連連線啟用這些路徑的匯入功能。

在 PUPI 範圍重疊時啟用通訊

如果消費者的虛擬私有雲已使用與生產者相同的 PUPI 範圍,生產者 Pod 就無法直接通訊。反之,生產者可以啟用 IP 位址偽裝功能,將 Pod IP 位址隱藏在生產者的節點 IP 位址後方。

下表顯示每個 VPC 的預設匯入和匯出設定。您可以使用 gcloud compute networks peerings update 指令修改預設 VPC 對等互連設定。

虛擬私有雲網路 匯入設定 匯出設定 附註
供應者端

預設行為 (關閉):不會匯入採用公開 IP 位址的子網路路徑
如要開啟:--import-subnet-routes-with-public-ip (透過對等互連)

預設行為 (開啟):匯出具有公開 IP 位址的子網路路徑
如要關閉:--no-export-subnet-routes-with-public-ip (透過對等互連)

透過服務網路控管的旗標。
消費者 關閉 (預設) 開啟 (預設) 通常由客戶管理,不需透過服務網路修改

這些設定會產生下列結果:

  • 供應商虛擬私有雲會看到所有客戶路徑。
  • 用戶虛擬私有雲不會看到在生產端虛擬私有雲的 Pod 子網路中設定的 PUPI 路徑。
  • 從生產者 Pod 傳送至 vpc-consumer 網路的流量,必須在生產者叢集中的節點位址後方進行轉譯。

必要條件

如要在虛擬私有雲 Pod 和另一個虛擬私有雲之間建立通訊,請確保符合下列必要條件和設定:

  • GKE 叢集必須符合下列最低版本要求:
    • Autopilot 叢集:GKE 1.22 以上版本
    • 標準叢集:GKE 1.14 以上版本
  • 選取非公開路由或 Google 擁有的 PUPI 範圍。
  • 請確保兩個 VPC 的節點 IP 位址和主要 IP 位址範圍不會重疊。
  • 如要在客戶虛擬私有雲和受管理服務之間直接進行 Pod 對 Pod 通訊,請按照下列步驟操作:
    • Autopilot 叢集:為 PUPI 設定 SNAT,確保 Pod 間的通訊。您不需要額外設定。
    • 標準叢集:使用 SNAT 將 Pod IP 位址轉換為對應的節點 IP 位址。為 PUPI 流量啟用 SNAT。詳情請參閱「啟用私人使用的外部 IP 位址範圍」。

為 GKE 叢集設定私人使用的公開 IP 位址

如要為 GKE 叢集設定 PUPI 位址,請按照下列步驟操作:

  1. 設定兩個虛擬私有雲網路。
  2. 在每個虛擬私有雲網路中設定一個子網路。
  3. 在每個子網路的次要位址範圍中,設定 PUPI 位址範圍。
  4. 在兩個虛擬私有雲網路之間建立虛擬私有雲對等互連關係,並設定適當的匯入和匯出設定。
  5. 檢查每個虛擬私有雲中的路徑。

費用

本文使用下列 Google Cloud計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

事前準備

開始之前,請確認您已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

設定網路和叢集

  1. 建立虛擬私有雲網路:

    建立下列兩個虛擬私有雲網路,並以 RFC-1918 做為節點的主要範圍,以 PUPI 做為 Pod 的範圍。從 RFC 1918 私人位址空間 (例如 10.x.x.x172.16.x.x192.168.x.x) 為兩個 VPC 指派主要 IP 位址範圍。這些範圍通常用於 GKE 叢集中的工作站節點。除了內部 IP 位址範圍,請為每個 VPC 指定不同的私用公開 IP 位址 (PUPI) 範圍。這些 PUPI 範圍僅用於對應 GKE 叢集內的 Pod IP 位址。

    • 消費者虛擬私有雲網路:這個虛擬私有雲會代管 GKE 叢集,消費者應用程式或工作負載會在其中執行。您可以使用類似下列的設定:

      Network: consumer
      Subnetwork: consumer-subnet
      Primary range: 10.129.0.0/24
      Service range name and cidr: consumer-services, 172.16.5.0/24
      Pod range name and cidr: consumer-pods, 5.5.5.0/24
      Cluster name: consumer-cluster
      
    • 供應商虛擬私有雲網路:這個虛擬私有雲會代管 GKE 叢集,負責提供消費者使用的服務。您可以使用類似下列的設定:

      Network: producer
      Subnetwork: producer-subnet
      Primary range: 10.128.0.0/24
      Service range name and cidr: producer-services, 172.16.45.0/24
      Pod range name and cidr: producer-pods, 45.45.45.0/24
      Cluster name: producer-cluster
      

    如要進一步瞭解如何建立虛擬私有雲網路,請參閱「建立虛擬私有雲網路」。

  2. 使用上一個步驟中以 PUPI 範圍建立的 VPC 網路和子網路,您可以建立兩個 GKE 叢集 (producerconsumer)。

    1. 使用生產者網路和子網路建立 producer 叢集,如下所示:

      gcloud container clusters create PRODUCER_CLUSTER_NAME \
          --location=PRODUCER_CONTROL_PLANE_LOCATION \
          --enable-ip-alias \
          --network=PRODUCER_NETWORK_NAME \
          --subnetwork=PRODUCER_SUBNETWORK_NAME \
          --cluster-secondary-range-name=PRODUCER_PODS \
          --services-secondary-range-name=PRODUCER_SERVICES \
          --num-nodes=1 \
          --project=PRODUCER_PROJECT_ID
      

      更改下列內容:

      • PRODUCER_CLUSTER_NAME:GKE 生產者叢集的名稱。
      • PRODUCER_CONTROL_PLANE_LOCATION:生產者叢集控制層的 Compute Engine位置。為地區叢集提供地區,或為區域叢集提供區域。
      • PRODUCER_NETWORK_NAME:現有供應商虛擬私有雲網路的名稱。
      • PRODUCER_SUBNETWORK_NAME:現有子網路的名稱。 子網路的主要 IP 位址範圍用於節點。子網路必須與叢集使用的區域位於相同地區。如果省略這個旗標,GKE 會嘗試在叢集所在區域的 default VPC 網路中使用子網路。
      • 如果次要範圍指派方法是由 GKE 管理:
        • POD_IP_RANGE:採用 CIDR 標記法的 IP 位址範圍,例如 10.0.0.0/14,或是 CIDR 區塊子網路遮罩的大小,例如 /14。 這項設定用於建立 Pod 的子網路次要 IP 位址範圍。如果省略 --cluster-ipv4-cidr 選項,GKE 會自動選擇 /14 範圍 (218 個位址)。系統會從 10.0.0.0/8 (224 個地址的範圍) 隨機選取自動選擇的範圍。
        • SERVICES_IP_RANGE:採用 CIDR 標記法的 IP 位址範圍 (例如 10.4.0.0/19),或是 CIDR 區塊子網路遮罩的大小 (例如 /19)。這項設定用於建立服務的子網路次要 IP 位址範圍。
      • 如果次要範圍指派方法為「使用者管理」
        • SECONDARY_RANGE_PODS:指定 SUBNET_NAME 中現有次要 IP 位址範圍的名稱。 GKE 會將整個子網路次要 IP 位址範圍用於叢集的 Pod。
        • SECONDARY_RANGE_SERVICES:指定範圍中現有次要 IP 位址範圍的名稱。
      • PRODUCER_PROJECT_ID:生產者專案的 ID。
    2. 使用下列指令,以消費者網路和子網路建立 consumer 叢集:

      gcloud container clusters create CONSUMER_CLUSTER_NAME \
          --location=CONSUMER_CONTROL_PLANE_LOCATION \
          --enable-ip-alias \
          --network=CONSUMER_NETWORK_NAME \
          --subnetwork=CONSUMER_SUBNETWORK_NAME \
          --cluster-secondary-range-name=CONSUMER_PODS \
          --services-secondary-range-name=CONSUMER_SERVICES \
          --num-nodes=1 \
          --project=CONSUMER_PROJECT_ID
      

      更改下列內容:

      • CONSUMER_CLUSTER_NAME:GKE 消費者叢集的名稱。
      • CONSUMER_CONTROL_PLANE_LOCATION:消費者叢集控制層的 Compute Engine位置。為地區叢集提供地區,或為區域叢集提供區域。
      • PRODUCER_NETWORK_NAME:現有消費者 VPC 網路的名稱。
      • CONSUMER_SUBNETWORK_NAME:現有子網路的名稱。 子網路的主要 IP 位址範圍用於節點。子網路必須與叢集使用的區域位於相同地區。如果省略這個旗標,GKE 會嘗試在叢集所在區域的 default VPC 網路中使用子網路。
      • 如果次要範圍指派方法為「由 GKE 管理」
        • POD_IP_RANGE:採用 CIDR 標記法的 IP 位址範圍,例如 10.0.0.0/14,或是 CIDR 區塊子網路遮罩的大小,例如 /14。 這項設定用於建立 Pod 的子網路次要 IP 位址範圍。如果省略 --cluster-ipv4-cidr 選項,GKE 會自動選擇 /14 範圍 (218 個位址)。系統會從 10.0.0.0/8 (224 個位址的範圍) 隨機選擇範圍,且不會包含分配給 VM、現有路由或分配給其他叢集的 IP 位址範圍。系統自動選擇的範圍可能會與預留 IP 位址動態路徑或與這個叢集對等互連的 VPC 內路徑衝突。如果使用這些方法,請指定 --cluster-ipv4-cidr,以免發生衝突。
        • SERVICES_IP_RANGE:採用 CIDR 標記法的 IP 位址範圍 (例如 10.4.0.0/19),或是 CIDR 區塊子網路遮罩的大小 (例如 /19)。這項設定用於建立服務的子網路次要 IP 位址範圍。
      • 如果次要範圍指派方法為「使用者管理」
        • SECONDARY_RANGE_PODS:指定 SUBNET_NAME 中現有次要 IP 位址範圍的名稱。 GKE 會將整個子網路次要 IP 位址範圍用於叢集的 Pod。
        • SECONDARY_RANGE_SERVICES:指定範圍中現有次要 IP 位址範圍的名稱。
      • CONSUMER_PROJECT_ID:取用者專案的 ID。

    如要進一步瞭解如何建立叢集,請參閱建立叢集

  3. 在消費者虛擬私有雲網路和生產者虛擬私有雲網路之間建立 VPC 對等互連關係,方法如下:

    • 如要將 consumer 網路連線至製作人,請執行下列指令:

      gcloud compute networks peerings create CONSUMER_PEERING_NAME \
          --project=CONSUMER_PROJECT_ID \
          --network=CONSUMER_NETWORK_NAME \
          --peer-network=PRODUCER_NETWORK_NAME
      

      CONSUMER_PEERING_NAME 替換為要新增至消費者網路的對等互連名稱。

    • 如要將 producer 網路連線至消費者,請執行下列指令:

      gcloud compute networks peerings create PRODUCER_PEERING_NAME \
          --project=PRODUCER_PROJECT_ID \
          --network=PRODUCER_NETWORK_NAME \
          --peer-network=CONSUMER_NETWORK_NAME \
          --no-export-subnet-routes-with-public-ip \
          --import-subnet-routes-with-public-ip
      

      PRODUCER_PEERING_NAME 替換為要新增至生產者網路的對等互連名稱。

    根據預設,取用者 VPC 會匯出 PUPI 位址。建立生產者虛擬私有雲時,請使用下列引數設定虛擬私有雲,匯入 PUPI 位址但不匯出:

    --no-export-subnet-routes-with-public-ip
    --import-subnet-routes-with-public-ip
    

確認網路和子網路

  1. 驗證生產者網路:

    gcloud compute networks describe PRODUCER_NETWORK_NAME \
        --project=PRODUCER_PROJECT_ID
    

    輸出結果會與下列內容相似:

    ...
    kind: compute#network
    name: producer
    peerings:
    - autoCreateRoutes: true
      exchangeSubnetRoutes: true
      exportCustomRoutes: false
      exportSubnetRoutesWithPublicIp: false
      importCustomRoutes: false
      importSubnetRoutesWithPublicIp: true
      name: producer-peer-consumer
    …
    
  2. 驗證生產者子網路:

    gcloud compute networks subnets describe PRODUCER_SUBNETWORK_NAME \
        --project=PRODUCER_PROJECT_ID\
        --region=PRODUCER_CONTROL_PLANE_LOCATION
    

    輸出結果會與下列內容相似:

    ...
    ipCidrRange: 10.128.0.0/24
    kind: compute#subnetwork
    name: producer-subnet
    …
    secondaryIpRanges:
    - ipCidrRange: 172.16.45.0/24
      rangeName: producer-services
    - ipCidrRange: 45.45.45.0/24
      rangeName: producer-pods
    …
    
  3. 驗證消費者網路:

    gcloud compute networks describe CONSUMER_NETWORK_NAME \
        --project=CONSUMER_PROJECT_ID
    

    輸出結果會與下列內容相似:

    ...
    kind: compute#network
    name: consumer
    peerings:
    - autoCreateRoutes: true
      exchangeSubnetRoutes: true
      exportCustomRoutes: false
      exportSubnetRoutesWithPublicIp: true
      importCustomRoutes: false
      importSubnetRoutesWithPublicIp: false
      name: consumer-peer-producer
    ...
    
  4. 驗證消費者子網路:

    gcloud compute networks subnets describe CONSUMER_SUBNETWORK_NAME \
        --project=CONSUMER_PROJECT_ID\
        --region=CONSUMER_CONTROL_PLANE_LOCATION
    

    輸出結果會與下列內容相似:

    ...
    ipCidrRange: 10.129.0.0/24
    kind: compute#subnetwork
    name: consumer-subnet
    ...
    secondaryIpRanges:
    - ipCidrRange: 172.16.5.0/24
      rangeName: consumer-services
    - ipCidrRange: 5.5.5.0/24
      rangeName: consumer-pods
    ...
    

驗證 GKE 叢集及其資源

  1. 取得消費者叢集憑證:

    gcloud container clusters get-credentials CONSUMER_CLUSTER_NAME \
        --project=CONSUMER_PROJECT_ID \
        --location=CONSUMER_CONTROL_PLANE_LOCATION
    

    輸出結果會與下列內容相似:

    ...
    Fetching cluster endpoint and auth data.
    kubeconfig entry generated for consumer-cluster.
    ...
    
  2. 安裝並驗證 helloapp

    或者,您也可以將下列資訊清單儲存為 deployment.yaml

    kubectl apply -f - <<'EOF'
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloweb
      labels:
        app: hello
    spec:
      selector:
        matchLabels:
          app: hello
          tier: web
      template:
        metadata:
          labels:
            app: hello
            tier: web
        spec:
          containers:
          - name: hello-app
            image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
            ports:
            - containerPort: 8080
            resources:
              requests:
                cpu: 200m
    EOF
    
  3. 套用 deployment.yaml:

    kubectl apply -f
    
  4. 驗證 helloweb 部署作業:

    kubectl get deployment helloweb
    

    輸出結果會與下列內容相似:

    ...
    NAME       READY   UP-TO-DATE   AVAILABLE   AGE
    helloweb   1/1     1            1           10s
    ...
    

驗證解決方案

  1. 確認您已成功建立 VPC 對等互連:

    gcloud compute networks peerings list
    

    輸出內容會類似如下,顯示名為 consumer 和 producer 的對等互連:

    NAME                                     NETWORK    PEER_PROJECT                PEER_NETWORK                            STACK_TYPE  PEER_MTU  IMPORT_CUSTOM_ROUTES  EXPORT_CUSTOM_ROUTES  STATE   STATE_DETAILS
    consumer-peer-producer                   consumer   <project_name>             producer                                IPV4_ONLY   1460      False                 False                 ACTIVE  [2023-08-07T13:14:57.178-07:00]: Connected.
    producer-peer-consumer                   producer   <project_name>             consumer                                IPV4_ONLY   1460      False                 False                 ACTIVE  [2023-08-07T13:14:57.178-07:00]: Connected.
    
  2. 確認消費者虛擬私有雲匯出 PUPI 路徑:

    gcloud compute networks peerings list-routes CONSUMER_PEERING_NAME \
        --direction=OUTGOING \
        --network=CONSUMER_NETWORK_NAME \
        --region=CONSUMER_CONTROL_PLANE_LOCATION
    

    輸出內容會與下列內容類似,顯示所有三個消費者 CIDR 區塊:

    DEST_RANGE     TYPE                  NEXT_HOP_REGION  PRIORITY  STATUS
    10.129.0.0/24  SUBNET_PEERING_ROUTE  us-central1      0         accepted by peer
    172.16.5.0/24  SUBNET_PEERING_ROUTE  us-central1      0         accepted by peer
    5.5.5.0/24     SUBNET_PEERING_ROUTE  us-central1      0         accepted by peer
    
  3. 驗證生產者 VPC 匯入的 PUPI 路徑:

    gcloud compute networks peerings list-routes PRODUCER_PEERING_NAME \
        --direction=INCOMING \
        --network=PRODUCER_NETWORK_NAME \
        --region=PRODUCER_CONTROL_PLANE_LOCATION
    

    輸出內容會與下列內容類似,顯示所有三個消費者 CIDR 區塊:

    DEST_RANGE     TYPE                  NEXT_HOP_REGION  PRIORITY  STATUS
    10.129.0.0/24  SUBNET_PEERING_ROUTE  us-central1      0         accepted
    172.16.5.0/24  SUBNET_PEERING_ROUTE  us-central1      0         accepted
    5.5.5.0/24     SUBNET_PEERING_ROUTE  us-central1      0         accepted
    
  4. 確認 GKE Pod 是否有 PUPI 位址:

    kubectl get pod -o wide
    

    輸出內容會與下列內容類似,顯示 Pod 的 IP 位址落在 5.5.5/24 範圍內。

    NAME                        READY   STATUS    RESTARTS   AGE   IP         NODE                                              NOMINATED NODE   READINESS GATES
    helloweb-575d78464d-xfklj   1/1     Running   0          28m   5.5.5.16   gke-consumer-cluster-default-pool-e62b6542-dp5f   <none>           <none>
    

後續步驟