Istio API を使用したゲートウェイのインストールとアップグレード

Cloud Service Mesh では、サービス メッシュの一部としてゲートウェイをデプロイし、管理できます。ゲートウェイでは、メッシュのエッジで動作し、受信または送信 HTTP/TCP 接続を処理するロードバランサを記述します。ゲートウェイは、主に上り(内向き)トラフィックの管理に使用されますが、他の種類のトラフィックを管理するように構成することもできます。

  • Egress ゲートウェイ: Egress ゲートウェイを使用すると、メッシュから外部に送信されるトラフィック専用の Exit ノードを構成できます。これにより、外部ネットワークへのアクセスを許可するサービスを制限できます。また、下り(外向き)トラフィックを安全に制御し、メッシュのセキュリティを強化することもできます。

  • Ingress ゲートウェイ: Ingress ゲートウェイを使用すると、受信 HTTP/TCP 接続を受け取る専用のエントランス ノードを構成できます。

  • East-West ゲートウェイ: East-West トラフィックのプロキシです。サービス ワークロードが異なるネットワーク上のマルチプライマリ メッシュのクラスタ境界を越えて通信できるようにします。デフォルトでは、このゲートウェイは、インターネットに公開されます。

このページでは、ゲートウェイ プロキシをデプロイしてアップグレードするためのベスト プラクティスと、独自の istio-ingressgateway および istio-egressgateway ゲートウェイ プロキシを構成する例について説明します。

ゲートウェイはさまざまな方法でデプロイできます。また、同じクラスタ内で複数のトポロジを使用することもできます。このトポロジの詳細については、Istio ドキュメントのゲートウェイ デプロイ トポロジをご覧ください。

ゲートウェイのデプロイに関するベスト プラクティス

ゲートウェイをデプロイするためのベスト プラクティスは、マネージド データプレーン非マネージド データプレーンのどちらを使用するかによって異なります。

マネージド データプレーンのベスト プラクティス

  1. マネージド データプレーンを有効にします。
  2. マネージド リビジョン ラベルを名前空間に追加します。
  3. コントロール プレーンとゲートウェイを個別にデプロイして管理します。
  4. セキュリティのベスト プラクティスとして、ゲートウェイをコントロール プレーンとは異なる名前空間にデプロイすることをおすすめします。
  5. 自動サイドカー インジェクション(自動インジェクション)を使用して、サービスのサイドカー プロキシを挿入する場合と同様にゲートウェイのプロキシ構成を挿入します。

ベスト プラクティスは次のとおりです。

  • 最新の強化機能とセキュリティ アップデートを使用して、マネージド ゲートウェイを常に最新の状態にします。
  • Cloud Service Mesh が管理するデータプレーンに、ゲートウェイ インスタンスの管理とメンテナンスをオフロードします。

非マネージド データプレーンのベスト プラクティス

  1. コントロール プレーンとゲートウェイを個別にデプロイして管理します。
  2. セキュリティのベスト プラクティスとして、ゲートウェイをコントロール プレーンとは異なる名前空間にデプロイすることをおすすめします。
  3. 自動サイドカー インジェクション(自動インジェクション)を使用して、サービスのサイドカー プロキシを挿入する場合と同様にゲートウェイのプロキシ構成を挿入します。

ベスト プラクティスは次のとおりです。

  • クラスタ全体に対する権限を持つように権限昇格を行わなくても、名前空間管理者がゲートウェイを管理できるようにします。
  • 管理者が、Kubernetes アプリケーションの管理に使用しているデプロイツールやメカニズムを使用して、ゲートウェイのデプロイや管理を行えるようにします。
  • 管理者にゲートウェイ Deployment に対するフルコントロールを許可し、操作を簡単に行えるようにします。新しいアップグレードが利用可能になるか、構成が変更されたときに、管理者が再起動を行うだけで、ゲートウェイ Pod が更新されるようにします。これにより、サービスでサイドカー プロキシを運用する場合と同じ方法でゲートウェイ Deployment を運用できるようになります。

サンプル ゲートウェイをデプロイする

既存のデプロイツールでユーザーをサポートするために、Cloud Service Mesh では、Istio と同じ方法(IstioOperator、Helm、Kubernetes YAML)でゲートウェイのデプロイを行うことができます。どの方法でも同じ結果になります。慣れている方法を選択することもできますが、Kubernetes YAML をおすすめします。こちらのほうが変更が簡単で、ソース制御にハイドレードされたマニフェストを保存できます。

