スタンドアロン NEG によるコンテナ ネイティブのロード バランシング


このページでは、Google Kubernetes Engine(GKE)VPC ネイティブ クラスタで、ゾーン GCE_VM_IP_PORT ネットワーク エンドポイント グループ(NEG)に基づいて Kubernetes Service を作成する方法について説明します。

コンテナ ネイティブのロード バランシングのメリット、要件、制限事項については、コンテナ ネイティブのロード バランシングをご覧ください。

概要

NEG はエンドポイントのグループを表します。GKE は、GCE_VM_IP_PORT タイプのスタンドアロン NEG をサポートしています。GCE_VM_IP_PORT NEG は、VM のプライマリ内部 IP アドレスかエイリアス IP 範囲の IP アドレスのいずれかを使用するエンドポイントをサポートします。

スタンドアロン NEG を使用する GKE VPC ネイティブ クラスタのコンテキストでは、各エンドポイントが Pod の IP アドレスとターゲット ポートになります。Pod の IP アドレスは、Pod 用のノードのエイリアス IP 範囲から使用され、この範囲は Pod 用のサブネット セカンダリ IP アドレス範囲から取得されます。

GKE には、GCE_VM_IP_PORT NEG のメンバーシップを管理するための NEG コントローラが用意されています。GKE API の外部で構成するロードバランサのバックエンド サービスに、バックエンドとして作成した NEG を追加できます。

次の図は、Kubernetes API オブジェクトと Compute Engine オブジェクトの対応関係を示しています。

Kubernetes Services は Compute Engine ネットワーク エンドポイント グループに対応し、Kubernetes の Pod は Compute Engine ネットワーク エンドポイントに対応します。コントロール プレーンの NEG コントローラのコンポーネントが管理を行います。

Ingress と NEG

NEG を GKE Ingress と一緒に使用すると、Ingress コントローラでロードバランサの作成が容易になります。たとえば、仮想 IP アドレス、転送ルール、ヘルスチェック、ファイアウォール ルールなどを簡単に作成できます。

Ingress は、NEG の管理を簡素化する多くの機能を備えているため、コンテナネイティブのロード バランシングを使用する場合におすすめします。スタンドアロン NEG は、Ingress によって管理される NEG がユースケースに対応していない場合の選択肢の一つです。

スタンドアロン NEG

Ingress 以外でプロビジョニングされたロードバランサを使用してデプロイされた NEG は、スタンドアロン NEG とみなされます。スタンドアロン NEG は NEG コントローラを介してデプロイ、管理されますが、転送ルール、ヘルスチェック、その他のロード バランシング オブジェクトは手動でデプロイする必要があります。

スタンドアロン NEG は、Ingress 対応のコンテナネイティブ ロード バランシングと競合しません。

次の図は、各シナリオでロード バランシング オブジェクトがデプロイされる方法の違いを示しています。

スタンドアロン NEG と Ingress マネージド NEG では、GKE コントロール プレーンの NEG コントローラが NEG オブジェクトとネットワーク エンドポイント オブジェクトを管理します。前述のように、スタンドアロン NEG の場合、他のすべてのコンポーネントはユーザーが管理します。

NEG 漏洩の防止

スタンドアロン NEG では、NEG のライフサイクルと、ロードバランサを構成するリソースを管理する必要があります。次のように NEG が漏洩する可能性があります。

  • GKE サービスが削除されても、NEG がバックエンド サービスによって参照されている場合は、関連付けられている NEG のガベージ コレクションは行われません。バックエンド サービスから NEG の参照を解除して、NEG を削除できるようにします。
  • クラスタを削除しても、スタンドアロン NEG は削除されません。

スタンドアロン NEG のユースケース

スタンドアロン NEG にはいくつかの重要な用途があります。スタンドアロン NEG は柔軟性に優れています。Ingress(NEG を併用するかどうかにかかわらず)とは対照的です。Ingress では、独自の方法で選択されたロード バランシング オブジェクトの特定のセットを定義し、オブジェクトを簡単に使えるようにしています。

スタンドアロン NEG の使用例:

コンテナと VM の異種混合サービス

NEG には、VM アドレスとコンテナの両方の IP アドレスを含めることができます。これは、Kubernetes ワークロードと Kubernetes 以外のワークロードの両方を含むバックエンドを単一の仮想 IP アドレスで参照できることを意味します。既存のワークロードを GKE クラスタに移行する場合にも使用可能です。

スタンドアロン NEG には複数の VM IP を設定できるため、同じサービス VIP に対して VM とコンテナの両方を含むバックエンドを参照するようにロードバランサを手動で構成することが可能です。

カスタマイズした Ingress コントローラ

スタンドアロン NEG をターゲットにするロードバランサを構成するには、カスタマイズした Ingress コントローラを使用します(あるいは Ingress コントローラを使用しません)。

GKE で Traffic Director を使用する

GKE では Traffic Director を使用できます。Traffic Director はスタンドアロン NEG を使用して、マネージド サービス メッシュにコンテナ ネイティブのロード バランシングを提供します。

GKE で外部プロキシ ネットワーク ロードバランサを使用する

スタンドアロン NEG を使用すると、Kubernetes / GKE がネイティブでサポートしていない外部プロキシ ネットワーク ロードバランサでコンテナのロード バランシングを直接行うことができます。

Pod の readiness(準備完了)

readiness ゲートは、PodStatus へのフィードバックまたはシグナルの挿入を可能にする Kubernetes の拡張機能です。これにより、Pod の状態を準備完了に移行できます。NEG コントローラは、Compute Engine ロードバランサから Pod までの完全なネットワーク パスを確実に機能させるため、カスタム readiness ゲートを管理します。GKE での Pod の readiness ゲートについては、コンテナ ネイティブのロード バランシングをご覧ください。

Ingress と NEG を使用する場合は、ロードバランサの代わりに Compute Engine のヘルスチェックをデプロイして管理します。ただし、Compute Engine のヘルスチェックは個別にデプロイして管理する必要があるため、スタンドアロン NEG ではこの機能を想定していません。Compute Engine のヘルスチェックは、受信準備が整っていないバックエンドへのトラフィックの配信を防ぐため、ロードバランサと一緒に構成する必要があります。NEG に関連するヘルスチェック ステータスがない場合(通常はヘルスチェックが構成されていないため)、NEG で対応するエンドポイントのプログラムが作成されると、NEG コントローラは Pod の readiness ゲートの値を True に設定します。

要件

クラスタが VPC ネイティブである必要があります。詳細については、VPC ネイティブ クラスタの作成をご覧ください。

クラスタで HttpLoadBalancing アドオンが有効になっている必要があります。GKE クラスタでは、HttpLoadBalancing アドオンがデフォルトで有効になっています。

始める前に

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

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

スタンドアロン NEG を使用する

次の手順では、GKE で外部 HTTP ロードバランサとスタンドアロン NEG を使用する方法について説明します。

