VPC ネットワーク間に内部ロードバランサを作成する


このページでは、VPC ネットワーク間に Google Kubernetes Engine(GKE)で内部パススルー ネットワーク ロードバランサを作成する方法について説明します。このページを読む前に、次のコンセプトをよく理解しておく必要があります。

始める前に

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

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

Private Service Connect を使用して内部ロードバランサを作成する

サービス プロデューサーとしてサービス アタッチメントを使用すると、Private Service Connect を使用して、他の VPC ネットワークのサービス コンシューマーがサービスを利用できるようになります。ServiceAttachment カスタム リソースを使用して、サービス アタッチメントを作成、管理、削除できます。

要件と制限事項

  • Private Service Connect の制限事項が適用されます。
  • サービス アタッチメントは、GKE バージョン 1.21.4-gke.300 以降で作成できます。
  • 複数サービスのアタッチメント構成で同じサブネットを使用することができません。
  • 内部パススルー ネットワーク ロードバランサを使用する GKE サービスを作成する必要があります。
  • 1.22.4-gke.100 より前のバージョンの GKE では、別のプロジェクト(共有 VPC)のサブネットを指定することはできません。共有 VPC の場合は、共有 VPC の要件がすべて満たされていることを確認してください。

ServiceAttachment の作成

  1. サブネットを作成します。

    ServiceAttachment ごとに新しいサブネットを作成する必要があります。

    gcloud beta compute networks subnets create SUBNET_NAME \
        --project PROJECT_ID \
        --network NETWORK_NAME \
        --region REGION \
        --range SUBNET_RANGE \
        --purpose PRIVATE_SERVICE_CONNECT
    

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

    • SUBNET_NAME: 新しいサブネットの名前。1.22.4-gke.100 以降のバージョンの GKE では、このフィールドに完全修飾リソース URL を使用することで、別のプロジェクトのサブネットを指定できます。完全修飾されたリソース URL は、コマンド gcloud compute networks subnets describe を使用して取得できます。
    • PROJECT_ID: Google Cloud プロジェクトの ID。
    • NETWORK_NAME: サブネットの VPC ネットワークの名前。
    • REGION: 新しいサブネットのリージョン。作成するサービスと同じリージョンを使用する必要があります。
    • SUBNET_RANGE: サブネットに使用する IP アドレス範囲。
  2. ワークロードをデプロイします。

    以下のマニフェストは、サンプルのウェブ アプリケーション コンテナ イメージを実行する 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.2.19
            ports:
              - name: http
                containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 5
              timeoutSeconds: 1
    
  3. マニフェストをクラスタに適用します。

    kubectl apply -f my-deployment.yaml
    
  4. サービスを作成します。次のマニフェストは、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: 新しいサービスの名前。
  5. マニフェストをクラスタに適用します。

    kubectl apply -f my-service.yaml
    
  6. 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
     resourceRef:
       kind: Service
       name: SERVICE_NAME
    

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

    • SERVICE_ATTACHMENT_NAME: 新しいサービス アタッチメントの名前。
    • SUBNET_NAME: 新しいサブネットの名前。1.22.4-gke.100 以降のバージョンの GKE では、このフィールドに完全修飾リソース URL を使用することで、別のプロジェクトのサブネットを指定できます。完全修飾されたリソース URL は、コマンド gcloud compute networks subnets describe を使用して取得できます。共有 VPC 構成の場合は、projects/HOST_PROJECT_ID/regions/COMPUTE_REGION/subnetworks/SUBNET_NAME の形式を使用します。

    マニフェスト フィールドの詳細については、サービス アタッチメントのフィールドをご覧ください。

  7. マニフェストをクラスタに適用します。

    kubectl apply -f my-psc.yaml
    
  8. Private Service Connect コントローラがサービス アタッチメントを作成したことを確認します。

    gcloud beta 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

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

 kubectl describe serviceattachment foo-sa
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 を使用する

別のプロジェクトのサービスを使用するには、次の手順を行います。

  1. ServiceAttachment の URL を取得します。

    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
    
  2. ServiceAttachment の URL を使用して、Private Service Connect エンドポイントを作成します。

  3. コンシューマ プロジェクトの 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 を更新するには、次の手順を行います。

  1. my-psc.yamlServiceAttachment マニフェストを編集します。

    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
    
  2. マニフェストをクラスタに適用します。

    kubectl apply -f my-psc.yaml
    

ServiceAttachment の削除

サービス アタッチメントに接続されている内部パススルー ネットワーク ロードバランサは削除できません。サービス アタッチメントと GKE Service は個別に削除する必要があります。

  1. サービス アタッチメントを削除します。

    kubectl delete serviceattachment SERVICE_ATTACHMENT_NAME --wait=false
    

    このコマンドは、サービス アタッチメントに削除マークを付けますが、リソースは引き続き存在します。--wait フラグを省略して、削除の完了を待つこともできます。

  2. Service を削除します。

    kubectl delete svc SERVICE_NAME
    
  3. サブネットを削除します。

    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 になります。
  • consumerAllowList: ServiceAttachment への接続が許可されているコンシューマ プロジェクトのリスト。このフィールドは、connectionPreferenceACCEPT_MANUAL の場合にのみ使用できます。このフィールドの詳細については、Private Service Connect を使用してサービスを公開するをご覧ください。
    • project: コンシューマ プロジェクトのプロジェクト ID または番号。
    • connectionLimit: コンシューマ プロジェクトの接続の上限。このフィールドは省略可能です。
    • forceSendFields: API リクエストに含めるフィールド名。このフィールドは省略可能です。
    • nullFields: API リクエストに null 値で含めるフィールド名。このフィールドは省略可能です。
  • consumerRejectList: コンシューマ プロジェクトの ID または番号のリスト。ServiceAttachment への接続は許可されません。このフィールドは、connectionPreferenceACCEPT_MANUAL の場合にのみ使用できます。このフィールドの詳細については、Private Service Connect を使用してサービスを公開するをご覧ください。
  • resourceRef: Kubernetes リソースへの参照。

    • kind: Kubernetes リソースのタイプ。Service を使用する必要があります。
    • name: 内部パススルー ネットワーク ロードバランサと同じ名前空間に存在する必要がある Kubernetes リソースの名前。

トラブルシューティング

次のコマンドを使用すると、エラー メッセージを表示できます。

kubectl get events -n NAMESPACE

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.

次のステップ