GKE にプライベートで使用されるパブリック IP アドレスを構成する


このチュートリアルでは、Google Kubernetes Engine(GKE) Pod のアドレス ブロックに、プライベートで使用されるパブリック IP(PUPI)アドレスを適用する方法を説明します。

プライベートで使用されるパブリック IP(PUPI)アドレスは、Google Cloud Virtual Private Cloud(VPC)ネットワーク内でプライベートに使用できるアドレスです。これらの IP アドレスは Google が所有しているものではありません。プライベートに使用するために、これらのパブリック IP アドレスを所有する必要はありません。

概要

GKE クラスタには、ノード、Pod、Service 専用の IP アドレス範囲が必要です。インフラストラクチャの規模が大きくなると、標準の内部 IP アドレス空間(RFC 1918)が不足する可能性があります。プライベート RFC 1918 アドレスの枯渇を軽減する方法の一つとして、GKE Pod CIDR ブロックにプライベートで使用されるパブリック IP(PUPI)アドレスを使用する方法があります。PUPI は、他のクラスタ コンポーネントにプライベート IP アドレスを予約することで、GKE Pod ネットワークの代替手段を提供します。

単一クラスタ: GKE クラスタを 1 つだけ作成する場合は、プライベートで使用される外部 IP アドレス範囲を有効にすることで PUPI を有効にできます。

複数のクラスタ: VPC ピアリングを介して接続された複数の GKE クラスタを使用している場合(サービス プロバイダの一般的なシナリオ)、より複雑な構成が必要になります。次の図は、企業(プロデューサー)が VPC ピアリングで PUPI を使用してお客様(コンシューマー)にマネージド サービスを提供する方法の例を示しています。

GKE Pod CIDR ブロックの PUPI アドレス。

上記の図では、次の点を考慮する必要があります。

  • プライマリ CIDR ブロック: ノードと内部ロードバランサ(ILB)に使用される非 PUPI CIDR ブロック。VPC 間で重複しないようにする必要があります。
  • プロデューサーのセカンダリ CIDR ブロック: Pod に使用される PUPI CIDR ブロック(例: 45.45.0.0/16)。
  • コンシューマーのセカンダリ CIDR ブロック: お客様側の他の PUPI CIDR ブロック(例: 5.5.0.0/16)。

サービス プロバイダのシナリオにおける PUPI の使用方法

サービス プロバイダ(プロデューサー)は、VPC(vpc-producer)内の GKE クラスタ(gke-2)でマネージド サービスを実行します。このクラスタは、Pod IP アドレスに PUPI 範囲 45.0.0.0/8 を使用します。

お客様(コンシューマー)は、独自の VPC(vpc-consumer)に GKE クラスタ(gke-1)を持ち、Pod の IP アドレスに別の PUPI 範囲 5.0.0.0/8 を使用しています。

これらの 2 つの VPC は VPC ピアリングを使用して接続されますが、ノード、サービス、内部ロードバランサには引き続き標準のプライベート IP アドレス(RFC 1918)が使用されます。

VPC 間の通信を確保する

  • コンシューマーからプロデューサー: デフォルトでは、コンシューマーの VPC は RFC 1918 ルート(PUPI は除く)をプロデューサーと自動的に共有します。これにより、コンシューマーの VPC 内のリソースは、プロデューサーの VPC のサービスにアクセスできます(通常は内部ロードバランサを経由します)。
  • プロデューサーからコンシューマー: プロデューサーの Pod がコンシューマーの VPC のリソースに到達するには、明示的な構成が必要です。
  • 重複なし: プロデューサーとコンシューマーは、コンシューマーの PUPI 範囲がプロデューサーの VPC で使用されている IP アドレスと競合しないようにする必要があります。
  • エクスポート / インポート: プロデューサーは PUPI ルートのエクスポートを有効にする必要があります。コンシューマーは、ピアリング接続を介してこれらのルートのインポートを有効にする必要があります。

PUPI 範囲が重複している場合に通信を有効にする

コンシューマーの VPC がプロデューサーと同じ PUPI 範囲を使用している場合、プロデューサー Pod からの直接通信はできません。代わりに、プロデューサーは IP アドレス マスカレードを有効にできます。これにより、Pod IP アドレスはプロデューサーのノード IP アドレスの背後で隠れて表示されなくなります。

次の表に、各 VPC のデフォルトのインポートとエクスポートの設定を示します。デフォルトの VPC ピアリングの設定は、gcloud compute networks peerings update コマンドを使用して変更できます。

VPC ネットワーク インポートの設定 エクスポートの設定
プロデューサー