次のオブジェクトを作成する必要があります。

  • Pod を作成して管理する Deployment
  • NEG を作成する Service
  • Compute Engine API で作成されるロードバランサ。これは、Ingress で NEG を使用する場合とは異なります。Ingress はロードバランサを自動的に作成して構成します。一方、スタンドアロン NEG は、NEG とバックエンド サービスを手動で関連付けて、Pod をロードバランサに接続する必要があります。ロードバランサは、次の図に示す複数のコンポーネントで構成されています。

ロードバランサには、転送ルール、ターゲット HTTP プロキシ、URL マップ、ヘルスチェック、バックエンド サービスというコンポーネントがあります。これにより、Pod の IP アドレスを含む NEG にトラフィックが転送されます。

VPC ネイティブ クラスタを作成する

Autopilot クラスタはデフォルトで VPC ネイティブであるため、ワークロードをデプロイするまでスキップできます。

Standard クラスタの場合は、ゾーン us-central1-a に VPC ネイティブ クラスタを作成します。

gcloud container clusters create neg-demo-cluster \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a

Deployment を作成する

次のマニフェストの例では、コンテナ化された HTTP サーバーの 3 つのインスタンスを実行する Deployment を指定しています。HTTP サーバーは、アプリケーション サーバーのホスト名(サーバーが実行されている Pod の名前)でリクエストに応答します。

Pod の readiness フィードバックを使用するワークロードを使用することをおすすめします。

Pod の readiness フィードバックを使用する

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname
  

ハードコードされた遅延を使用する

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec:
  minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready
  replicas: 3
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname
  

このマニフェストを neg-demo-app.yaml として保存し、次のコマンドを実行して Deployment を作成します。

kubectl apply -f neg-demo-app.yaml

Service を作成する

次のマニフェストでは、Service を指定しています。

  • run: neg-demo-app というラベルが付いた Pod は、この Service のメンバーになります。
  • Service の 1 つの ServicePort フィールドにポート 80 が設定されています。
  • cloud.google.com/neg アノテーションは、ポート 80 が NEG に関連付けられることを示します。オプションの name フィールドは、NEG に NEG_NAME という名前を付けることを指定します。name フィールドを省略すると、一意の名前が自動生成されます。詳しくは、NEG に名前を付けるをご覧ください。
  • 各メンバー Pod には、TCP ポート 9376 でリッスンするコンテナが必要です。
apiVersion: v1
kind: Service
metadata:
  name: neg-demo-svc
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'
spec:
  type: ClusterIP
  selector:
    run: neg-demo-app # Selects Pods labelled run: neg-demo-app
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376

NEG_NAME は、NEG の名前に置き換えます。NEG 名は、リージョン内で一意である必要があります。

このマニフェストを neg-demo-svc.yaml として保存し、次のコマンドを実行して Service を作成します。

kubectl apply -f neg-demo-svc.yaml

NEG は、Service の作成から数分以内に作成されます。

Service タイプ

この例では ClusterIP サービスを使用していますが、5 つの Service タイプはすべてスタンドアロン NEG をサポートしています。デフォルトのタイプ ClusterIP をおすすめします。

NEG に名前を付ける

GKE バージョン 1.18.18-gke.1200 以降では、NEG にカスタム名を指定することも、GKE によって自動的に名前を生成することもできます。以前のバージョンの GKE では、自動生成された NEG 名のみがサポートされています。

GKE は、クラスタで使用されるゾーンごとに 1 つの NEG を作成します。NEG はすべて同じ名前を使用します。

名前の指定

カスタム NEG 名を指定すると、事前に NEG の名前とゾーンがわかっているため、ロードバランサの構成が簡単になります。カスタム NEG 名は次の要件を満たす必要があります。

  • ゾーンクラスタのクラスタの場合はゾーンで一意、リージョン クラスタの場合はリージョンで一意になっている必要があります。
  • GKE NEG コントローラ以外で作成された既存の NEG の名前と一致する必要があります。
  • アンダースコアを使用することはできません。

NEG 名を指定するには、Service の cloud.google.com/neg アノテーションで name フィールドを使用します。

cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'

NEG_NAME は、NEG の名前に置き換えます。NEG 名は、リージョン内で一意である必要があります。

自動生成された名前を使用する

自動生成された NEG 名は、一意になることが保証されています。自動生成された名前を使用する場合は、name フィールドを省略します。

cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'

自動生成された名前の形式は次のとおりです。

k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH

ポートを複数の NEG にマッピングする

Service は複数のポートをリッスンできます。定義上、NEG の IP アドレスとポートは 1 つだけです。つまり、複数のポートを持つ Service を指定すると、ポートごとに NEG が作成されます。

cloud.google.com/neg アノテーションの形式は次のとおりです。

cloud.google.com/neg: '{
   "exposed_ports":{
      "SERVICE_PORT_1":{},
      "SERVICE_PORT_2":{},
      "SERVICE_PORT_3":{},
      ...
   }
 }'

この例の SERVICE_PORT_N の各インスタンスは、Service の既存のサービスポートを参照する個別のポート番号です。それぞれのサービスポートに対して、NEG コントローラはクラスタのゾーンごとに 1 つの NEG を作成します。

NEG ステータスを取得する

次のコマンドを使用して、クラスタの Service のステータスを取得します。

kubectl get service neg-demo-svc -o yaml

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

cloud.google.com/neg-status: '{
   "network-endpoint-groups":{
      "SERVICE_PORT_1": "NEG_NAME_1",
      "SERVICE_PORT_2": "NEG_NAME_2",
      ...
   },
   "zones":["ZONE_1", "ZONE_2", ...]
}

この出力の network-endpoint-groups マッピングの各要素は、サービスポート(SERVICE_PORT_1 など)と対応するマネージド NEG の名前(NEG_NAME_1 など)です。zones リストには、NEG が存在するすべてのゾーン(ZONE_1 など)が含まれます。

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

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'
    cloud.google.com/neg-status: '{"network_endpoint_groups":{"80":"k8s1-cca197ad-default-neg-demo-app-80-4db81e02"},"zones":["ZONE_1", "ZONE_2"]}'
  labels:
    run: neg-demo-app
  name: neg-demo-app
  namespace: default
  selfLink: /api/v1/namespaces/default/services/neg-demo-app
  ...
spec:
  clusterIP: 10.0.14.252
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376
  selector:
    run: neg-demo-app
  sessionAffinity: None
status:
  loadBalancer: {}

この例のアノテーションは、サービスポート 80 が k8s1-cca197ad-default-neg-demo-app-80-4db81e02 という名前の NEG に公開されていることを示しています。

NEG の作成を検証する

NEG は、Service の作成から数分以内に作成されます。Service マニフェストで指定されたラベルと一致する Pod がある場合、NEG にその Pod の IP が含まれます。

NEG が作成され、正しく構成されていることを確認する方法は 2 つあります。GKE 1.18.6-gke.6400 以降では、カスタム リソース ServiceNetworkEndpointGroup が、Service コントローラによって作成された NEG のステータス情報を保存します。それより前のバージョンでは、NEG を直接調べる必要があります。

ServiceNetworkEndpointGroup リソース

ServiceNetworkEndpointGroup リソースをすべて取得して、クラスタ内の NEG を一覧表示します。

kubectl get svcneg

