Ingress での HTTP 負荷分散の設定

このチュートリアルでは、Ingress リソースを構成することにより、HTTP ロードバランサの背後でウェブ アプリケーションを実行する方法について説明します。

背景

Kubernetes Engine には、一般公開するアプリケーション用に次の 2 種類の Cloud Load Balancing のサポートが組み込まれています。

  1. TCP ロードバランサ: サービス リソース マニフェストで type: LoadBalancer を指定することでこれを作成できます。TCP ロードバランサは HTTP ウェブサーバーで動作しますが、個々の HTTP(S) リクエストを認識しないので、HTTP(S) トラフィックを終端させるようには設計されていません。Kubernetes Engine は、TCP ロードバランサのヘルスチェックを設定しません。

  2. HTTP(S) ロードバランサ: Ingress リソースを使用してこれを作成できます。HTTP(S) ロードバランサは HTTP(S) リクエストを終端させるように設計されており、状況に応じてより適切に負荷分散の判断を下すことができます。提供される機能には、カスタマイズ可能な URL マップTLS ターミネーションなどがあります。Kubernetes Engine は、HTTP(S) ロードバランサのヘルスチェックを自動的に設定します。

Kubernetes Engine でホストされている HTTP(S) サービスを公開する場合は、負荷分散として HTTP(S) 負荷分散の利用をおすすめします。

始める前に

次の手順で Kubernetes Engine API を有効にします。
  1. Google Cloud Platform Console で Kubernetes Engine ページにアクセスします。
  2. プロジェクトを作成または選択します。
  3. API と関連サービスが有効になるのを待ちます。これには数分かかることがあります。
  4. プロジェクトに対して課金が有効になっていることを確認します。

    課金を有効にする方法について

このチュートリアルで使用されている以下のコマンドライン ツールをインストールします。

  • Kubernetes Engine クラスタを作成および削除するには、gcloud を使用します。gcloudGoogle Cloud SDK に含まれています。
  • kubectl は、Kubernetes Engine で使用されるクラスタ オーケストレーション システムである Kubernetes を管理するために使用されます。gcloud を使用して kubectl をインストールできます。
    gcloud components install kubectl

gcloud コマンドライン ツールのデフォルトを設定する

次のコマンドを実行してデフォルト値を設定しておくと、gcloud コマンドライン ツールでプロジェクト IDCompute Engine ゾーンの各オプションを入力する時間を節約できます。
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

コンテナ クラスタを作成する

次のコマンドを実行して、loadbalancedcluster という名前のコンテナ クラスタを作成します。

gcloud container clusters create loadbalancedcluster

ステップ 1: ウェブ アプリケーションをデプロイする

ポート 8080 で HTTP サーバーをリッスンするサンプル ウェブ アプリケーション コンテナ イメージを使用して、Deployment を作成します。

kubectl run web --image=gcr.io/google-samples/hello-app:1.0 --port=8080

ステップ 2: Deployment をサービスとして内部公開する

コンテナ クラスタ内で web Deployment を到達可能にするための Service リソースを作成します。

kubectl expose deployment web --target-port=8080 --type=NodePort

このコマンドで NodePort タイプの Service を作成すると、クラスタ内のすべてのノードで、ランダムに選択された上位ポート番号(32640 など)を使用して Service を利用できるようになります。

Service が作成されてノードポートが割り当てられたことを確認します。

$ kubectl get service web
NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
web       NodePort   10.35.245.219   <none>        8080:32640/TCP   5m

上記のサンプル出力の場合、web サービスのノードポートは 32640 です。また、このサービスには外部 IP アドレスが割り当てられていないことに注意してください。デフォルトで Kubernetes Engine ノードに外部からアクセスすることはできないため、この Service を作成しても、インターネットからアプリケーションにアクセスできるようにはなりません。

HTTP(S) ウェブサーバー アプリケーションを公開するには、Ingress リソースを作成する必要があります。

ステップ 3: Ingress リソースを作成する

Ingress は、外部 HTTP(S) トラフィックを内部サービスにルーティングするためのルールと設定の集合をカプセル化する Kubernetes リソースです。

