Cloud Service Mesh コントロール プレーンのリビジョン

このページでは、コントロール プレーンのリビジョンの仕組みと、それを使用してサービス メッシュのアップグレード(およびロールバック)を安全に行う方法について説明します。

サービス メッシュ インストールの基礎

Cloud Service Mesh のインストールは、大きく分けて 2 つのフェーズから構成されます。

  1. まず、asmcli ツールを使用してクラスタ内コントロール プレーンをインストールします。コントロール プレーンは、メッシュ構成を管理する一連のシステム サービスで構成されます。

  2. 次に、特殊なサイドカー プロキシを環境全体にデプロイして、各ワークロードとネットワーク間の通信をインターセプトします。プロキシはコントロール プレーンと通信して構成を取得します。これにより、ワークロードを変更せずに、メッシュ間のトラフィック(データプレーン トラフィック)を誘導および制御できます。

    プロキシをデプロイするには、自動サイドカー インジェクション(自動挿入)というプロセスを使用して、各ワークロード Pod で追加のサイドカー コンテナとしてプロキシを実行します。ワークロードのデプロイに使用する Kubernetes マニフェストを変更する必要はありませんが、名前空間にラベルを追加して Pod を再起動する必要があります。

リビジョンを使用してメッシュを安全にアップグレードする

トラフィックの制御機能は、サービス メッシュを使用する主なメリットの 1 つです。 たとえば、アプリケーションを本番環境に最初にデプロイするときに、トラフィックを新しいバージョンのアプリケーションに段階的にシフトできます。アップグレード中に問題が検出された場合、トラフィックを元のバージョンに戻すことができるため、リスクの低い方法でロールバックできます。この手順はカナリア リリースと呼ばれ、これにより新しいデプロイに伴うリスクが大幅に軽減されます。

カナリア アップグレードでは、コントロール プレーンのリビジョンを使用して、既存のコントロール プレーンと一緒に新しいコントロール プレーンとその構成をインストールします。インストーラは、新しいコントロール プレーンを識別するためにリビジョンという文字列を割り当てます。まず、サイドカー プロキシが以前のバージョンのコントロール プレーンから構成を受信します。名前空間または Pod のラベルを新しいコントロール プレーンのリビジョンに付けることで、ワークロードを新しいコントロール プレーンに段階的に関連付けます。新しいリビジョンで名前空間または Pod に名前を付けたら、ワークロード Pod を再起動します。新しいサイドカーが自動挿入され、その構成を新しいコントロール プレーンから受け取ります。問題がある場合は、ワークロードを元のコントロール プレーンに関連付けることでロールバックできます。

自動挿入の仕組み

自動挿入では、アドミッション コントロールと呼ばれる Kubernetes 機能を使用します。新たに作成された Pod を監視するために、変更用アドミッション Webhook が登録されます。Webhook は、特定のラベルを持つ Namespace にデプロイされている Pod のみと一致するように、Namespace セレクタを使用して構成されています。Pod が一致すると、Webhook がコントロール プレーンから提供されたインジェクション サービスを利用して、Pod の変更済みの新しい構成を取得します。これには、サイドカーの実行に必要なコンテナとボリュームが含まれます。

サイドカー インジェクタ

  1. インストール中に Webhook 構成が作成されます。Webhook は Kubernetes API サーバーに登録されます。
  2. Kubernetes API サーバーは、Webhook namespaceSelector に一致する名前空間で Pod のデプロイを監視します。
  3. 名前空間にラベルが付けられ、namespaceSelector で照合されます。
  4. 名前空間にデプロイされた Pod が Webhook をトリガーします。
  5. コントロール プレーンが提供する inject サービスは、Pod 仕様を変更してサイドカーを自動挿入します。

リビジョンとは

自動挿入に使用されるラベルは、他のユーザー定義の Kubernetes ラベルに似ています。ラベルは基本的に、タグ付のコンセプトをサポートするために使用できる Key-Value ペアです。ラベルはタグ付けやリビジョンに広く使用されています。(例: Git タグ、Docker タグ、Knative のリビジョン)。

