スタンドアロン NEG によるコンテナ ネイティブの負荷分散

このページでは、ゾーン ネットワーク エンドポイント グループ(NEG)を基盤とする Kubernetes Service の作成方法について説明します。

コンテナ ネイティブの負荷分散のメリット、要件、制限事項については、コンテナ ネイティブの負荷分散をご覧ください。

概要

ネットワーク エンドポイント グループ(NEG)は、ロードバランサによって処理されるバックエンドのグループです。NEG は NEG コントローラが管理する IP アドレスのリストで、Google Cloud ロードバランサが使用します。NEG 内の IP アドレスには、VM のプライマリ IP アドレスまたはセカンダリ IP アドレスを指定できます。Pod の IP でもかまいません。これにより、コンテナ ネイティブの負荷分散が可能になり、Google Cloud ロードバランサから直接 Pod にトラフィックを送信できます。

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

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

Ingress と NEG

NEG を GKE Ingress と一緒に使用すると、Ingress コントローラで L7 ロードバランサの作成が容易になります。たとえば、仮想 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 で TCP プロキシ負荷分散を使用する

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

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 に設定します。

要件

スタンドアロン NEG は GKE 1.10 以降で使用できます。Pod の readiness フィードバックは、バージョン 1.16.4 以降のスタンドアロン NEG で有効になります。

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

クラスタの HTTP 負荷分散を有効にする必要があります。デフォルトでは、GKE クラスタで HTTP 負荷分散が有効になっています。

始める前に

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

次のいずれかの方法で gcloud のデフォルトの設定を指定します。

  • gcloud init。デフォルトの設定全般を確認する場合に使用します。
  • gcloud config。プロジェクト ID、ゾーン、リージョンを個別に設定する場合に使用します。

gcloud init の使用

エラー One of [--zone, --region] must be supplied: Please specify location を受信した場合は、このセクションの内容を実施します。

  1. gcloud init を実行して、次の操作を行います。

    gcloud init

    リモート サーバーで SSH を使用している場合は、--console-only フラグを指定して、コマンドがブラウザを起動しないようにします。

    gcloud init --console-only
  2. 手順に従って gcloud を承認し、Google Cloud アカウントを使用します。
  3. 新しい構成を作成するか、既存の構成を選択します。
  4. Google Cloud プロジェクトを選択します。
  5. ゾーンクラスタの場合はデフォルトの Compute Engine ゾーン、リージョン クラスタまたは Autopilot クラスタの場合はデフォルトの Compute Engine リージョンを選択します。

gcloud config の使用

  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project PROJECT_ID
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone COMPUTE_ZONE
  • Autopilot クラスタまたはリージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region COMPUTE_REGION
  • gcloud を最新バージョンに更新します。
    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 ネイティブ クラスタを作成する

コンテナネイティブの負荷分散を使用するには、有効なエイリアス IP を使用したクラスタを作成する必要があります。このクラスタは次の条件を満たしている必要があります。

  • Google Kubernetes Engine バージョン 1.16.4 以降が実行されている。
  • VPC ネイティブ クラスタである。
  • HTTP 負荷分散アドオンが有効になっている。GKE クラスタの HTTP 負荷分散はデフォルトで有効になっています。無効にしないでください。

次のコマンドを実行して、自動でプロビジョニングされたサブネットワークを持つクラスタ NEG_DEMO_CLUSTER をゾーン us-central1-a に作成します。

gcloud container clusters create NEG_DEMO_CLUSTER \
    --enable-ip-alias \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a \
    --cluster-version VERSION

VERSION をクラスタのバージョン番号に置き換えます。バージョンは 1.16.4 以降である必要があります。

Deployment を作成する

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

お使いの GKE のバージョンで可能な場合は、Pod の readiness フィードバックを使うワークロードの使用をおすすめします。詳細については、上記の Pod の readiness をご覧ください。Pod readiness のフィードバックを使用するために必要な GKE のバージョンについては、要件をご覧ください。クラスタを更新して、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: k8s.gcr.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: k8s.gcr.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(NEG_DEMO_SVC)を指定します。

  • 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 に名前を付ける