Kubernetes Engine では、Ingress は Cloud Load Balancing を使用して実装されます。クラスタで Ingress を作成すると、Kubernetes Engine により HTTP(S) ロードバランサが作成され、トラフィックをアプリケーションにルーティングするように構成されます。

Kubernetes Ingress はベータ版リソースであり、Ingress オブジェクトの記述方法は変更される可能性がありますが、Kubernetes Engine で Ingress を実装するためにプロビジョニングされる Cloud Load Balancer は、本番環境に対応しています。

次の設定ファイルでは、トラフィックを web サービスに転送する Ingress リソースが定義されています。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: basic-ingress
spec:
  backend:
    serviceName: web
    servicePort: 8080

この Ingress リソースをデプロイするには、basic-ingress.yaml をダウンロードして実行します。

kubectl apply -f basic-ingress.yaml

このマニフェストをデプロイすると、Kubernetes の Ingress リソースがクラスタに作成されます。クラスタで実行される Ingress コントローラは、HTTP(S) ロードバランサを作成し、公開された web NodePort サービスにすべての外部 HTTP トラフィック(ポート 80)をルーティングします。

ステップ 4: アプリケーションにアクセスする

次のコマンドを実行して、アプリケーションに対応するロードバランサの外部 IP アドレスを調べます。

$ kubectl get ingress basic-ingress
NAME            HOSTS     ADDRESS         PORTS     AGE
basic-ingress   *         203.0.113.12    80        2m

ブラウザでアプリケーションの外部 IP アドレスを指定すると、次のようなプレーン テキストの HTTP レスポンスが表示されます。

Hello, world!
Version: 1.0.0
Hostname: web-6498765b79-fq5q5

GCP Console の [負荷分散] にアクセスすると、Ingress コントローラによって作成されたネットワーキング リソースを調べることができます。

ステップ 5: (オプション)静的 IP アドレスを設定する

ドメイン名でウェブサーバーを公開する場合、アプリケーションの外部 IP アドレスを変化しない静的 IP アドレスにする必要があります。

デフォルトで、Ingress によって公開される HTTP アプリケーションに Kubernetes Engine が割り当てるのはエフェメラル外部 IP アドレスです。エフェメラル アドレスは変化する可能性があります。長期間使用する予定のウェブ アプリケーションでは、静的外部 IP アドレスを使用する必要があります。

Ingress リソースに静的 IP アドレスを設定した場合、Ingress を削除しても、それに関連付けられている静的 IP アドレスは削除されないことに注意してください。設定した静的 IP アドレスを再び使用する予定がない場合は、クリーンアップが必要になります。

オプション 1: 既存のエフェメラル IP アドレスを静的 IP アドレスに変換する

Ingress をすでにデプロイしてある場合、GCP Console の [外部 IP アドレス] セクションで、外部 IP アドレスを変更することなく、アプリケーションの既存のエフェメラル IP アドレスを予約された静的 IP アドレスに変換できます。

オプション 2: 新しい静的 IP アドレスを予約する

次のコマンドを実行することにより、web-static-ip という静的外部 IP アドレスを予約します。

gcloud compute addresses create web-static-ip --global

次に、予約した IP アドレスを使用するように、既存の Ingress リソースを設定する必要があります。basic-ingress.yaml マニフェストの内容を次のマニフェストに置き換えます。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: basic-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: web-static-ip
spec:
  backend:
    serviceName: web
    servicePort: 8080

この変更により、web-static-ip という名前の静的 IP リソースを使用するためのアノテーションが Ingress に追加されます。この変更を既存の Ingress に適用するには、次のコマンドを実行します。

kubectl apply -f basic-ingress.yaml

kubectl get ingress basic-ingress を実行します。アプリケーションの IP アドレスが web-static-ip リソースの予約済み IP アドレスを使用するように変更されるまで待ちます。

既存の Ingress リソースが更新され、ロードバランサが再設定されて、負荷分散ルールが世界中に伝播されるまで、数分かかることがあります。このオペレーションが完了すると、Kubernetes Engine は、以前にアプリケーションに割り当てられていたエフェメラル IP アドレスを解放します。