ServiceNetworkEndpointGroup リソースのステータスをチェックして、NEG のステータスを確認します。

kubectl get svcneg NEG_NAME -o yaml

NEG_NAME は、チェックする個々の NEG の名前に置き換えます。

このコマンドの出力に含まれるステータス セクションには、エラー メッセージが含まれている場合があります。エラーには、Service イベントとして報告されるものがあります。Service オブジェクトにクエリを実行すると、詳細を確認できます。

kubectl describe service SERVICE_NAME

SERVICE_NAME は、関連する Service の名前に置き換えます。

NEG コントローラが NEG を正常に同期していることを確認するには、ServiceNetworkEndpointGroup リソースのステータス フィールドを type:Synced の条件でチェックします。最新の同期時刻は、status.lastSyncTime フィールドに入っています。

ServiceNetworkEndpointGroup リソースは、GKE バージョン 1.18 以降にのみ存在します。

NEG を直接調べる

Google Cloud プロジェクトの NEG を一覧表示し、作成した Service に一致する NEG を確認して、NEG が存在することを確認します。NEG の名前の形式は次のとおりです。

k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH

次のコマンドを使用して、NEG を一覧表示します。

gcloud compute network-endpoint-groups list

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

NAME                                          LOCATION       ENDPOINT_TYPE   SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f  ZONE_NAME      GCE_VM_IP_PORT  3

この出力では、NEG の SIZE が 3 になっています。これは、Deployment の 3 つの Pod に対応する 3 つのエンドポイントがあることを意味します。

次のコマンドを使用して、個々のエンドポイントを特定します。

gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME

NEG_NAME は、個々のエンドポイントを表示する NEG の名前に置き換えます。

出力には、3 つのエンドポイントが表示されます。各エンドポイントには、Pod の IP アドレスとポートがあります。

INSTANCE                                           IP_ADDRESS  PORT
gke-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.43  9376
gke-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.44  9376
gke-cluster-3-default-pool-4cc71a15-w9nk  10.12.2.26  9376

外部アプリケーション ロードバランサをスタンドアロン NEG に接続する

Compute Engine API を使用して、NEG を外部アプリケーション ロードバランサのバックエンドとして使用できます。

  1. ファイアウォール ルールの作成ヘルスチェックを実行するために、ロードバランサはクラスタ エンドポイントにアクセスする必要があります。このコマンドは、アクセスを許可するファイアウォール ルールを作成します。

    gcloud compute firewall-rules create fw-allow-health-check-and-proxy \
       --network=NETWORK_NAME \
       --action=allow \
       --direction=ingress \
       --target-tags=GKE_NODE_NETWORK_TAGS \
       --source-ranges=130.211.0.0/22,35.191.0.0/16 \
       --rules=tcp:9376
    

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

    • NETWORK_NAME: クラスタが実行されるネットワーク。
    • GKE_NODE_NETWORK_TAGS: GKE ノードのネットワーク タグ

    ノードにカスタム ネットワーク タグを作成していない場合は、GKE がタグを自動的に生成します。生成されたタグを検索するには、次のコマンドを実行します。

    gcloud compute instances describe INSTANCE_NAME
    

    INSTANCE_NAME は、GKE ノードを実行するホスト Compute Engine VM インスタンスの名前に置き換えます。たとえば、前のセクションの出力には、GKE ノードの INSTANCE 列にインスタンス名が表示されます。 Standard クラスタの場合は、gcloud compute instances list を実行して、プロジェクト内のすべてのインスタンスを一覧表示することもできます。

  2. ロードバランサのグローバル仮想 IP アドレスを作成します。

    gcloud compute addresses create hostname-server-vip \
        --ip-version=IPV4 \
        --global
    
  3. ヘルスチェックを作成します。これは、NEG 内の個々のエンドポイントの liveness を検出するためにロードバランサが使用します。

    gcloud compute health-checks create http http-basic-check \
        --use-serving-port
    
  4. これがグローバル外部アプリケーション ロードバランサであることを指定するバックエンド サービスを作成します。

    gcloud compute backend-services create my-bes \
        --protocol HTTP \
        --health-checks http-basic-check \
        --global
    
  5. ロードバランサの URL マップターゲット プロキシを作成します。この例では、serve_hostname アプリのエンドポイントが 1 つだけで、URL を使用しないため、非常にシンプルになっています。

    gcloud compute url-maps create web-map \
        --default-service my-bes
    
    gcloud compute target-http-proxies create http-lb-proxy \
        --url-map web-map
    
  6. 転送ルールを作成します。これにより、ロードバランサが作成されます。

    gcloud compute forwarding-rules create http-forwarding-rule \
        --address=HOSTNAME_SERVER_VIP \
        --global \
        --target-http-proxy=http-lb-proxy \
        --ports=80
    

    HOSTNAME_SERVER_VIP は、ロードバランサに使用する IP アドレスに置き換えます。--address を省略すると、GKE によって自動的にエフェメラル IP アドレスが割り当てられます。 新しい静的外部 IP アドレスを予約することもできます。

チェックポイント

これまでに作成したリソースは次のとおりです。

  • 外部仮想 IP アドレス
  • 転送ルール
  • ファイアウォール ルール
  • ターゲット HTTP プロキシ
  • Compute Engine ヘルスチェックの URL マップ
  • バックエンド サービス
  • Compute Engine ヘルスチェック

次の図に、これらのリソースの関係を示します。

画像

これらのリソースはロードバランサです。次のステップでは、ロードバランサにバックエンドを追加します。

ここで説明するスタンドアロン NEG の利点の 1 つは、ロードバランサとバックエンドのライフサイクルを完全に独立させることができることです。アプリケーション、サービス、GKE クラスタが削除された後でも、ロードバランサは継続して実行できます。フロントエンドのロードバランサ オブジェクトを変更せずに、ロードバランサから新しい NEG または複数の NEG をロードバランサに追加および削除できます。

ロードバランサにバックエンドを追加する

NEG とロードバランサを接続するには、gcloud compute backend-services add-backend を使用して my-bes バックエンド サービスのバックエンドとして追加します。

gcloud compute backend-services add-backend my-bes \
    --global \
    --network-endpoint-group=NEG_NAME \
    --network-endpoint-group-zone=NEG_ZONE \
    --balancing-mode RATE --max-rate-per-endpoint 5

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

  • NEG_NAME: ネットワーク エンドポイント グループの名前。この名前は、NEG の作成時に指定した名前か、自動生成された名前のいずれかです。NEG の名前を指定しなかった場合は、次の手順を行い、自動生成された名前を確認してください。
  • NEG_ZONE: ネットワーク エンドポイント グループが存在するゾーン。この値を確認するには、次の手順を行います。

次のコマンドを使用して、NEG の名前とロケーションを取得します。

gcloud compute network-endpoint-groups list

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

NAME                                          LOCATION       ENDPOINT_TYPE   SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f  ZONE_NAME      GCE_VM_IP_PORT  3

この出力例では、NEG の名前は k8s1-70aa83a6-default-my-service-80-c9710a6f です。