NEG の名前は、指定することも、自動的に割り当てることもできます。NEG の名前を指定すると、事前に NEG の名前を調べる必要がなくなるため、後の手順が簡素化されます。ただし、以下の点を保証しなければなりません。

  • NEG 名は指定のリージョンで一意である。
  • Ingress コントローラの外部に NEG がまだ作成されていない。

そうでない場合、NEG の作成と同期は失敗します。NEG が Service と同期しない。をご覧ください。自動生成される NEG 名は、一意になることが保証されています。

NEG 名は GKE バージョン 1.18.10-gke.600 以降でのみ指定できます。自動生成された NEG 名は、以前のバージョンで使用されます。

名前を指定する

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

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

NEG_NAME は、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

このコマンドは、NEG のステータスを次の形式で出力します。

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":["us-central1-a", "us-central1-b"]}'
  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 がゾーン us-central1-aus-central1-b にある 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  us-central1-a  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-standard-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.43  9376
gke-standard-cluster-3-default-pool-4cc71a15-qlpf  10.12.1.44  9376
gke-standard-cluster-3-default-pool-4cc71a15-w9nk  10.12.2.26  9376

スタンドアロン NEG にロードバランサを接続する

NEG を作成したら、次のタイプのロードバランサのバックエンドとして使用できます。

  • 外部 HTTP(S) ロードバランサ
  • 内部 HTTP(S) ロードバランサ
  • SSL プロキシ ロードバランサ
  • TCP プロキシ ロードバランサ

次の例をご覧ください。

外部 HTTP(S) ロードバランサをスタンドアロン NEG に接続する

次の手順は、Compute Engine API を使用して外部 HTTP ロードバランサを作成する方法を示しています。

  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 列にインスタンス名が表示されます。標準クラスタの場合、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. バックエンド サービスを作成して、これがグローバル外部 HTTP(S) ロードバランサであることを指定します。

    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 アドレスに置き換えます。この目的で使用する新しい静的外部 IP アドレスを予約できます。--address オプションを省略すると、エフェメラル 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  us-central1-a  GCE_VM_IP_PORT  3

この出力例では、NEG の名前は k8s1-70aa83a6-default-my-service-80-c9710a6f で、ゾーン us-central1-a にあります。

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

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

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

  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-standard-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.43
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-standard-cluster-3-default-pool-4cc71a15-qlpf
    ipAddress: 10.12.1.44
    port: 50000
  - healthState: HEALTHY
    instance: ... gke-standard-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 になります。

内部 HTTP(S) ロードバランサをスタンドアロン NEG に接続する

このセクションでは、スタンドアロン GKE Pod で実行されるサービスの内部 HTTP(S) 負荷分散を構成する手順について説明します。

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

プロキシ専用サブネットは、ロードバランサのリージョン内のすべての内部 HTTP(S) ロードバランサ(この例では us-west1)用です。

Console

GCP Console を使用している場合は、しばらく待ってから、Load Balancing の UI でプロキシ専用サブネットを作成できます。

gcloud

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

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

API

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

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

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

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

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

  • 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 を使用して、適用するインスタンスを識別します。

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

Console

  1. Google Cloud Console の [ファイアウォール ルール] ページに移動します。
    [ファイアウォール ルール] ページに移動
  2. [ファイアウォール ルールを作成] をクリックして、SSH 接続の受信を許可するルールを作成します。
    • 名前: fw-allow-ssh
    • ネットワーク: lb-network
    • トラフィックの方向: 上り
    • 一致したときのアクション: 許可
    • ターゲット: 指定されたターゲットタグ
    • ターゲットタグ: allow-ssh
    • ソースフィルタ: IP ranges
    • ソース IP の範囲: 0.0.0.0/0
    • プロトコルとポート:
      • 指定されたプロトコルとポートを選択します。
      • tcp にチェックを入れて、ポート番号に「22」と入力します。
  3. [作成] をクリックします。
  4. [ファイアウォール ルールを作成] をもう一度クリックして、Google Cloud ヘルスチェックを許可するルールを作成します。
    • 名前: fw-allow-health-check
    • ネットワーク: lb-network
    • トラフィックの方向: 上り
    • 一致したときのアクション: 許可
    • ターゲット: 指定されたターゲットタグ
    • ターゲットタグ: load-balanced-backend
    • ソースフィルタ: IP ranges
    • 送信元 IP 範囲: 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
    • ソースフィルタ: IP ranges
    • ソース IP の範囲: 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"
}

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

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

