Ingress による HTTP(S) 負荷分散の設定

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

背景

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

  • リソース マニフェストに type:LoadBalancer を指定すると、GKE は LoadBalancer タイプの Service を作成します。GKE は、適切な Google Cloud API 呼び出しを行い、外部ネットワーク ロードバランサまたは内部 TCP/UDP ロードバランサを作成します。cloud.google.com/load-balancer-type: "Internal" アノテーションを追加すると、GKE は内部 TCP/UDP ロードバランサを作成します。追加しない場合、GKE は外部ネットワーク ロードバランサを作成します。

    このいずれかのロードバランサを HTTP(S) トラフィックの処理に使用できますが、これらは OSI レイヤ 3 または 4 で動作します。このため、HTTP 接続や、個々の HTTP リクエストとレスポンスを認識しません。もう 1 つの重要な特徴は、リクエストがプロキシ経由で宛先に送信されない点です。

  • リソース マニフェストに type:Ingress を指定すると、GKE は Ingress リソースを作成します。アノテーション、サポート ワークロード、Service を指定すると、独自の Ingress コントローラを作成できます。それ以外の場合、GKE は適切な Google Cloud API 呼び出しを行い、外部 HTTP(S) ロードバランサを作成します。ロードバランサの URL マップのホストルールとパスマッチャーは 1 つ以上のバックエンド サービスを参照します。Ingress で参照されているように、各バックエンド サービスは NodePort タイプの GKE Service に対応しています。各バックエンド サービスのバックエンドは、インスタンス グループまたはネットワーク エンドポイント グループ(NEG)のいずれかです。Ingress の構成の一部として コンテナ ネイティブの負荷分散を構成すると、NEG が作成されます。GKE は、対応する GKE Service が参照するワークロードの準備プローブ設定に基づいて、バックエン ドサービスごとに Google Cloud ヘルスチェックを作成します。

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

始める前に

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

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

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

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

次のようにしてデフォルト値を設定しておくと、gcloud コマンドライン ツールでプロジェクト ID および Compute Engine ゾーン オプションを入力する時間が節約されます。
    gcloud config set project [PROJECT_ID]
    gcloud config set compute/zone [COMPUTE_ENGINE_ZONE]

コンテナ クラスタの作成

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

    gcloud container clusters create loadbalancedcluster
    

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

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

Deployment を作成するには、web-deployment.yaml をダウンロードしてリソースをクラスタに適用します。

    kubectl apply -f web-deployment.yaml
    

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

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

Deployment を作成するには、web-service.yaml をダウンロードしてリソースをクラスタに適用します。

    kubectl apply -f web-service.yaml
    

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

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

    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 Service のノードポートは 32640 です。また、この Service には外部 IP アドレスが割り当てられていないことに注意してください。デフォルトで GKE ノードに外部からアクセスすることはできないため、この Service を作成しても、インターネットからアプリケーションにアクセスできるようにはなりません。

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

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

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

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

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

次の構成ファイルでは、トラフィックを web Service に転送する 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 Service にすべての外部 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

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

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

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

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

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

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

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

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

web-static-ip という静的外部 IP アドレスを予約します。

gcloud

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

Config Connector

注: この手順には Config Connector が必要です。Config Connector をクラスタにインストールするには、インストール手順を実行してください。

apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: web-static-ip
    spec:
      location: global
このマニフェストをデプロイするには、マニフェストを compute-address.yaml というファイル名でマシンにダウンロードしてから、次のコマンドを実行します。
kubectl apply -f compute-address.yaml

次に、予約した 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 リソースが更新され、ロードバランサが再構成されて、負荷分散ルールが世界中に伝播されるまで、数分かかることがあります。このオペレーションが完了すると、以前にアプリケーションに割り当てられていたエフェメラル IP アドレスが解放されます。

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

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

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

web-deployment-v2.yaml をダウンロードして、リソースをクラスタに適用します。

    kubectl apply -f web-deployment-v2.yaml
    

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

web-service-v2.yaml をダウンロードして、リソースをクラスタに適用します。

    kubectl apply -f web-service-v2.yaml
    

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

  • /v2/ でパスが始まるリクエストを web2 Service にルーティングする。
  • 他のすべてのリクエストを web Service にルーティングする。
    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 Service にルーティングされる)。
  • http://<IP_ADDRESS>/v2/ に移動し、レスポンスに Version: 2.0.0 が含まれていることを確認します(リクエストは web2 Service にルーティングされる)。

GKE Ingress の path フィールドでサポートされているワイルドカード パターン マッチングは、* 文字の使用のみです。たとえば、/*/foo/bar/* などの path フィールドを持つルールを作成できます。path の制限事項については、URL マップのドキュメントをご覧ください。

備考

デフォルトでは、Ingress は GET リクエストを / パスで実行してアプリケーションの状態を判断することで定期的なヘルスチェックを実行し、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 に変換した場合は、Cloud Console にアクセスして静的 IP を削除します。

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

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

    gcloud container clusters delete loadbalancedcluster

次のステップ