同じバックエンド サービスに複数の NEG を追加できます。my-bes などのグローバル バックエンド サービスの場合、複数のリージョンに NEG バックエンドを配置できますが、リージョン バックエンド サービスの場合は 1 つのリージョンにのみバックエンドを配置します。

ロードバランサが機能することを確認する

設定したロードバランサが動作していることを確認するには、次の 2 つの方法があります。

  • ヘルスチェックが正しく構成され、正常に報告されていることを確認します。
  • アプリケーションにアクセスしてレスポンスを確認します。

ヘルスチェックを確認する

バックエンド サービスがヘルスチェックとネットワーク エンドポイント グループに関連付けられていることを確認し、個々のエンドポイントが正常な状態であることを確認します。

次のコマンドを使用して、バックエンド サービスがヘルスチェックとネットワーク エンドポイント グループに関連付けられていることを確認します。

gcloud compute backend-services describe my-bes --global

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

backends:
- balancingMode: RATE
  capacityScaler: 1.0
  group: ... /networkEndpointGroups/k8s1-70aa83a6-default-my-service-80-c9710a6f
...
healthChecks:
- ... /healthChecks/http-basic-check
...
name: my-bes
...

次に、個々のエンドポイントの状態を確認します。

gcloud compute backend-services get-health my-bes --global

出力の status: セクションは次のようになります。

status:
  healthStatus:
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.43
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.44
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-cluster-3-default-pool-4cc71a15-w9nk
    ipAddress: 10.12.2.26
    port: 50000

アプリケーションへのアクセス

ロードバランサの IP アドレスを使用してアプリケーションにアクセスし、すべてが機能していることを確認します。

まず、ロードバランサの仮想 IP アドレスを取得します。

gcloud compute addresses describe hostname-server-vip --global | grep "address:"

出力に IP アドレスが含まれます。次に、その IP アドレス(この例では 34.98.102.37)にリクエストを送信します。

curl 34.98.102.37

serve_hostname アプリからのレスポンスは neg-demo-app になります。

内部アプリケーション ロードバランサをスタンドアロン NEG に接続する

NEG を使用して、スタンドアロン GKE Pod で実行されるサービスの内部アプリケーション ロードバランサを構成できます。

プロキシ専用サブネットの構成

プロキシ専用サブネットは、ロードバランサのリージョン内のすべてのリージョン内部アプリケーション ロードバランサ用です。

コンソール

Google Cloud コンソールを使用している場合は、しばらく待ってから、プロキシ専用サブネットを作成できます。

gcloud

gcloud compute networks subnets create コマンドを使用して、プロキシ専用サブネットを作成します。

gcloud compute networks subnets create proxy-only-subnet \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=COMPUTE_REGION \
    --network=lb-network \
    --range=10.129.0.0/23

COMPUTE_REGION は、サブネットの Compute Engine に置き換えます。

API

subnetworks.insert メソッドを使用して、プロキシ専用サブネットを作成します。

POST https://compute.googleapis.com/compute/projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks
{
  "name": "proxy-only-subnet",
  "ipCidrRange": "10.129.0.0/23",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "region": "projects/PROJECT_ID/regions/COMPUTE_REGION",
  "purpose": "REGIONAL_MANAGED_PROXY",
  "role": "ACTIVE"
}

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

  • PROJECT_ID: プロジェクト ID。
  • COMPUTE_REGION: サブネットの Compute Engine

ファイアウォール ルールの構成

この例では、次のファイアウォール ルールを使用します。

  • fw-allow-ssh: ロードバランスされたインスタンスに適用される上り(内向き)ルール。任意のアドレスから TCP ポート 22 への SSH 接続が許可されます。このルールには、送信元の IP 範囲をより限定的に指定できます。たとえば、SSH セッションを開始するシステムの IP 範囲のみを指定できます。この例では、ターゲットタグ allow-ssh を使用して、ファイアウォール ルールが適用される VM が識別されます。

  • fw-allow-health-check: ロードバランスされたインスタンスに適用される上り(内向き)ルール。Google Cloud ヘルスチェック システム(130.211.0.0/2235.191.0.0/16)からのすべての TCP トラフィックが許可されます。この例では、ターゲットタグ load-balanced-backend を使用して、適用するインスタンスを識別します。

  • fw-allow-proxies: ロードバランスされたインスタンスに適用される上り(内向き)ルール。内部 HTTP(S) ロードバランサが管理するプロキシからポート 9376 への TCP トラフィックを許可します。この例では、ターゲットタグ load-balanced-backend を使用して、適用するインスタンスを識別します。

これらのファイアウォール ルールがない場合は、デフォルトの上り(内向き)拒否ルールによってバックエンド インスタンスへの受信トラフィックがブロックされます。

コンソール

  1. Google Cloud コンソールの [ファイアウォール ポリシー] ページに移動します。

    [ファイアウォール ポリシー] に移動

  2. [ファイアウォール ルールを作成] をクリックして、SSH 接続の受信を許可するルールを作成します。

    • 名前: fw-allow-ssh
    • ネットワーク: lb-network
    • トラフィックの方向: 上り(内向き)
    • 一致したときのアクション: 許可
    • ターゲット: 指定されたターゲットタグ
    • ターゲットタグ: allow-ssh
    • ソースフィルタ: IPv4 ranges
    • 送信元 IPv4 範囲: 0.0.0.0/0
    • プロトコルとポート:
      • 指定したプロトコルとポートを選択します。
      • tcp チェックボックスをオンにして、ポート 22 を指定します。
  3. [作成] をクリックします。

  4. もう一度 [ファイアウォール ルールを作成] をクリックして、Google Cloud ヘルスチェックを許可するルールを作成します。

    • 名前: fw-allow-health-check
    • ネットワーク: lb-network
    • トラフィックの方向: 上り(内向き)
    • 一致したときのアクション: 許可
    • ターゲット: 指定されたターゲットタグ
    • ターゲットタグ: load-balanced-backend
    • ソースフィルタ: IPv4 ranges
    • 送信元 IPv4 範囲: 130.211.0.0/2235.191.0.0/16
    • プロトコルとポート:
      • 指定したプロトコルとポートを選択します。
      • tcp チェックボックスをオンにして、ポート 80 を指定します。このルールは、ヘルスチェックに使用されているプロトコルとポートのみに制限することをおすすめします。プロトコルとポートに tcp:80 を使用すると、Google Cloud はポート 80 で HTTP を使用して VM に接続できますが、ポート 443 で HTTPS を使用して VM に接続することはできません。
  5. [作成] をクリックします。

  6. もう一度 [ファイアウォール ルールを作成] をクリックして、ロードバランサのプロキシ サーバーがバックエンドに接続できるようにするルールを作成します。

    • 名前: fw-allow-proxies
    • ネットワーク: lb-network
    • トラフィックの方向: 上り(内向き)
    • 一致したときのアクション: 許可
    • ターゲット: 指定されたターゲットタグ
    • ターゲットタグ: load-balanced-backend
    • ソースフィルタ: IPv4 ranges
    • 送信元 IPv4 範囲: 10.129.0.0/23
    • プロトコルとポート:
      • 指定したプロトコルとポートを選択します。
      • tcp チェックボックスをオンにして、ポート 9376 を指定します。
  7. [作成] をクリックします。