Console

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

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

ロードバランサの準備

  1. ロードバランサの [名前] に「l7-ilb-gke-map」と入力します。
  2. [リージョン] で us-west1 を選択します。
  3. [ネットワーク] で lb-network を選択します。
  4. ウィンドウを開いたままにして続行します。

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

内部 HTTP(S) 負荷分散の場合は、プロキシ専用サブネットを予約します。

  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. エンドポイントあたりの 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. [完了] をクリックします。

構成の完了

  1. [作成] をクリック

gcloud

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

    gcloud compute health-checks create http l7-ilb-gke-basic-check \
       --region=us-west1 \
       --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=us-west1 \
      --region=us-west1
    
  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=us-west1-b \
       --region=us-west1 \
       --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=us-west1
    
  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=us-west1 \
      --region=us-west1
    

    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=us-west1
    

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

    gcloud compute target-https-proxies create l7-ilb-gke-proxy \
      --url-map=l7-ilb-gke-map \
      --region=us-west1 \
      --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=us-west1 \
      --target-http-proxy=l7-ilb-gke-proxy \
      --target-http-proxy-region=us-west1
    

    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=us-west1 \
      --target-https-proxy=l7-ilb-gke-proxy \
      --target-https-proxy-region=us-west1
    

API

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

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

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

regionBackendServices.insert メソッドに POST リクエストを送信してリージョン バックエンド サービスを作成します。project-id は実際のプロジェクト ID で置き換えます。neg-name は、作成した NEG の名前で置き換えます。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/us-west1/backendServices
{
  "name": "l7-ilb-gke-backend-service",
  "backends": [
    {
      "group": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/us-west1-b/networkEndpointGroups/NEG_NAME",
      "balancingMode": "RATE",
      "maxRatePerEndpoint": 5
    }
  ],
  "healthChecks": [
    "projects/PROJECT_ID/regions/us-west1/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/us-west1/urlMaps
{
  "name": "l7-ilb-gke-map",
  "defaultService": "projects/PROJECT_ID/regions/us-west1/backendServices/l7-ilb-gke-backend-service"
}

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

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

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

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

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

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

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

テスト

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

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

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

各クライアント インスタンスへ SSH を介して接続します。

gcloud compute ssh l7-ilb-client-us-west1-b \
    --zone=us-west1-b

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

curl 10.1.2.199

HTTPS テストの場合、curl は次のもので置き換えます。

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 ZONE --network=NETWORK \
     --subnet=SUBNET --image-project=cos-cloud \
     --image-family=cos-stable --tags=vm-neg-tag

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

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

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

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

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

    gcloud compute ssh vm1 --zone=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=ZONE
  5. VM エンドポイントを NEG に接続します。

    gcloud compute network-endpoint-groups update vm-neg --zone=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=ZONE
  7. コンテナ バックエンドの追加に使用したコマンドを使用して、NEG をバックエンド サービスに接続します。

    gcloud compute backend-services add-backend my-bes --global \
     --network-endpoint-group vm-neg \
     --network-endpoint-group-zone 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 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 の制限

料金

ロードバランサの料金の詳細については、料金ページの負荷分散のセクションをご覧ください。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 の範囲で許可します。
    • エンドポイントが正常であることを確認するには、gcloud を使用するか、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 以降を使用している場合は、こちらの手順を使用して ServiceNetworkEndpointGroup リソースのイベントを確認できます。
  • NEG がまだサービスに必要かどうかを確認します。NEG に対応するサービスの svcneg リソースをチェックして、Service アノテーションが存在するかどうかを確認します。

NEG が Service と同期しない

症状: 想定されるエンドポイントが存在しない、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 以降を使用している場合は、Ingress コントローラの外部で NEG がまだ作成されていないことを確認します。NEG が前に gcloud または Cloud Console で作成された場合は、NEG を削除すると、Ingress コントローラによって自動的に再作成されます。これにより、同期を再開できます。

次のステップ