ステップ 6: (オプション)1 つのロードバランサで複数のアプリケーションに対応する

Ingress でルーティング ルールを設定することにより、単一のロードバランサとパブリック IP アドレスで複数のサービスを実行できます。同じ Ingress で複数のサービスをホストすると、インターネットに公開するサービスごとに追加のロードバランサ(課金対象のリソース)を作成しなくて済みます。

同じウェブ アプリケーションのバージョン 2.0 として別のウェブサーバー Deployment を作成します。

kubectl run web2 --image=gcr.io/google-samples/hello-app:2.0 --port=8080

次に、この web2 Deployment を、web という名前の NodePort サービス上のクラスタに内部公開します。

kubectl expose deployment web2 --target-port=8080 --type=NodePort

以下に示すマニフェストは、次のような Ingress リソースを記述しています。

  • /v2/ でパスが始まるリクエストを web2 サービスにルーティングする。
  • 他のすべてのリクエストを web サービスにルーティングする。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: fanout-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: web
          servicePort: 8080
      - path: /v2/*
        backend:
          serviceName: web2
          servicePort: 8080

このマニフェストをデプロイするには、マニフェストを fanout-ingress.yaml に保存して次のコマンドを実行します。

kubectl create -f fanout-ingress.yaml

Ingress をデプロイした後、kubectl get ingress fanout-ingress を実行して、クラスタのパブリック IP アドレスを調べます。

次に、IP アドレスを参照して、両方のアプリケーションが同じロードバランサ上で到達可能であることを確認します。

  • http://<IP_ADDRESS>/ に移動し、レスポンスに Version: 1.0.0 が含まれていることを確認します(リクエストは web サービスにルーティングされる)
  • http://<IP_ADDRESS>/v2/ に移動し、レスポンスに Version: 2.0.0 が含まれていることを確認します(リクエストは web2 サービスにルーティングされる)

備考

Ingress を介して公開される Service は、/ パスでの GET リクエストに対して HTTP 200 ステータスでレスポンスを返す必要があります。これはヘルスチェックに使用されます。アプリケーションが / 上で HTTP 200 を返さない場合、そのバックエンドは異常とマークされ、トラフィックが取得されなくなります。

Ingress は、次のような高度なユースケースをサポートしています。

  • 名前ベースの仮想ホスティング: Ingress を使用して、複数のドメイン名およびサブドメインに対してロードバランサを再利用し、複数の Service を 1 つの IP アドレスとロードバランサで公開することができます。これらのタスク用に Ingress を設定する方法については、簡単なファンアウト名前ベースの仮想ホスティングの例をご覧ください。

  • HTTPS ターミネーション: Cloud Load Balancer を使用して HTTPS トラフィックを終端するように Ingress を設定できます。

Ingress を削除すると、関連付けられているリソース(予約された静的 IP アドレスを除く)は Ingress コントローラによって自動的にクリーンアップされます。

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

  1. Ingress を削除する: アプリケーションに関連付けられているエフェメラル外部 IP アドレスと負荷分散リソースの割り当てを解除します。

    kubectl delete ingress basic-ingress
    

    「ステップ 6」を行った場合は、次のコマンドを実行して Ingress を削除します。

    kubectl delete ingress fanout-ingress
    
  2. 静的 IP アドレスを削除する: この手順は、ステップ 5 を行った場合にのみ実行します。

    • ステップ 5 の「オプション 1」を実行して既存のエフェメラル IP アドレスを静的 IP アドレスに変換した場合は、GCP Console で静的 IP アドレスを削除します。

    • ステップ 5 の「オプション 2」を実行した場合は、次のコマンドを実行して静的 IP アドレスを削除します。

      gcloud compute addresses delete web-static-ip --global
      
  3. クラスタを削除する: コンテナ クラスタのコンピューティング ノードとその他のリソース(クラスタ内の Deployment など)を削除します。

    gcloud container clusters delete loadbalancedcluster
    

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Kubernetes Engine のチュートリアル