gcloud

  1. ネットワーク タグ allow-ssh を使用して、VM との SSH 接続を許可する fw-allow-ssh ファイアウォール ルールを作成します。source-ranges を省略すると、Google Cloud は任意の送信元としてルールを解釈します。

    gcloud compute firewall-rules create fw-allow-ssh \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --target-tags=allow-ssh \
        --rules=tcp:22
    
  2. Google Cloud ヘルスチェックを許可する fw-allow-health-check ルールを作成します。この例では、ヘルスチェック プローブからのすべての TCP トラフィックを許可します。ただし、必要に応じてポートの範囲を狭く構成することもできます。

    gcloud compute firewall-rules create fw-allow-health-check \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --target-tags=load-balanced-backend \
        --rules=tcp
    
  3. 内部 HTTP(S) ロードバランサのプロキシにバックエンドへの接続を許可する fw-allow-proxies ルールを作成します。

    gcloud compute firewall-rules create fw-allow-proxies \
        --network=lb-network \
        --action=allow \
        --direction=ingress \
        --source-ranges=10.129.0.0/23 \
        --target-tags=load-balanced-backend \
        --rules=tcp:9376
    

API

firewalls.insert メソッドに POST リクエストを送信して、fw-allow-ssh ファイアウォール ルールを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-ssh",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "0.0.0.0/0"
  ],
  "targetTags": [
    "allow-ssh"
  ],
  "allowed": [
   {
     "IPProtocol": "tcp",
     "ports": [
       "22"
     ]
   }
  ],
 "direction": "INGRESS"
}

PROJECT_ID を実際のプロジェクト ID に置き換えます。

firewalls.insertメソッドに POST リクエストを送信して、fw-allow-health-check ファイアウォール ルールを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-health-check",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "130.211.0.0/22",
    "35.191.0.0/16"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp"
    }
  ],
  "direction": "INGRESS"
}

firewalls.insert メソッドを使用して、プロキシ サブネット内の TCP トラフィックを許可する fw-allow-proxies ファイアウォール ルールを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "fw-allow-proxies",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "sourceRanges": [
    "10.129.0.0/23"
  ],
  "targetTags": [
    "load-balanced-backend"
  ],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "9376"
      ]
    }
  ],
  "direction": "INGRESS"
}

PROJECT_ID を実際のプロジェクト ID に置き換えます。

ロードバランサを構成する

転送ルールの IP アドレスには、バックエンド サブネットを使用します。プロキシ専用サブネットを使用すると、転送ルールの作成に失敗します。

コンソール

ロードバランサ タイプの選択

  1. Google Cloud コンソールで [ロードバランサの作成] ページに移動します。[ロードバランサの作成] に移動
  2. [HTTP(S) ロード バランシング] で [構成を開始] をクリックします。
  3. [VM 間のみ] を選択します。この設定は、ロードバランサが内部であることを意味します。
  4. [続行] をクリックします。

ロードバランサを準備する

  1. ロードバランサの [名前] に「l7-ilb-gke-map」と入力します。
  2. [リージョン] で、サブネットを作成したリージョンを選択します。
  3. [ネットワーク] で lb-network を選択します。

プロキシ専用サブネットの予約

プロキシ専用サブネットを予約します。

  1. [サブネットの予約] をクリックします。
  2. [名前] に「proxy-only-subnet」と入力します。
  3. [IP アドレス範囲] に「10.129.0.0/23」と入力します。
  4. [追加] をクリックします。

バックエンド サービスの構成

  1. [バックエンドの設定] をクリックします。
  2. [バックエンド サービスの作成または選択] メニューから [バックエンド サービスを作成] を選択します。
  3. バックエンド サービスの [名前] を l7-ilb-gke-backend-service に設定します。
  4. [バックエンド タイプ] で [ネットワーク エンドポイント グループ] を選択します。
  5. [バックエンド] の [新しいバックエンド] カードで次の手順を行います。
    1. GKE によって作成された NEG にネットワーク エンドポイント グループを設定します。NEG 名を取得するには、NEG の作成を検証するをご覧ください。
    2. [最大 RPS] で、エンドポイントあたりの 5 RPS の最大レートを指定します。Google Cloud では、必要に応じて最大レートを超える場合があります。
    3. [完了] をクリックします。
  6. [ヘルスチェック] プルダウン リストから [ヘルスチェックの作成] を選択し、次のパラメータを指定します。
    1. 名前: l7-ilb-gke-basic-check
    2. プロトコル: HTTP
    3. ポートの指定: サービスポート
    4. [保存して次へ] をクリックします。
  7. [作成] をクリックします。

URL マップの構成

  1. [ルーティング ルール] をクリックします。l7-ilb-gke-backend-service が、ホストとパスが一致しなかった場合に使用される唯一のバックエンド サービスであることを確認します。

フロントエンドを構成する

[フロントエンドの構成] をクリックして、次の操作を行います。

HTTP の場合:

  1. [フロントエンドの構成] をクリックします。
  2. [フロントエンド IP とポートの追加] をクリックします。
  3. [名前] を l7-ilb-gke-forwarding-rule に設定します。
  4. [プロトコル] を HTTP に設定します。
  5. [サブネットワーク] を backend-subnet に設定します。
  6. [内部 IP] で [静的内部 IP アドレスの予約] を選択します。
  7. 表示されるパネルで、次の情報を入力します。
    1. 名前: l7-ilb-gke-ip
    2. [静的 IP アドレス] セクションで、[ユーザー選択] を選択します。
    3. [カスタム IP アドレス] セクションに「10.1.2.199」と入力します。
    4. [予約] をクリックします。
  8. [ポート] を 80 に設定します。
  9. [完了] をクリックします。

HTTPS の場合:

クライアントとロードバランサ間で HTTPS を使用する場合は、プロキシを構成するために 1 つ以上の SSL 証明書リソースが必要になります。SSL 証明書リソースの作成方法については、SSL 証明書をご覧ください。内部 HTTP(S) ロードバランサでは Google マネージド証明書がサポートされません。

  1. [フロントエンドの構成] をクリックします。
  2. [フロントエンド IP とポートの追加] をクリックします。
  3. [名前] フィールドに「l7-ilb-gke-forwarding-rule」と入力します。
  4. [プロトコル] フィールドで HTTPS (includes HTTP/2) を選択します。
  5. [サブネット] を backend-subnet に設定します。
  6. [内部 IP] で [静的内部 IP アドレスの予約] を選択します。
  7. 表示されるパネルで、次の情報を入力します。
    1. 名前: l7-ilb-gke-ip
    2. [静的 IP アドレス] セクションで、[ユーザー選択] を選択します。
    3. [カスタム IP アドレス] セクションに「10.1.2.199」と入力します。
    4. [予約] をクリックします。
  8. HTTPS トラフィックを許可するように、ポート443 に設定されていることを確認します。
  9. [証明書] プルダウン リストをクリックします。
    1. プライマリ SSL 証明書として使用しようとしているセルフマネージド SSL 証明書リソースがすでにある場合は、プルダウン メニューから選択します。
    2. そうでない場合は、[新しい証明書を作成] を選択します。
      1. [名前] に「l7-ilb-cert」と入力します。
      2. 該当するフィールドに PEM 形式のファイルをアップロードします。
        • 公開鍵証明書
        • 証明書チェーン
        • 秘密鍵
      3. [作成] をクリックします。
  10. プライマリ SSL 証明書リソースに加えて証明書リソースを追加するには、次の手順に沿って操作します。
    1. [証明書を追加] をクリックします。
    2. [証明書] リストから証明書を選択するか、[新しい証明書の作成] をクリックし、上記の操作を行います。
  11. [完了] をクリックします。