次の手順では、サンプル ゲートウェイをデプロイする方法を示します。

  1. ゲートウェイの名前空間をまだ作成していない場合は作成します。GATEWAY_NAMESPACE は、名前空間に置き換えます。

    kubectl create namespace GATEWAY_NAMESPACE
    
  2. インジェクションの名前空間を有効にします。手順は、コントロール プレーンの実装によって異なります。

    マネージド(TD)

    1. デフォルトのインジェクション ラベルを名前空間に適用します。
    kubectl label namespace GATEWAY_NAMESPACE \
        istio.io/rev- istio-injection=enabled --overwrite
    

    マネージド(Istiod)

    推奨: 次のコマンドを実行して、デフォルトのインジェクション ラベルを名前空間に適用します。

      kubectl label namespace GATEWAY_NAMESPACE \
          istio.io/rev- istio-injection=enabled --overwrite
    

    マネージド Istiod コントロール プレーンを使用している既存のユーザーの場合: デフォルトのインジェクションを使用することをおすすめしますが、リビジョンベースのインジェクションもサポートされています。次の手順を行います。

    1. 利用可能なリリース チャンネルを探すには、次のコマンドを実行します。

      kubectl -n istio-system get controlplanerevision
      

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

      NAME                AGE
      asm-managed-rapid   6d7h
      

      注: 上記のリストに 2 つのコントロール プレーンのリビジョンが表示されている場合は、1 つを削除します。クラスタに複数のコントロール プレーン チャネルを配置することはできません。

      出力で、NAME 列の値は、Cloud Service Mesh バージョンで使用可能なリリース チャンネルに対応するリビジョン ラベルです。

    2. リビジョン ラベルを名前空間に適用します。

      kubectl label namespace GATEWAY_NAMESPACE \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      

    クラスタ内

    推奨: 次のコマンドを実行して、デフォルトのインジェクション ラベルを名前空間に適用します。

      kubectl label namespace GATEWAY_NAMESPACE \
          istio.io/rev- istio-injection=enabled --overwrite
    

    デフォルトのインジェクションを使用することをおすすめしますが、リビジョンベースのインジェクションがサポートされています。 次の手順を使用します。

    1. 次のコマンドを使用して、istiod のリビジョン ラベルを探します。

      kubectl get deploy -n istio-system -l app=istiod -o \
         jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. リビジョン ラベルを名前空間に適用します。次のコマンドで、REVISION_LABEL は前の手順でメモした istiod リビジョン ラベルの値です。

      kubectl label namespace GATEWAY_NAMESPACE \
          istio-injection- istio.io/rev=REVISION_LABEL --overwrite
      
  3. サンプル ゲートウェイの構成ファイルを anthos-service-mesh リポジトリからコピーします。

  4. ディレクトリを samples ディレクトリに変更します。正しいディレクトリにいることを確認するには、ls コマンドを実行してディレクトリの内容を一覧表示し、gateways ディレクトリ(次のステップでアクセスします)と online-boutique ディレクトリがあることを確認します。

  5. Ingress または Egress ゲートウェイをデプロイします。これらは samples/gateways/ ディレクトリにそのままの状態であります。または必要に応じて変更します。

    Ingress

    kubectl apply -n GATEWAY_NAMESPACE -f samples/gateways/istio-ingressgateway
    

    Egress

    kubectl apply -n GATEWAY_NAMESPACE -f samples/gateways/istio-egressgateway
    
  6. Deployment を作成したら、新しいサービスが正常に動作していることを確認します。

    kubectl get pod,service -n GATEWAY_NAMESPACE
    

    次のような内容が出力されていることを確認します。

    NAME                                      READY   STATUS    RESTARTS   AGE
    pod/istio-ingressgateway-856b7c77-bdb77   1/1     Running   0          3s
    
    NAME                           TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
    service/istio-ingressgateway   LoadBalancer   10.24.5.129    34.82.157.6      80:31904/TCP   3s

ゲートウェイ リソースは、他の Kubernetes アプリケーションと同様に管理します。anthos-service-mesh-packages リポジトリのサンプルは、ガイダンスとクイックスタート用です。必要に応じてカスタマイズします。

ゲートウェイ セレクタ

istio-ingressgatewayistio-egressgateway のプロキシにゲートウェイ構成を適用して、メッシュの受信トラフィックと送信トラフィックを管理します。これにより、メッシュ内外に送受信されるトラフィックを指定できます。ゲートウェイ Deployment の Pod のラベルは、ゲートウェイの構成リソースで使用されるため、ゲートウェイ セレクタがこれらのラベルと一致している必要があります。

たとえば、上記の Deployment では、ゲートウェイ Pod に istio=ingressgateway ラベルが設定されます。ゲートウェイ構成をこれらの Deployment に適用するには、同じラベルを選択する必要があります。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: gateway
spec:
  selector:
    istio: ingressgateway
...

ゲートウェイ構成と仮想サービスの例については、Online Boutique サンプル アプリケーションの frontend.yaml をご覧ください。

ゲートウェイをアップグレードする

インプレース アップグレード

ほとんどの場合、インプレース アップグレード パターンに従ってゲートウェイをアップグレードする必要があります。ゲートウェイは Pod インジェクションを利用するため、新しく作成されたゲートウェイ Pod は、バージョンを含む最新の構成で自動的に挿入されます。

ゲートウェイが使用するコントロール プレーンのリビジョンを変更する場合は、ゲートウェイの Deployment に istio.io/rev ラベルを設定できます。これにより、ローリング再起動もトリガーされます。

マネージド コントロール プレーン

マネージド コントロール プレーンのアップグレードは Google が管理しているため、ゲートウェイ Deployment を再起動するだけで、新しい Pod が最新の構成とバージョンで自動的に挿入されます。