現在の Cloud Service Mesh のインストール プロセスでは、インストール済みのコントロール プレーンをリビジョン文字列でラベル付けできます。インストーラは、すべてのコントロール プレーン オブジェクトにリビジョンをラベル付けします。Key-Value ペアのキーは istio.io/rev です。クラスタ内コントロール プレーンの場合、istiod Service と Deployment には通常 istio.io/rev=asm-1233-2 のようなリビジョン ラベルがあります。ここで、asm-1233-2 は Cloud Service Mesh のバージョンを表します。リビジョンはサービス名の一部になります(例: istiod-asm-1233-2.istio-system)。

自動挿入を有効にするには、コントロール プレーンのリビジョン ラベルと一致するリビジョンの名前空間を追加します。たとえば、リビジョン istio.io/rev=asm-1233-2 のコントロール プレーンは、ラベル istio.io/rev=asm-1233-2 の名前空間の Pod を選択し、サイドカーを挿入します。

カナリア アップグレード プロセス

リビジョン ラベルを使用すると、クラスタ内コントロール プレーンのカナリア アップグレードとロールバックを実行できます。

カナリア アップグレード

以下の手順ではプロセスについて説明します。

  1. 既存の Cloud Service Mesh またはオープンソースの Istio インストールから始めます。名前空間でリビジョン ラベルと istio-injection=enabled ラベルのどちらを使用していても問題ありません。
  2. 新しいバージョンのコントロール プレーンをインストールする場合は、リビジョン文字列を使用します。リビジョン文字列により、既存のバージョンと一緒に新しいコントロール プレーンがインストールされます。新しいインストールには、特定のリビジョン ラベルで名前空間を監視するように構成された namespaceSelector を使用した新しい Webhook 構成が含まれています。
  3. サイドカー プロキシを新しいコントロール プレーンに移行するには、Namespace から古いラベルを削除し、新しいリビジョン ラベルを追加してから、Pod を再起動します。Cloud Service Mesh でリビジョンを使用する場合は、istio-injection=enabled ラベルの使用を停止する必要があります。リビジョンを使用したコントロール プレーンは、リビジョン ラベルがあっても、istio-injection のラベルが付いた名前空間内の Pod を選択しません。新しいコントロール プレーンの Webhook は、Pod にサイドカーを挿入します。
  4. アップグレードされたコントロール プレーンに関連付けられているワークロードを十分にテストし、アップグレードをロールアウトするか、元のコントロール プレーンにロールバックします。

Pod を新しいコントロール プレーンに関連付けた後に、既存のコントロール プレーンと Webhook がインストールされます。古い Webhook は、新しいコントロール プレーンに移行された Namespace の Pod には影響しません。新しいリビジョン ラベルを削除し、元のラベルを追加して Pod を再起動することで、Namespace 内の Pod を元のコントロール プレーンにロールバックできます。アップグレードが完了したことを確認したら、古いコントロール プレーンを削除できます。

変更用 Webhook 構成の詳細

自動サイドカー インジェクションの Webhook の変更を理解するため、ご自身で構成を確認してください。次のコマンドを使用します。

kubectl -n istio-system get mutatingwebhookconfiguration -l app=sidecar-injector -o yaml

インストールしたコントロール プレーンごとに個別の構成が表示されます。リビジョンベースのコントロール プレーンの名前空間セレクタは次のようになります。

 namespaceSelector:
    matchExpressions:
    - key: istio-injection
      operator: DoesNotExist
    - key: istio.io/rev
      operator: In
      values:
      - asm-1233-2

セレクタは、実行している Cloud Service Mesh または Istio のバージョンによって異なります。istio-injection ラベルが付いていない限り、このセレクタは特定のリビジョン ラベルを持つ Namespace に一致します。

セレクタに一致する名前空間に Pod がデプロイされると、その Pod の仕様はミューテーションのためにインジェクタ サービスに送信されます。呼び出されるインジェクタ サービスは次のとおりです。

     service:
        name: istiod-asm-1233-2
        namespace: istio-system
        path: /inject
        port: 443

サービスは、コントロール プレーンによって inject URL パスのポート 443 で公開されます。

rules セクションでは、Webhook を Pod の作成に適用するように指定します。

   rules:
    - apiGroups:
      - ""
      apiVersions:
      - v1
      operations:
      - CREATE
      resources:
      - pods
      scope: '*'