構成の完了

[作成] をクリックします。

gcloud

  1. gcloud compute health-checks create http コマンドを使用して、HTTP ヘルスチェックを定義します。

    gcloud compute health-checks create http l7-ilb-gke-basic-check \
        --region=COMPUTE_REGION \
        --use-serving-port
    
  2. gcloud compute backend-services create コマンドを使用して、バックエンド サービスを定義します。

    gcloud compute backend-services create l7-ilb-gke-backend-service \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --protocol=HTTP \
        --health-checks=l7-ilb-gke-basic-check \
        --health-checks-region=COMPUTE_REGION \
        --region=COMPUTE_REGION
    
  3. DEPLOYMENT_NAME 変数を設定します。

    export DEPLOYMENT_NAME=NEG_NAME
    

    NEG_NAME は、サービスの名前に置き換えます。

  4. gcloud compute backend-services add-backend コマンドを使用して、NEG バックエンド サービスにバックエンドを追加します。

    gcloud compute backend-services add-backend l7-ilb-gke-backend-service \
        --network-endpoint-group=$DEPLOYMENT_NAME \
        --network-endpoint-group-zone=COMPUTE_ZONE-b \
        --region=COMPUTE_REGION \
        --balancing-mode=RATE \
        --max-rate-per-endpoint=5
    
  5. gcloud compute url-maps create コマンドを使用して、URL マップを作成します。

    gcloud compute url-maps create l7-ilb-gke-map \
        --default-service=l7-ilb-gke-backend-service \
        --region=COMPUTE_REGION
    
  6. ターゲット プロキシを作成します。

    HTTP の場合:

    gcloud compute target-http-proxies create コマンドを使用します。

    gcloud compute target-http-proxies create l7-ilb-gke-proxy \
        --url-map=l7-ilb-gke-map \
        --url-map-region=COMPUTE_REGION \
        --region=COMPUTE_REGION
    

    HTTPS の場合:

    SSL 証明書リソースの作成方法については、SSL 証明書をご覧ください。内部 HTTP(S) ロードバランサでは Google マネージド証明書がサポートされません。

    ファイルパスを変数名に割り当てます。

    export LB_CERT=PATH_TO_PEM_FORMATTED_FILE
    
    export LB_PRIVATE_KEY=PATH_TO_PEM_FORMATTED_FILE
    

    gcloud compute ssl-certificates create コマンドを使用して、リージョン SSL 証明書を作成します。

    gcloud compute ssl-certificates create

    gcloud compute ssl-certificates create l7-ilb-cert \
        --certificate=$LB_CERT \
        --private-key=$LB_PRIVATE_KEY \
        --region=COMPUTE_REGION
    

    リージョン SSL 証明書を使用して、gcloud compute target-https-proxies create コマンドを実行してターゲット プロキシを作成します。

    gcloud compute target-https-proxies create l7-ilb-gke-proxy \
        --url-map=l7-ilb-gke-map \
        --region=COMPUTE_REGION \
        --ssl-certificates=l7-ilb-cert
    
  7. 転送ルールを作成します。

    カスタム ネットワークでは、転送ルールでサブネットを参照する必要があります。このサブネットは、VM サブネットでありプロキシ専用サブネットではありません。

    HTTP の場合:

    適切なフラグを設定して、gcloud compute forwarding-rules create コマンドを実行します。

    gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --network=lb-network \
        --subnet=backend-subnet \
        --address=10.1.2.199 \
        --ports=80 \
        --region=COMPUTE_REGION \
        --target-http-proxy=l7-ilb-gke-proxy \
        --target-http-proxy-region=COMPUTE_REGION
    

    HTTPS の場合:

    適切なフラグを設定して、gcloud compute forwarding-rules create コマンドを実行します。

    gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \
        --load-balancing-scheme=INTERNAL_MANAGED \
        --network=lb-network \
        --subnet=backend-subnet \
        --address=10.1.2.199 \
        --ports=443 \
        --region=COMPUTE_REGION \
        --target-https-proxy=l7-ilb-gke-proxy \
        --target-https-proxy-region=COMPUTE_REGION
    

API

regionHealthChecks.insert メソッドに POST リクエストを送信してヘルスチェックを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks
{
   "name": "l7-ilb-gke-basic-check",
   "type": "HTTP",
   "httpHealthCheck": {
     "portSpecification": "USE_SERVING_PORT"
   }
}

PROJECT_ID は、プロジェクト ID で置き換えます。

regionBackendServices.insert メソッドに POST リクエストを送信してリージョン バックエンド サービスを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices
{
  "name": "l7-ilb-gke-backend-service",
  "backends": [
    {
      "group": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/networkEndpointGroups/NEG_NAME",
      "balancingMode": "RATE",
      "maxRatePerEndpoint": 5
    }
  ],
  "healthChecks": [
    "projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks/l7-ilb-gke-basic-check"
  ],
  "loadBalancingScheme": "INTERNAL_MANAGED"
}

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

  • PROJECT_ID: プロジェクト ID。
  • NEG_NAME: NEG の名前。

regionUrlMaps.insert メソッドに POST リクエストを送信して URL マップを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/urlMaps
{
  "name": "l7-ilb-gke-map",
  "defaultService": "projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices/l7-ilb-gke-backend-service"
}

PROJECT_ID は、プロジェクト ID で置き換えます。

regionTargetHttpProxies.insert メソッドに POST リクエストを送信して、ターゲット HTTP プロキシを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxy
{
  "name": "l7-ilb-gke-proxy",
  "urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-gke-map",
  "region": "COMPUTE_REGION"
}

PROJECT_ID は、プロジェクト ID で置き換えます。

forwardingRules.insert メソッドに POST リクエストを送信して転送ルールを作成します。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/forwardingRules
{
  "name": "l7-ilb-gke-forwarding-rule",
  "IPAddress": "10.1.2.199",
  "IPProtocol": "TCP",
  "portRange": "80-80",
  "target": "projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxies/l7-ilb-gke-proxy",
  "loadBalancingScheme": "INTERNAL_MANAGED",
  "subnetwork": "projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks/backend-subnet",
  "network": "projects/PROJECT_ID/global/networks/lb-network",
  "networkTier": "PREMIUM",
}

PROJECT_ID は、プロジェクト ID で置き換えます。

テスト

ゾーンに VM インスタンスを作成して接続をテストします。