デフォルトの動作(無効): パブリック IP アドレスを含むサブネット ルートはインポートされません。
有効にするには: --import-subnet-routes-with-public-ip を使用します(ピアリング経由)。

デフォルトの動作(有効): パブリック IP アドレスを含むサブネット ルートをエクスポートします。
無効にするには: --no-export-subnet-routes-with-public-ip を使用します(ピアリング経由)。

サービス ネットワーキングで制御されるフラグ。
コンシューマー 無効(デフォルト) 有効(デフォルト) 通常はお客様側で管理します。サービス ネットワーキングで変更する必要はありません。

これらの設定は次のようになります。

  • プロデューサー VPC は、お客様のすべてのルートを表示します。
  • コンシューマー VPC には、プロデューサー VPC の Pod サブネットで構成されている PUPI ルートは表示されません。
  • プロデューサー Pod から vpc-consumer ネットワークへのトラフィックは、プロデューサー クラスタ内のノードアドレスの背後で変換する必要があります。

前提条件

VPC Pod と別の VPC 間の通信を正常に確立するには、次の前提条件と構成を満たしている必要があります。

  • GKE クラスタは、次の最小バージョン要件を満たしている必要があります。
    • Autopilot クラスタ: GKE バージョン 1.22 以降
    • Standard クラスタ: GKE バージョン 1.14 以降。
  • パブリックにルーティングできないか、Google が所有していない PUPI 範囲を選択します。
  • 両方の VPC のノード IP アドレスとプライマリ IP アドレス範囲が重複しないようにします。
  • お客様の VPC とマネージド サービスの間で直接的な Pod 間通信が必要な場合は、次の操作を行います。
    • Autopilot クラスタ: Pod 間の通信を確保するために、PUPI の SNAT を構成します。追加の構成は必要ありません。
    • Standard クラスタ: SNAT を使用して、Pod の IP アドレスを対応するノードの IP アドレスに変換します。PUPI トラフィックに対して SNAT を有効にします。詳細については、プライベートで使用される外部 IP アドレス範囲を有効にするをご覧ください。

GKE クラスタにプライベートで使用されるパブリック IP アドレスを構成する

GKE クラスタの PUPI アドレスを構成するには:

  1. 2 つの Virtual Private Cloud ネットワークを構成します。
  2. 各 Virtual Private Cloud ネットワーク内にサブネットを 1 つ構成します。
  3. 各サブネットのセカンダリ アドレス範囲に PUPI アドレス範囲を構成します。
  4. 適切なインポートとエクスポートの設定を使用して、2 つの Virtual Private Cloud ネットワーク間の Virtual Private Cloud ピアリング関係を確立します。
  5. 各 Virtual Private Cloud 内のルートを検査します。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを算出できます。

始める前に

始める前に、次の作業が完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。
  • VPC ネイティブ クラスタのみを使用します。

  • VPC ピアリングに必要な IPAM 仕様を設定します。

