Ingress による HTTP/2 を使用した負荷分散

このページでは、Kubernetes の Ingress オブジェクトと Service オブジェクトを使用して、バックエンド サービスとの通信で HTTP/2 を使用するように外部 HTTP(S) ロードバランサを構成する方法について説明します。この機能は、Google Kubernetes Engine バージョン 1.11.2 以降で使用できます。

概要

HTTP(S) ロードバランサは、クライアントとアプリケーションの間のプロキシとして機能します。クライアントは、HTTP/1.1 または HTTP/2 を使用してロードバランサ プロキシと通信できます。ただし、ロードバランサ プロキシからアプリケーションへの接続には、デフォルトで HTTP/1.1 を使用します。Google Kubernetes Engine Pod で実行中のアプリケーションで HTTP/2 リクエストを受信できる場合、アプリケーションにリクエストを転送するときに HTTP/2 を使用するように外部ロードバランサを構成します。

ロードバランサから Pod までの HTTP/2 を表す図(クリックして拡大)

この演習では、Deployment、Service、Ingress を作成します。Service マニフェストに cloud.google.com/app-protocols アノテーションを挿入して、ロードバランサがアプリケーションとの通信に HTTP/2 を使用する必要があることを指定します。その後、Service を呼び出して、アプリケーションが HTTP/2 リクエストを受信したことを確認します。

始める前に

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

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

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

gcloud init の使用

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

    gcloud init

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

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

gcloud config の使用

  • デフォルトのプロジェクト 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

Deployment を作成する

この Deployment マニフェストでは、echoheaders ウェブ アプリケーションの 2 つのレプリカを実行することを宣言します。

apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echoheaders
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: echoheaders
      template:
        metadata:
          labels:
            app: echoheaders
        spec:
          containers:
          - name: echoheaders
            image: k8s.gcr.io/echoserver:1.10
            ports:
            - containerPort: 8443
    

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

kubectl apply -f my-deployment.yaml
    

Service を作成する

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

apiVersion: v1
    kind: Service
    metadata:
      annotations:
        cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
      name: echoheaders
      labels:
        app: echoheaders
    spec:
      type: NodePort
      ports:
      - port: 443
        targetPort: 8443
        protocol: TCP
        name: my-port
      selector:
        app: echoheaders
    

このマニフェストを my-service.yaml という名前のファイルに保存して Service を作成します。

kubectl apply -f my-service.yaml
    

Service を表示します。

kubectl get service echoheaders --output yaml
    

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

apiVersion: v1
    kind: Service
    metadata:
      annotations:
        cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
        ...
      labels:
        app: echoheaders
      name: echoheaders
      ...
    spec:
      clusterIP: 10.39.251.148
      ...
      ports:
      - name: my-port
        nodePort: 30647
        port: 443
        protocol: TCP
        targetPort: 8443
      selector:
        app: echoheaders
      ...
      type: NodePort
    ...
    

この演習では、Service について次の項目を把握することが重要です。

  • Service のタイプは NodePort です。これは Service の必須タイプで、Ingress に関連付けられます。

  • app: echoheaders というラベルを持つすべての Pod は Service のメンバーです。これは、selector フィールドで指定されています。

  • Service にはポートが 1 つあり、その名前は my-port です。cloud.google.com/app-protocols アノテーションは、my-port が HTTP/2 プロトコルを使用する必要があることを指定します。

  • TCP ポート 443 のサービスに向かうトラフィックは、いずれかのメンバー Pod の TCP ポート 8443 にルーティングされます。これは、porttargetPort フィールドで指定されています。

Ingress を作成する

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

apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: echomap
    spec:
      backend:
        serviceName: echoheaders
        servicePort: 443
    

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

kubectl apply -f my-ingress.yaml
    

Kubernetes Ingress コントローラが HTTP(S) ロードバランサを構成するまで数分かかります。構成が完了したら Ingress を表示します。

kubectl get ingress echomap --output yaml
    

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

kind: Ingress
    metadata:
      ...
      name: echomap
      ...
    spec:
      backend:
        serviceName: echoheaders
        servicePort: 443
    status:
      loadBalancer:
        ingress:
        - ip: 203.0.113.2
    

この演習では、Ingress について次の項目を把握することが重要です。

  • 受信トラフィックの IP アドレスは loadBalancer:ingress の下に表示されます。

  • 受信リクエストは、echoheaders Service のメンバーである Pod にルーティングされます。この演習では、メンバー Pod に app: echoheaders というラベルが付いています。

  • リクエストは、echoheaders Service マニフェストで指定されているターゲット ポート上の Pod にルーティングされます。この演習では、Pod のターゲット ポートは 8443 です。

ロードバランサが HTTP/2 をサポートしていることを確認する

gcloud

  1. バックエンド サービスを一覧表示します。

    gcloud compute backend-services list
        
  2. バックエンド サービスの説明を設定します。

    gcloud beta compute backend-services describe backend-service-name --global
        

    backend-service-name はバックエンド サービスの名前です。

  3. 出力で、プロトコルが HTTP/2 になっていることを確認します。

    backends:
        ...
        description: '{...,"kubernetes.io/service-port":"443","x-features":["HTTP2"]}'
        ...
        kind: compute#backendService
        loadBalancingScheme: EXTERNAL
        protocol: HTTP2
        ...
        

Console

  1. Google Cloud Console で [負荷分散] ページに移動します。

    [負荷分散] ページに移動

  2. [名前] で、ロードバランサを探します。

    Google Cloud Console に表示される HTTP ロードバランサのスクリーンショット(クリックして拡大)
  3. バックエンド サービスを表示するには、ロードバランサの名前をクリックします。

  4. バックエンド サービスのエンドポイント プロトコルHTTP/2 であることを確認します。

    Google Cloud Console に表示される HTTP/2 バックエンド サービスのスクリーンショット(クリックして拡大)

サービスを呼び出す

ロードバランサとバックエンド サービスが構成されるまで数分待ちます。ブラウザのアドレスバーにロードバランサの外部 IP アドレスを入力します。

ロードバランサから Pod へのリクエストに関する情報が出力に表示されます。

Hostname: echoheaders-7886d5bc68-xnrwj
    ...
    Request Information:
      ...
      method=GET
      real path=/
      query=
      request_version=2
      request_scheme=https
      ...

    Request Headers:
      ...
      x-forwarded-for=[YOUR_IP_ADDRESS], 203.0.113.2
      x-forwarded-proto=http
    ...
    

この演習では、上記の出力について次の項目を把握することが重要です。

  • request_version=2 は、ロードバランサと Pod の間のリクエストで HTTP/2 が使用されたことを示します。

  • x-forwarded-proto=http は、ユーザーとロードバランサの間のリクエストで HTTP/2 ではなく HTTP 1.1 が使用されたことを示します。

次のステップ

  • Ingress で HTTP 負荷分散を設定する。

  • Ingress を使用して Ingress アプリケーションの静的 IP とドメイン名を構成する。

  • Ingress ロードバランサの SSL 証明書を構成する。

  • 複数のリージョンに存在する複数の Google Kubernetes Engine クラスタで実行されるアプリケーションがある場合は、マルチクラスタ Ingress を構成して、ユーザーに最も近いリージョンのクラスタにトラフィックをルーティングする。