gcloud compute instances create l7-ilb-client \
    --image-family=debian-9 \
    --image-project=debian-cloud \
    --zone=COMPUTE_ZONE \
    --network=lb-network \
    --subnet=backend-subnet \
    --tags=l7-ilb-client,allow-ssh

クライアント インスタンスにログインして、内部アプリケーション ロードバランサの転送ルールの IP アドレスを介使用してバックエンドの HTTP(S) サービスに到達可能であること、NEG のエンドポイント間でトラフィックのロード バランシングが行われていることを確認します。

SSH を使用して各クライアント インスタンスに接続します。

gcloud compute ssh l7-ilb-client \
    --zone=COMPUTE_ZONE-b

IP がホスト名を提供していることを確認します。

curl 10.1.2.199

HTTPS テストの場合は、次のコマンドを実行します。

curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.199:443

-k フラグを指定すると、curl は証明書の検証をスキップします。

100 個のリクエストを実行しロードバランスされていることを確認します。

HTTP の場合:

{
RESULTS=
for i in {1..100}
do
    RESULTS="$RESULTS:$(curl --silent 10.1.2.199)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
echo "***"
echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
echo
}

HTTPS の場合:

{
RESULTS=
for i in {1..100}
do
    RESULTS="$RESULTS:$(curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.199:443
)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
echo "***"
echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
echo
}

異種混合サービスを実装する(VM とコンテナ)

ロードバランサは、Kubernetes ワークロードと Kubernetes 以外のワークロードのフロントエンドとして機能します。たとえば、VM からコンテナへの移行や、共有ロードバランサを使用する永続的なアーキテクチャの一部として利用されます。これは、スタンドアロン NEG を含むさまざまなバックエンドを対象とするロードバランサを作成することで実現できます。

同じバックエンド サービス内の VM とコンテナ

この例では、ワークロードを実行している既存の VM を参照する NEG を作成し、この NEG を既存の backendService の別のバックエンドとして追加します。これにより、VM と GKE コンテナの間で単一のロードバランサが作成されます。

この例では、外部の HTTP ロードバランサを使用する上記の例を拡張します。

すべてのエンドポイントが同じ backendService でグループ化されるため、VM とコンテナのエンドポイントは同じサービスとみなされます。つまり、ホストまたはパスのマッチングでは、URL マップのルールに基づいてすべてのバックエンドが同じように扱われます。

ここで説明するアーキテクチャを示す図。前に作成したロードバランサは、2 つの NEG(以前に作成したコンテナの NEG と VM の IP アドレスを含む新しい NEG)を参照します。

NEG をバックエンド サービスのバックエンドとして使用する場合、そのバックエンド サービスのその他のすべてのバックエンドも NEG でなければなりません。インスタンス グループと NEG を同じバックエンド サービスのバックエンドとして使用することはできません。また、コンテナと VM は同じ NEG 内にエンドポイントとして共存できないため、常に別々の NEG で構成する必要があります。

  1. 次のコマンドで VM を Compute Engine にデプロイします。

    gcloud compute instances create vm1 \
        --zone=COMPUTE_ZONE \
        --network=NETWORK \
        --subnet=SUBNET \
        --image-project=cos-cloud \
        --image-family=cos-stable --tags=vm-neg-tag
    

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

    • COMPUTE_ZONE: ゾーンの名前。
    • NETWORK: ネットワークの名前。
    • SUBNET: ネットワークに関連付けられたサブネットの名前。
  2. アプリケーションを VM にデプロイします。

    gcloud compute ssh vm1 \
        --zone=COMPUTE_ZONE \
        --command="docker run -d --rm --network=host registry.k8s.io/serve_hostname:v1.4 && sudo iptables -P INPUT ACCEPT"
    

    このコマンドは、前の例で使用したサンプル アプリケーションを VM にデプロイします。説明をわかりやすくするため、アプリケーションを Docker コンテナとして実行していますが、これは必須ではありません。実行中のコンテナへのファイアウォール アクセスを許可する場合は、iptables コマンドが必要です。

  3. アプリケーションがポート 9376 で動作し、vm1 での実行を報告していることを確認します。

    gcloud compute ssh vm1 \
        --zone=COMPUTE_ZONE \
        --command="curl -s localhost:9376"
    

    サーバーが vm1 を返すはずです。

  4. VM エンドポイントで使用する NEG を作成します。コンテナと VM の両方を NEG エンドポイントにできますが、1 つの NEG に VM エンドポイントとコンテナ エンドポイントの両方を設定することはできません。

    gcloud compute network-endpoint-groups create vm-neg \
        --subnet=SUBNET \
        --zone=COMPUTE_ZONE
    
  5. VM エンドポイントを NEG に接続します。

    gcloud compute network-endpoint-groups update vm-neg \
        --zone=COMPUTE_ZONE \
        --add-endpoint="instance=vm1,ip=VM_PRIMARY_IP,port=9376"
    

    VM_PRIMARY_IP は、VM のプライマリ IP アドレスに置き換えます。

  6. NEG に VM エンドポイントがあることを確認します。

    gcloud compute network-endpoint-groups list-network-endpoints vm-neg \
        --zone COMPUTE_ZONE
    
  7. コンテナ バックエンドの追加に使用したコマンドを使用して、NEG をバックエンド サービスに接続します。

    gcloud compute backend-services add-backend my-bes
        --global \
        --network-endpoint-group vm-neg \
        --network-endpoint-group-zone COMPUTE_ZONE \
        --balancing-mode RATE --max-rate-per-endpoint 10
    
  8. ファイアウォールを開いて、VM のヘルスチェックを許可します。

    gcloud compute firewall-rules create fw-allow-health-check-to-vm1 \
        --network=NETWORK \
        --action=allow \
        --direction=ingress \
        --target-tags=vm-neg-tag \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --rules=tcp:9376
    
  9. テスト トラフィックを送信して、ロードバランサが新しい vm1 バックエンドと既存のコンテナ バックエンドの両方にトラフィックを転送していることを確認します。

    for i in `seq 1 100`; do curl ${VIP};echo; done
    

    コンテナ(neg-demo-app)と VM(vm1)の両方のエンドポイントからのレスポンスが表示されます。

さまざまなバックエンド サービスの VM とコンテナ

この例では、ワークロードを実行している既存の VM を参照する NEG を作成し、この NEG を新しい backendService にバックエンドとして追加します。この機能は、コンテナと VM が異なるサービスで、同じ L7 ロードバランサを共有する場合(サービスが同じ IP アドレスまたはドメイン名を共有する場合など)に便利です。

この例では、前の例を拡張することにします。前の例では、コンテナ バックエンドと同じバックエンド サービスに VM バックエンドが存在していました。この例でもその VM を再利用します。

コンテナと VM のエンドポイントは別々のバックエンド サービスにグループ化されるため、異なるサービスとみなされます。つまり、URL マップがバックエンドを照合し、ホスト名に基づいて VM またはコンテナにトラフィックを転送します。

次の図では、1 つの仮想 IP アドレスが 2 つのホスト名に対応し、さらに、コンテナベースのバックエンド サービスと VM ベースのバックエンド サービスに対応しています。