ネットワークとクラスタを設定する

  1. VPC ネットワークを作成します。

    ノードのプライマリ範囲と Pod の PUPI 範囲として RFC-1918 を使用して、次の 2 つの VPC ネットワークを作成します。RFC 1918 プライベート アドレス空間(10.x.x.x172.16.x.x192.168.x.x など)のプライマリ IP アドレス範囲を両方の VPC に割り当てます。これらの範囲は通常、GKE クラスタ内のワーカーノードに使用されます。内部 IP アドレス範囲に加えて、VPC ごとにプライベートで使用されるパブリック IP アドレス(PUPI)の個別の範囲を指定します。これらの PUPI 範囲は、対応する GKE クラスタ内の Pod IP アドレスにのみ使用されます。

    • コンシューマーの VPC ネットワーク: この VPC は、コンシューマーのアプリケーションまたはワークロードが実行される 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
      
    • プロデューサーの VPC ネットワーク: この VPC は、コンシューマーが使用するサービスを提供する 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
      

    VPC ネットワークの作成の詳細については、VPC ネットワークを作成するをご覧ください。

  2. 前の手順で PUPI 範囲を使用して作成した VPC ネットワークとサブネットを使用して、2 つの GKE クラスタ(producerconsumer)を作成できます。

    1. 次のように、プロデューサー ネットワークとサブネットを使用して producer クラスタを作成します。

      gcloud container clusters create PRODUCER_CLUSTER_NAME \
          --enable-ip-alias \
          --network=NETWORK_NAME \
          --subnetwork=SUBNETWORK_NAME \
          --cluster-secondary-range-name=PRODUCER_PODS \
          --services-secondary-range-name=PRODUCER_SERVICES \
          --num-nodes=1 \
          --zone=PRODUCER_ZONE_NAME \
          --project=PRODUCER_PROJECT_NAME
      

      次のように置き換えます。

      • PRODUCER_CLUSTER_NAME: GKE プロデューサー クラスタの名前。
      • COMPUTE_LOCATION: クラスタの Compute Engine のロケーション
      • PRODUCER_SUBNET_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 など)です。これは、Service 用のサブネット セカンダリ IP アドレス範囲を作成するために使用されます。
      • セカンダリ範囲の割り当て方式がユーザーによって管理されている場合:
        • SECONDARY_RANGE_PODS: 指定された SUBNET_NAME 内の既存のセカンダリ IP アドレス範囲の名前。GKE は、クラスタの Pod にサブネット セカンダリ IP アドレス範囲全体を使用します。
        • SECONDARY_RANGE_SERVICES: 指定された既存のセカンダリ IP アドレス範囲の名前。
    2. 次のように、コンシューマー ネットワークとサブネットを使用して consumer クラスタを作成します。

      gcloud container clusters create CONSUMER_CLUSTER_NAME \
          --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 \
          --zone=CONSUMER_ZONE \
          --project=CONSUMER_PROJECT
      

      次のように置き換えます。

      • CONSUMER_CLUSTER_NAME: GKE コンシューマー クラスタの名前。
      • COMPUTE_LOCATION: クラスタの Compute Engine のロケーション
      • CONSUMER_SUBNET_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 など)です。これは、Service 用のサブネット セカンダリ IP アドレス範囲を作成するために使用されます。
      • セカンダリ範囲の割り当て方式がユーザーによって管理されている場合:
        • SECONDARY_RANGE_PODS: 指定された SUBNET_NAME 内の既存のセカンダリ IP アドレス範囲の名前。GKE は、クラスタの Pod にサブネット セカンダリ IP アドレス範囲全体を使用します。
        • SECONDARY_RANGE_SERVICES: 指定された既存のセカンダリ IP アドレス範囲の名前。

    クラスタの作成の詳細については、クラスタの作成をご覧ください。

  3. 次のように、コンシューマー VPC ネットワークとプロデューサー VPC ネットワークの間に VPC ピアリング関係を確立します。

    • consumer ネットワークをプロデューサーに接続するには、次のコマンドを実行します。

      gcloud compute networks peerings create PEERING_NAME \
          --project=consumer_project \
          --network=consumer \
          --peer-network=producer
      
    • producer ネットワークをコンシューマーに接続するには、次のコマンドを実行します。

      gcloud compute networks peerings create PEERING_NAME \
          --project=producer_project \
          --network=producer \
          --peer-network=consumer \
          --no-export-subnet-routes-with-public-ip \
          --import-subnet-routes-with-public-ip
      

    次のように置き換えます。

    • PEERING_NAME: GKE コンシューマー クラスタの名前。
    • CONSUMER_CLUSTER_NAME: GKE コンシューマー クラスタの名前。

    デフォルトでは、コンシューマー VPC は PUPI アドレスをエクスポートします。プロデューサー VPC を作成するときは、次の引数を使用して VPC を構成して PUPI アドレスをインポートしますが、エクスポートはしません。

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

ネットワークとサブネットワークを確認する

  1. プロデューサー ネットワークを確認します。

    gcloud compute networks describe producer \
        --project=producer_project
    

    出力は次のようになります。

    ...
    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-subnet \
        --project=producer_project\
        --region=producer_region
    

    出力は次のようになります。

    ...
    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 subnets describe consumer-subnet \
        --project=consumer_project \
        --region=consumer_region
    

    出力は次のようになります。

    ...
    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 describe consumer \
    --project=consumer_project
    

    出力は次のようになります。

    ...
    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 \
        --project=consumer_project \
        --zone=consumer_zone
    

    出力は次のようになります。

    ...
    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 Deployment を確認します。

    kubectl get deployment helloweb
    

    出力は次のようになります。

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

ソリューションの確認

  1. VPC ピアリングが正常に作成されたことを確認します。

    gcloud compute networks peerings list
    

    出力は次のようになります。コンシューマーとプロデューサーという名前のピアリングが表示されます。

    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. コンシューマー VPC が PUPI ルートをエクスポートしていることを確認します。

    gcloud compute networks peerings list-routes consumer-peer-producer \
        --direction=OUTGOING \
        --network=consumer \
        --region=<consumer_region>
    

    出力は次のようになります。3 つのコンシューマー 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-peer-consumer \
        --direction=INCOMING \
        --network=producer \
        --region=<producer_region>
    

    出力は次のようになります。3 つのコンシューマー 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>
    

次のステップ