kubectl rollout restart deployment istio-ingressgateway \
  -n GATEWAY_NAMESPACE

クラスタ内コントロール プレーン

クラスタ内コントロール プレーンがある場合に同じパターンをゲートウェイに適用するには、ゲートウェイで使用されているコントロール プレーン リビジョンを変更する必要があります。ローリング再起動をトリガーするゲートウェイ Deployment に istio.io/rev ラベルを設定します。必要な手順は、名前空間またはゲートウェイ Pod のリビジョン ラベルを更新する必要があるかどうかによって異なります。

  • インジェクション用の名前空間にラベルを付けた場合は、名前空間の istio.io/rev ラベルに新しいリビジョン値を設定します。

      kubectl label namespace GATEWAY_NAMESPACE \
        istio-injection- istio.io/rev=REVISION \
        --overwrite
    
  • ゲートウェイ Pod に対してのみインジェクションを有効にした場合は、Deployment の istio.io/rev ラベルに新しいリビジョン値を設定します。次の Kubernetes YAML ファイルはその一例です。

    cat <<EOF > gateway-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: istio-ingressgateway
      namespace: GATEWAY_NAMESPACE
    spec:
      selector:
        matchLabels:
          istio: ingressgateway
      template:
        metadata:
          annotations:
            # This is required to tell Cloud Service Mesh to inject the gateway with the
            # required configuration.
            inject.istio.io/templates: gateway
          labels:
            istio: ingressgateway
            istio.io/rev: REVISION
        spec:
          containers:
          - name: istio-proxy
            image: auto # The image will automatically update each time the pod starts.
    EOF
    
    kubectl apply -f gateway-deployment.yaml
    

カナリア アップグレード(高度)

クラスタ内コントロール プレーンを使用していて、新しいコントロール プレーン リビジョンのロールアウトを段階的に行うには、カナリア アップグレード パターンを使用します。複数のバージョンのゲートウェイ Deployment を実行し、トラフィックのサブセットですべてが想定どおりに機能することを確認できます。たとえば、新しいリビジョンであるカナリアをロールアウトする場合は、ゲートウェイ Deployment のコピーを作成し、istio.io/rev=REVISION ラベルを新しいリビジョンと新しい名前に設定します(例: istio-ingressgateway-canary)。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: istio-ingressgateway-canary
  namespace: GATEWAY_NAMESPACE
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  template:
    metadata:
      annotations:
        inject.istio.io/templates: gateway
      labels:
        istio: ingressgateway
        istio.io/rev: REVISION # Set to the control plane revision you want to deploy
    spec:
      containers:
      - name: istio-proxy
        image: auto

この Deployment が作成されると、同じ Service で選択された 2 つのバージョンのゲートウェイが作成されます。

kubectl get endpoints -o "custom-columns=NAME:.metadata.name,PODS:.subsets[*].addresses[*].targetRef.name"

NAME                   PODS
istio-ingressgateway   istio-ingressgateway-788854c955-8gv96,istio-ingressgateway-canary-b78944cbd-mq2qf

アプリケーションが期待どおりに機能していることを確認したら、次のコマンドを実行して、古い istio.io/rev ラベルが設定された Deployment を削除し、新しいバージョンに移行します。

kubectl delete deploy/istio-ingressgateway -n GATEWAY_NAMESPACE

新しいバージョンのゲートウェイでアプリケーションをテストするときに問題が発生した場合は、次のコマンドを実行して、新しい istio.io/rev ラベルが設定された Deployment を削除し、以前のバージョンに戻してください。

kubectl delete deploy/istio-ingressgateway-canary -n GATEWAY_NAMESPACE

詳細構成

ゲートウェイの最小 TLS バージョンを構成する

Cloud Service Mesh の場合、ゲートウェイ サーバーのデフォルトの最小 TLS バージョンは 1.2 です。最小 TLS バージョンは、minProtocolVersion フィールドを使用して構成できます。詳細については、ServerTLSSettings をご覧ください。

サポートされていない機能

TRAFFIC_DIRECTOR コントロール プレーンの実装がある場合、Gateway の次のフィールドまたは値はサポートされていません。

  • AUTO_PASSTHROUGH 値の ServerTLSSettings.TLSmode
  • ServerTLSSettings.verifyCertificateSpki
  • ServerTLSSettings.verifyCertificateHash

ゲートウェイのトラブルシューティング

auto からゲートウェイ イメージを更新できない

ゲートウェイをデプロイまたはアップグレードすると、Cloud Service Mesh が image フィールドにプレースホルダとして auto を挿入します。変更用 Webhook を呼び出すと、Cloud Service Mesh でこのプレースホルダが自動的に実際の Cloud Service Mesh プロキシ イメージに置き換えられます。変更用 Webhook の呼び出しが失敗した場合、auto プレースホルダは残り、コンテナは検出されません。これは通常、名前空間ラベルが正しくないことが原因で発生します。正しい名前空間が構成されていることを確認してから、ゲートウェイを再度デプロイまたはアップグレードしてください。