Ingress による負荷分散の構成

このページでは、Kubernetes Ingress オブジェクトを作成して HTTP(S) ロードバランサを構成する方法について説明します。1 つの Ingress オブジェクトは 1 つ以上の Service オブジェクトに関連付けられている必要があります。それぞれの Service オブジェクトはポッドのセットに関連付けられます。

Service オブジェクトには 1 つ以上の servicePort 構造があります。Ingress がターゲットにしているそれぞれの servicePort は、Google Cloud バックエンド サービス リソースに関連付けられます。

始める前に

このタスクの準備として、次の手順を行います。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Google Kubernetes Engine API の有効化
  • Cloud SDK がインストール済みであることを確認します。
  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project [PROJECT_ID]
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone [COMPUTE_ZONE]
  • リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud を最新バージョンに更新します。
    gcloud components update
  • 複数のバックエンド サービス

    HTTP(S) ロードバランサにより、リクエストをさまざまなバックエンド サービスにルーティングする際にも、単一の固定 IP アドレスを使用できます。

    この演習では、URL パスに応じて異なるバックエンド サービスにリクエストをルーティングするようにロードバランサを構成します。パスが / のリクエストとパスが /kube のリクエストを、それぞれ別のバックエンド サービスにルーティングします。

    この演習の全体を通した手順は次のとおりです。

    1. Deployment を作成し、hello-world という名前の Service で公開します。
    2. 2 番目の Deployment を作成し、hello-kubernetes という名前の Service で公開します。
    3. リクエスト内の URL パスに応じて、ある Service から別の Service にリクエストをルーティングするためのルールを指定する Ingress を作成します。Ingress を作成すると、GKE Ingress コントローラが HTTP(S) ロードバランサを作成して構成します。
    4. HTTP(S) ロードバランサをテストします。

    最初の Deployment のマニフェストは次のとおりです。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-world-deployment
    spec:
      selector:
        matchLabels:
          greeting: hello
          department: world
      replicas: 3
      template:
        metadata:
          labels:
            greeting: hello
            department: world
        spec:
          containers:
          - name: hello
            image: "gcr.io/google-samples/hello-app:2.0"
            env:
            - name: "PORT"
              value: "50000"
    

    このマニフェストを hello-world-deployment.yaml という名前のファイルにコピーし、次のようにして Deployment を作成します。

    kubectl apply -f hello-world-deployment.yaml
    

    最初の Deployment を公開する Service のマニフェストは次のとおりです。

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-world
    spec:
      type: NodePort
      selector:
        greeting: hello
        department: world
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50000
    

    この演習を進めるにあたって、この Service について次のことを理解しておくことが重要です。

    • greeting: hello ラベルと department: world ラベルの両方を持つすべてのポッドはこの Service のメンバーです。

    • リクエストが TCP ポート 60000 でこの Service に送信されると、そのリクエストは TCP ポート 50000 でメンバーポッドの 1 つに転送されます。

    マニフェストを hello-world-service.yaml という名前のファイルにコピーして、Service を作成します。

    kubectl apply -f hello-world-service.yaml
    

    2 番目の Deployment のマニフェストは次のとおりです。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello-kubernetes-deployment
    spec:
      selector:
        matchLabels:
          greeting: hello
          department: kubernetes
      replicas: 3
      template:
        metadata:
          labels:
            greeting: hello
            department: kubernetes
        spec:
          containers:
          - name: hello-again
            image: "gcr.io/google-samples/node-hello:1.0"
            env:
            - name: "PORT"
              value: "8080"
    

    このマニフェストを hello-kubernetes-deployment.yaml という名前のファイルにコピーし、次のようにして Deployment を作成します。

    kubectl apply -f hello-kubernetes-deployment.yaml
    

    2 番目の Deployment を公開する Service のマニフェストは次のとおりです。

    apiVersion: v1
    kind: Service
    metadata:
      name: hello-kubernetes
    spec:
      type: NodePort
      selector:
        greeting: hello
        department: kubernetes
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
    

    この演習を進めるにあたって、この Service について次のことを理解しておくことが重要です。

    • greeting: hello ラベルと department: kubernetes ラベルの両方を持つすべてのポッドはこの Service のメンバーです。

    • リクエストが TCP ポート 80 でこの Service に送信されると、そのリクエストは TCP ポート 8080 でメンバーポッドの 1 つに転送されます。

    マニフェストを hello-kubernetes-service.yaml という名前のファイルにコピーして、Service を作成します。

    kubectl apply -f hello-kubernetes-service.yaml
    

    Ingress のマニフェストを次に示します。

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: my-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /*
            backend:
              serviceName: hello-world
              servicePort: 60000
          - path: /kube
            backend:
              serviceName: hello-kubernetes
              servicePort: 80
    

    Ingress マニフェストには 2 つの(serviceNameservicePort)ペアがあります。Ingress がターゲットにしているそれぞれの(serviceNameservicePort)は、Google Cloud バックエンド サービス リソースに関連付けられます。

    このマニフェストを my-ingress.yaml という名前のファイルにコピーし、次のようにして Ingress を作成します。

    kubectl apply -f my-ingress.yaml
    

    Ingress を作成すると、GKE Ingress コントローラにより HTTP(S) ロードバランサが作成され、次のようにロードバランサが構成されます。

    • クライアントが URL パス / を使用してロードバランサにリクエストを送信すると、そのリクエストはポート 60000 で hello-world Service に転送されます。

    • クライアントが URL パス /kube を使用してロードバランサにリクエストを送信すると、そのリクエストはポート 80 で hello-kubernetes に転送されます。

    ロードバランサが構成されるまで約 5 分待ちます。

    Ingress を確認します。

    kubectl get ingress my-ingress --output yaml
    

    出力には、HTTP(S) ロードバランサの外部 IP アドレスが示されます。

    status:
      loadBalancer:
        ingress:
        - ip: 203.0.113.1
    

    / パスをテストします。

    curl [LOAD_BALANCER_IP]/
    

    ここで、[LOAD_BALANCER_IP] はロードバランサの外部 IP アドレスです。

    出力には、Hello, world! メッセージが表示されます。

    Hello, world!
    Version: 2.0.0
    Hostname: ...
    

    /kube パスをテストします。

    curl [LOAD_BALANCER_IP]/kube
    

    出力には、Hello Kubernetes メッセージが表示されます。

    Hello Kubernetes!
    

    クライアントとロードバランサ間の HTTPS

    HTTP(S) ロードバランサは、クライアントとアプリケーションの間のプロキシとして機能します。クライアントからの HTTPS リクエストを受け入れるには、ロードバランサは証明書を持っていなければなりません。これにより、適切な送信先であることをクライアントに示すことができます。さらに、ロードバランサには、HTTPS handshake を完了するための秘密鍵も必要です。詳細情報

    HTTP の無効化

    クライアントとロードバランサ間のすべてのトラフィックで HTTPS を使用する場合は、HTTP を無効にすることができます。詳しくは、HTTP の無効化をご覧ください。

    ロードバランサとクライアント間の HTTPS

    GKE ポッドで実行しているアプリケーションが HTTPS リクエストを受信できる場合は、ロードバランサがリクエストをアプリケーションに転送するときに HTTPS を使用するようにロードバランサを構成できます。詳しくは、ロードバランサとアプリケーション間の HTTPS(TLS)をご覧ください。

    クライアントとロードバランサ間の HTTP/2

    クライアントは HTTP/2 を使用してロードバランサにリクエストを送信できます。構成は不要です。

    ロードバランサとアプリケーション間の HTTP/2

    GKE ポッドで実行しているアプリケーションが HTTP/2 リクエストを受信できる場合は、ロードバランサがリクエストをアプリケーションに転送するときに HTTP/2 を使用するようにロードバランサを構成できます。詳しくは、Ingress による HTTP/2 を使用した負荷分散をご覧ください。

    ネットワーク エンドポイント グループ

    クラスタがコンテナ ネイティブの負荷分散をサポートしている場合は、ネットワーク エンドポイント グループを使用するようにロードバランサを構成できます。詳しくは、コンテナ ネイティブの負荷分散を使用するをご覧ください。

    Ingress アノテーションの概要

    kubernetes.io/ingress.allow-http
    クライアントと HTTP(S) ロードバランサ間の HTTP トラフィックを許可するかどうかを指定します。有効な値は "true" と "false" です。デフォルトは "true" です。HTTP の無効化をご覧ください。
    ingress.gcp.kubernetes.io/pre-shared-cert
    証明書と鍵を Google Cloud プロジェクトにアップロードできます。このアノテーションを使用して証明書と鍵を参照します。HTTP(S) 負荷分散のための複数の SSL 証明書の使用をご覧ください。
    kubernetes.io/ingress.global-static-ip-name
    このアノテーションを使用して、以前に作成した静的外部 IP アドレスをロードバランサが使用するように指定します。HTTP(S) ロードバランサの静的 IP アドレスをご覧ください。
    service.alpha.kubernetes.io/app-protocols
    このアノテーションを使用して、ロードバランサとアプリケーション間の通信用のプロトコルを設定します。有効なプロトコルは HTTP、HTTPS、HTTP/2 です。ロードバランサとアプリケーション間の HTTPSIngress による HTTP/2 を使用した負荷分散をご覧ください。
    beta.cloud.google.com/backend-config
    このアノテーションを使用して、servicePort に関連付けられるバックエンド サービスを構成します。BackendConfig カスタム リソースをご覧ください。
    cloud.google.com/neg
    このアノテーションを使用して、ロードバランサがネットワーク エンドポイント グループを使用するように指定します。コンテナ ネイティブの負荷分散の使用をご覧ください。

    次のステップ