次の図は、前のセクションで説明したアーキテクチャを示しています。

このアーキテクチャには 2 つの NEG があります。1 つはコンテナで実装されたサービス用、もう 1 つは VM で実装されたサービス用です。NEG ごとにバックエンド サービス オブジェクトがあります。URL Map オブジェクトは、リクエストされた URL に基づいて正しいバックエンド サービスにトラフィックを送信します。

  1. VM に新しいバックエンド サービスを作成します。

    gcloud compute backend-services create my-vm-bes \
       --protocol HTTP \
       --health-checks http-basic-check \
       --global
    
  2. VM の NEG vm-negをバックエンド サービスに接続します。

    gcloud compute backend-services add-backend my-vm-bes \
        --global \
        --network-endpoint-group vm-neg \
        --network-endpoint-group-zone COMPUTE_ZONE \
        --balancing-mode RATE --max-rate-per-endpoint 10
    
  3. container.example.com ホストのリクエストをコンテナ バックエンド サービスに送信できるように、ホストルールを URL マップに追加します。

    gcloud compute url-maps add-path-matcher web-map \
        --path-matcher-name=container-path --default-service=my-bes \
        --new-hosts=container.example.com --global
    
  4. vm.example.com ホストのリクエストを VM バックエンド サービスに送信できるように、別のホストルールを URL マップに追加します。

    gcloud compute url-maps add-path-matcher web-map \
        --path-matcher-name=vm-path --default-service=my-vm-bes \
        --new-hosts=vm.example.com --global
    
  5. リクエストされたパスに基づいてロードバランサが VM バックエンドにトラフィックを送信していることを確認します。

    curl -H "HOST:vm.example.com" VIRTUAL_IP
    

    VIRTUAL_IP を仮想 IP アドレスに置き換えます。

スタンドアロン NEG の制限

  • アノテーションの検証エラーは Kubernetes イベントを通じてユーザーに公開されます。
  • NEG の制限はスタンドアロン NEG にも適用されます。

料金

ロードバランサの料金の詳細については、料金ページのロード バランシングのセクションをご覧ください。NEG に追加料金はかかりません。

トラブルシューティング

このセクションでは、スタンドアロン NEG で発生する可能性のある一般的な問題のトラブルシューティング手順について説明します。

スタンドアロン NEG が構成されない

症状: NEG が作成されません。

考えられる解決策:

  • Service に関連するイベントを確認し、エラー メッセージを探します。
  • スタンドアロン NEG アノテーションが正しい形式の JSON であり、公開されたポートが Service 仕様の既存のポートと一致していることを確認します。
  • NEG ステータスのアノテーションを確認し、サービスポートに対応する NEG があるかどうかを確認します。
  • gcloud compute network-endpoint-groups list コマンドを実行して、NEG が目的のゾーンに作成されていることを確認します。
  • GKE バージョン 1.18 以降を使用している場合は、Service の svcneg リソースが存在するかどうかを確認します。存在する場合は、Initialized 条件をチェックしてエラー情報を確認します。
  • カスタム NEG 名を使用している場合は、リージョン内の各 NEG 名が一意であることを確認します。

トラフィックがエンドポイントに到達しない

症状: 502 エラーが発生したか、接続が拒否されました。

考えられる解決策:

  • サービスが構成されると、通常、新しいエンドポイントは NEG に接続後にヘルスチェックに応答できれば到達可能になります。
  • この時間を過ぎてもトラフィックがエンドポイントに到達できず、for HTTP(S) のエラーコード 502 が返されるか、TCP / SSL ロードバランサの接続が拒否された場合は、次の点を確認してください。
    • ファイアウォール ルールで、エンドポイントへの TCP トラフィックの受信を 130.211.0.0/2235.191.0.0/16 の範囲で許可します。
    • Google Cloud CLI を使用するか、showHealth パラメータを SHOW に設定し backendServicegetHealth API または NEG の listEndpoints API を呼び出して、エンドポイントが正常であることを確認します。

停滞時のロールアウト

症状: 更新した Deployment がロールアウトし、最新のレプリカの数が選択されたレプリカの数と一致しません。

考えられる解決策:

デプロイのヘルスチェックが失敗しています。コンテナ イメージが不適切であるか、ヘルスチェックが正しく構成されていない可能性があります。Pod のローリングの置換は、新しく開始した Pod が Pod の readiness ゲートを通過してから行います。これは、Pod がロードバランサのヘルスチェックに応答している場合にのみ発生します。Pod が応答しない場合、またはヘルスチェックが正しく構成されていない場合は、readiness ゲートの条件を満たせず、ロールアウトを続行できません。

  • kubectl 1.13 以降を使用している場合は、次のコマンドで Pod の readiness ゲートのステータスを確認できます。

    kubectl get my-Pod -o wide
    

    READINESS GATES 列を確認します。

    この列は、kubectl 1.12 以下には存在しません。READY 状態であるとマークされた Pod は、readiness ゲートに失敗した可能性があります。これを確認するには、次のコマンドを使用します。

    kubectl get my-pod -o yaml
    

    readiness ゲートとそのステータスが出力に一覧表示されます。

  • Deployment の Pod の仕様のコンテナ イメージが正しく機能し、ヘルスチェックに応答できることを確認します。

  • ヘルスチェックが正しく構成されていることを確認します。

NEG がガベージ コレクションの対象になっていない

症状: 削除されるはずの NEG がまだ存在します。

考えられる解決策:

  • NEG がバックエンド サービスから参照されている場合、その NEG はガベージ コレクションの対象になりません。詳細は、NEG 漏洩の防止をご覧ください。
  • 1.18 以降を使用している場合は、サービス NEG の手順ServiceNetworkEndpointGroup リソースのイベントを確認できます。
  • NEG がまだサービスに必要かどうかを確認します。NEG に対応するサービスの svcneg リソースをチェックして、Service アノテーションが存在するかどうかを確認します。

NEG が Service と同期しない

症状: 想定される(Pod IP)エンドポイントが NEG に存在しません、NEG が同期されていないか、エラー Failed to sync NEG_NAME (will not retry): neg name NEG_NAME is already in use, found a custom named neg with an empty description です。

考えられる解決策:

GKE 1.18 以降を使用している場合は、svcneg リソースで次の情報を確認してください。

  • status.lastSyncTime の値を調べて、NEG が最近同期したかどうかを確認します。
  • 最新の同期で発生したエラーで、Synced 状態のものを確認します。

GKE 1.19.9 以降を使用している場合は、GKE NEG コントローラが作成する必要がある NEG の名前とゾーンに一致する名前とゾーンを持つ NEG の存在を確認します。たとえば、クラスタのゾーン(またはクラスタのゾーンの一つ)で、NEG コントローラが使用する名前の NEG が gcloud CLI または Google Cloud コンソールで作成されている可能性があります。この場合、NEG コントローラがエンドポイントを同期する前に、既存の NEG を削除する必要があります。スタンドアロン NEG の作成とメンバーシップは、NEG コントローラによって管理されるように設計されています。

次のステップ