Config Management を使用した安全なロールアウト

このドキュメントでは、クラスタ運用者とプラットフォーム管理者が Config Management を使用して複数の環境で変更を安全にロールアウトする方法について説明します。Config Management を使用すると、すべての環境に対して同時に影響するエラーを回避できます。

Config Management は、Git リポジトリに保存されたファイルを使用して、単一のクラスタ、マルチテナント クラスタ、マルチクラスタ Kubernetes 構成を管理できるようにします。Config Management は、Config SyncPolicy ControllerConfig Connector の 3 つのテクノロジーを結合したものです。Config Sync は Git リポジトリにあるすべてのファイルの更新を監視し、関連するすべてのクラスタに変更を自動的に適用します。Policy Controller は、クラスタ内のオブジェクトに対してポリシーの管理と適用を行います。Config Connector は、Google Kubernetes Engine(GKE)の顧客リソースを使用して Cloud リソースを管理します。

Config Sync の構成は、たとえば次のようなものを表すことができます。

Config Management は、GKE Enterprise 上に構築するプラットフォーム(セキュリティ エージェント、モニタリング エージェント、証明書マネージャーなど)を実行するために必要な構成、ポリシー、ワークロードをデプロイするのに最適です。

Config Management を使用してユーザー向けのアプリケーションをデプロイすることはできますが、前述の管理ワークロードのリリース ライフサイクルにリリースのライフサイクルをリンクさせることはおすすめしません。代わりに、継続的デプロイツールなど、アプリケーションのデプロイ専用のツールを使用することをおすすめします。そうすることで、アプリケーション チームはリリース スケジュールを自分で管理できます。

Config Management は、多数の要素を管理できる強力なプロダクトであり、大きな影響が発生するエラーを避けるための保護対策が必要になります。このドキュメントでは、保護対策を作成するいくつかのメソッドについて説明します。最初のセクションでは段階的なロールアウトについて説明します。2 番目のセクションではテストと検証を取り上げ、3 番目のセクションでは、Policy Controller を使用して保護対策を作成するメソッドを説明します。4 番目のセクションでは、Config Management のデプロイをモニタリングするメソッドを説明します。

完全な Config Management プロダクトではなく Config Sync のみを使用している場合でも、このドキュメントで説明する方法の大部分を使用できます。完全版の Config Management プロダクトを使用しない場合で、ポリシー コントローラに関連するメソッドを実装したい場合、Gatekeeper を使用することで実現できます。ただし、Google Cloud Console の Config Management 構成の更新をはじめとして、Google Cloud Console の Config Management ページに依存しているメソッドは適用外です。このドキュメントで説明するいくつかのメソッドを同時に使用することもできます。次のセクションでは、同時使用が可能なメソッドを表にまとめています。

Config Management を使用した段階的なロールアウトの実装

GKE Enterprise ユーザーによく見られるマルチクラスタ環境では、すべてのクラスタに対して構成変更を同時適用することは推奨されません。クラスタごと(または、アプリケーション間の境界として名前空間を使用している場合は名前空間ごと)の段階的なロールアウトは、エラーの影響範囲が少なくなるため、はるかに安全です。

Config Management を使用して段階的なロールアウトを実装するメソッドを以下に示します。

  • Git commit またはタグを使用して、クラスタに手動で変更を適用する。
  • Git ブランチを使用して、変更がマージされたときに変更を自動的に適用する。クラスタのグループごとに異なるブランチを使用できます。
  • ClusterSelector オブジェクトと NamespaceSelector オブジェクトを使用して、変更をクラスタまたは名前空間のサブグループに選択的に適用する。

段階的ロールアウトのすべてのメソッドにはメリットとデメリットがあります。次の表に、同時使用が可能なメソッドを示します。

X は Y と同時使用可能か? Git commit またはタグ Git ブランチ クラスタ セレクタ 名前空間セレクタ
Git commit またはタグ 同時使用不可 互換 互換
Git ブランチ 同時使用不可 互換 互換
クラスタ セレクタ 互換 互換 互換
名前空間セレクタ 互換 互換 互換

次のディシジョン ツリーを使用すると、段階的ロールアウト・メソッドの 1 つを使用するタイミングを決定できます。

ロールアウト メソッドのディシジョン ツリー

Git commit またはタグを使用する

他の段階的なロールアウト方法と比較すると、Git commit またはタグを使用する方法は最も制御しやすく、最も安全な方法です。コンソールの [Config Management] ページを使用して、複数のクラスタを同時に更新できます。この方法は、変更をクラスタごとに 1 つずつ適用し、変更のタイミングを厳密に制御する場合に使用します。

この方法では、各クラスタを Config Management リポジトリの特定のバージョン(commit またはタグ)に「固定」します。この方法は、Git commit をコンテナ イメージ タグとして使用するに似ています。このメソッドを実装するには、RootSync または RepoSync カスタム リソースspec.git.revision フィールドに commit、タグ、またはハッシュを指定します。

Kustomize などのツールを使用して RootSync または RepoSync カスタム リソースを管理すると、変更のロールアウトに必要な手作業を削減できます。このようなツールを使用すると、revision パラメータを最初に 1 か所で変更するだけで、新しい RootSync または RepoSync カスタム リソースを、選択した順序とペースで複数のクラスタに選択的に適用できます。

また、Config Sync ではなく Config Management を使用している場合は、Google Cloud コンソールの [Config Management] ページにもアクセスできます。このページでは、同じフリートに属する複数のクラスタの revision パラメータを同時に更新できます。Config Management の構成を更新する自動システムを使用している場合、コンソールを使用してこの構成を変更することはおすすめできません。

たとえば、次の RootSync の定義は、1.2.3 タグを使用するよう Config Management を構成します。

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  sourceType: git
  sourceFormat: unstructured
  git:
    repo: git@example.com:anthos/config-management.git
    revision: 1.2.3
    auth: ssh

この構成をクラスタに適用すると、Config Management は example.com:anthos/config-management.git リポジトリの 1.2.3 タグを使用します。

クラスタを更新するには、spec.git.revision フィールドをクラスタの新しい値に変更します。これにより、更新するクラスタと更新のタイミングを定義できます。変更をロールバックする必要がある場合は、spec.git.revision フィールドを元の値に戻します。

次の図に、このメソッドのロールアウト プロセスを示します。まず Config Management リポジトリに変更を commit してから、すべてのクラスタで RootSync 定義を更新します。

Git commit とタグのロールアウト プロセス

今回の変更に伴い、次のご対応をおすすめします。

  • タグではなく Git commit ID を使用します。Git の機能によって、Git commit ID が絶対に変更されないことが保証されます。たとえば、git push --force は、Config Management が使用している commit を変更できません。このアプローチは、監査目的やログでどの commit を使用しているか追跡する際に有効です。また、タグとは異なり、ID を commit する特別な手順はありません。
  • GitLab を使用していて Git commit ID の代わりに Git タグを使用する場合、タグが移動または削除されないようにタグを保護してください。他の主要な Git ソリューションには、この機能はありません。
  • 複数のクラスタを同時に更新する場合、Config Management のコンソール ページで更新できます。複数のクラスタを一度に更新するには、それらが同じフリートの一部であること(かつ同じプロジェクトに属していること)が必要です。

Git ブランチを使用する

Git リポジトリにマージされた変更を即座にクラスタに適用する必要がある場合は、commit やタグではなく Git ブランチを使用するように Config Management を構成します。このメソッドでは、Git リポジトリに有効期間が長い複数のブランチを作成し、別のクラスタで Config Management を構成してその構成を異なるブランチから読み取るようにします。

たとえば、単純なパターンは 2 つのブランチで構成されます。

  • 非本番環境クラスタ用の staging ブランチ。
  • 本番環境クラスタ用の master ブランチ。

非本番環境クラスタの場合、spec.git.branch フィールドを staging に設定して RootSync または RepoSync オブジェクトを作成します。本番環境クラスタの場合、spec.git.branch パラメータを master に設定して RootSync または RepoSync オブジェクトを作成します。

たとえば、次の RootSync の定義では、master ブランチを使用するように Config Management を構成します。

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-management-system
spec:
  git:
    repo: git@example.com:anthos/config-management.git
    branch: master
    auth: ssh

次の図に、このメソッドのロールアウト プロセスを示します。

Git ブランチのロールアウト プロセス

このパターンは、3 つ以上のブランチを使用するか、環境以外のものにマッピングされているブランチを使用して、特定のニーズに適応できます。変更をロールバックする必要がある場合は、git revert コマンドを使用して、同じブランチに新しい commit を作成し、前の commit から元に戻します。

今回の変更に伴い、次のご対応をおすすめします。

  • 複数のクラスタを扱う場合、少なくとも 2 つの Git ブランチを使用して、本番環境クラスタと非本番環境クラスタを区別できるようにします。
  • ほとんどの Git ソリューションでは、保護されたブランチ機能を使用して、ブランチの削除や未確認の変更を防ぐことができます。詳細については、GitHubGitLabBitbucket に関するドキュメントをご覧ください。

ClusterSelector オブジェクトと NamespaceSelector オブジェクトを使用する

Git ブランチは、複数のクラスタに段階的に変更をロールアウトして、最終的にすべてのクラスタが同じポリシーを持つようにする場合に適しています。ただし、変更をクラスタのサブセットまたは名前空間のサブセットにのみロールアウトする場合は、ClusterSelector オブジェクトと NamespaceSelector オブジェクトを使用します。これらのオブジェクトには、特定のラベルを持つクラスタまたは名前空間にのみオブジェクトを適用するという類似した目的があります。

例:

  • ClusterSelector オブジェクトを使用すると、コンプライアンスの運用がさまざまに異なるクラスタが置かれている国に応じて、それぞれ異なるポリシーを適用できます。
  • NamespaceSelector オブジェクトを使用すると、内部チームの名前空間と外部コントラクタの名前空間に異なるポリシーを適用できます。

ClusterSelector オブジェクトと NamespaceSelector オブジェクトを使用して、次のような高度なテストとリリースのメソッドを実装することもできます。

  • ポリシーのカナリア リリース。ポリシーの影響を調査するために長時間にわたって、少数のクラスタと名前空間に新しいポリシーをデプロイします。
  • A/B テスト。同じポリシーの異なるバージョンを異なるクラスタにデプロイしてポリシー バージョンの影響を調査し、デプロイ先に最適なものを選択します。

たとえば、複数の本番環境クラスタがある組織について考えてみましょう。プラットフォーム チームは、Config Management、ClusterClusterSelector オブジェクトを使用して、canary-prodprod という 2 つの本番環境クラスタのカテゴリをすでに作成しています(ClusterSelectors を使用するを参照)。

プラットフォーム チームは、Policy Controller を使用してポリシーをロールアウトし、各 Namespace にチームラベルのプレゼンスを適用して Namespace がどのチームに属しているかを識別したいと考えています。このポリシーの 1 つのバージョンがすでにドライラン モードでロールアウトされており、今これを少数のクラスタに適用したいと考えています。ClusterSelector オブジェクトを使用して 2 つの異なる K8sRequiredLabels リソースを作成し、異なるクラスタに適用します。

  • K8sRequiredLabels リソースを、enforcementAction パラメータを dryrun に設定した prod タイプのクラスタに適用します。

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: prod
    Spec:
      enforcementAction: dryrun
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    
  • K8sRequiredLabels リソースを、enforcementAction パラメータがない canary-prod タイプのクラスタに適用します。つまり、これでポリシーが実際に適用されます。

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: canary-prod
    spec:
      match:
        kinds:
          - apiGroups: [""]
        kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    

configmanagement.gke.io/cluster-selector アノテーションを使用すると、チームは canary-prod タイプのクラスタに対してのみポリシーを適用し、予期せぬ副作用が本番環境の全体に波及しないようにできます。Policy Controller のドライラン機能の詳細については、制約の作成をご覧ください。

今回の変更に伴い、次のご対応をおすすめします。

  • ClusterSelector オブジェクトと NamespaceSelector オブジェクトは、無期限または長期間にわたって、構成の変更をクラスタまたは名前空間のサブセットにのみ適用する必要がある場合に使用します。
  • セレクタを使用して変更をロールアウトする場合は、慎重に行ってください。Git commit を使用すると、変更はクラスタごとにロールアウトされるため、エラーの影響は一度に 1 つのクラスタに限定されます。ただし、Git ブランチを使用する場合、そのブランチを使用するすべてのクラスタにエラーの影響が及ぶ可能性があります。セレクタを使用すると、一度にすべてのクラスタにエラーの影響が及ぶ可能性があります。

レビュー、テスト、検証の実装

Config Management の利点の一つは、Kubernetes リソース、クラウド リソース、ポリシーなどをすべて宣言型で管理できることです。つまり、ソース管理システムのファイルはリソース(Config Management の場合は Git ファイル)を表します。この特性により、アプリケーションのソースコードにすでに使用している開発ワークフロー(レビューと自動テスト)を実装できます。

レビューを実装する

Config Management は Git に基づいているため、目的の Git ソリューションを使用して Config Management リポジトリをホストできます。Git ソリューションには、Config Management リポジトリに加えられた変更を確認するためのコードレビュー機能が含まれていると考えられます。

Config Management リポジトリへの変更を確認するおすすめの方法は、次のように通常のコードレビューと同じです。

Config Management コードベースは機密性が高いため、Git ソリューションでは可能であれば次の構成を行うことをおすすめします。

これらのさまざまな機能を使用することで、Config Management コードベースに対する各変更リクエストの承認を適用できます。たとえば、各変更について、少なくともプラットフォーム チームのメンバー(複数のクラスタを管理するユーザー)とセキュリティ チームのメンバー(セキュリティ ポリシーの定義と実装を担当するメンバー)によって承認されるように構成できます。

次の対応をおすすめします。

  • Config Management リポジトリにピアレビューを適用し、クラスタが使用する Git ブランチを保護する。

自動テストを実装する

コードベースの作業で、継続的インテグレーションを実装するのは、一般的なベスト プラクティスです。つまり、変更リクエストが作成または更新されたときに実行する自動テストを構成します。自動テストでは、人間が変更リクエストを確認する前に多くのエラーを検出できます。これにより、デベロッパーのフィードバック ループが強化されます。Config Management リポジトリでも、同じツールで同じアイデアを実装できます。

たとえば、最初のうちは新しい変更に対して自動的に nomos vet コマンドを実行することをおすすめします。このコマンドは、Config Management リポジトリの構文が有効かどうかを検証します。このテストは、構成ファイルの検証チュートリアルに沿って Cloud Build を使用して実装できます。Cloud Build は次のオプションと統合できます。

構成ファイルの検証チュートリアルに示されているように、テストはコンテナ イメージを使用して行われます。したがって、Cloud Build だけでなく、コンテナを実行する継続的インテグレーション ソリューションでテストを実装できます。具体的には、こちらの例に沿って GitLab CI で実装できます。このサンプルには、Policy Controller のテストも含まれています。

フィードバック ループをさらに強化する場合は、nomos vet コマンドを Git pre-commit フックとして実行するようユーザーに求める方法があります。注意すべき点としては、一部のユーザーはConfig Management によって管理されている Kubernetes クラスタにアクセスできない可能性があり、ワークステーションから完全な検証を実行できない場合があることです。nomos vet --clusters "" コマンドを実行して、検証をセマンティック チェックとシンタックス チェックに制限します。

必要または役立つと思われるテストを実装できます。Policy Controller を使用する場合、Policy Controller のポリシーに対する変更をテストするで説明されているように、ポリシーに対する変更案の自動テストを実装できます。

次の対応をおすすめします。

  • 継続的インテグレーション パイプラインにテストを実装します。提案されたすべての変更で少なくとも nomos vet コマンドを実行します。

Policy Controller の使用

Policy Controller は、Kubernetes の動的アドミッション コントローラです。Policy Controller をインストールして構成すると、Kubernetes は、ポリシーと呼ばれる事前定義されたルールを遵守していない変更を拒否できます。

次に、Policy Controller のユースケースとして 2 つの例を示します。

  • Kubernetes オブジェクトに特定のラベルを適用する。
  • 特権 Pod が作成されないようにする。

ポリシー テンプレートのライブラリは、最も一般的に使用されているポリシーの実装に使用できますが、Rego という強力な言語を使用して独自のポリシーを記述することもできます。たとえば、Policy Controller を使用して、ユーザーが Ingress で構成できるホスト名を制限できます(詳細については、このチュートリアルをご覧ください)。

Policy Controller は、Config Sync と同様、Config Management プロダクトの一部です。Policy Controller と Config Sync は異なりますが、以下のように相互補完的なユースケースがあります。

  • Config Sync は GitOps スタイルのツールです。これを使用すると、どのような Kubernetes オブジェクトでも、複数のクラスタで同時に作成できる可能性があります。概要で説明したとおり、Config Sync は特にポリシーの管理に便利です。
  • Policy Controller を使用すると、Kubernetes で作成できるオブジェクトのためにポリシーを定義できます。これらのポリシーは、Kubernetes オブジェクト自体であるカスタム リソースに定義します。

上述の機能は、2 つのアプリケーション間の双方向の関係を作り出します。Config Sync を使用すると、Policy Controller によって適用されるポリシーを作成できます。それらのポリシーを使用すると、以下の図に示すように、Config Sync(または他のプロセス)が作成できるオブジェクトを正確に制御できます。

Config Sync と Policy Controller。

Git リポジトリ、Config Sync、Policy コントローラ、Kubernetes、継続的デプロイ(CD)システム、およびユーザーは、全体として次のようなやり取りを行っています。

  • ユーザーは Config Management Git リポジトリを操作して、Kubernetes オブジェクトの作成、更新、削除を行います。
  • Config Sync は、Config Management Git リポジトリから構成を読み取ります。
  • Config Sync は Kubernetes API サーバーとやり取りして、Policy Controller のポリシーを含むオブジェクトを作成します。
  • CD システムも Kubernetes API サーバーとやり取りして、オブジェクトを作成します。Policy Controller に制約を設定できます。ただし、このユースケースでは Config Management を使用することをおすすめします。これにより、制約の管理とテストを一元化できるためです。
  • Kubernetes API サーバーは、Policy Controller からのレスポンスに基づいて、Config Sync と CD システムによるオブジェクトの作成を受け入れるか拒否します。
  • Policy Controller は、Kubernetes API サーバーから読み取ったポリシーに基づいてレスポンスを返します。

次の図は、これらのインタラクションを示しています。

Git リポジトリ、Config Sync、Policy Controller、Kubernetes、継続的デプロイ システム、ユーザー間のインタラクション。

Policy Controller は、審査担当者や自動テストをくぐり抜けたポリシー違反を摘出できるため、Kubernetes クラスタの最後の防御手段であるとみなせます。Policy Controller は、Config Management での審査担当者の数が増えると、有用性が一層高くなります。ソーシャル ローフィング現象により、審査担当者の数が増えるに従い、組織が定義するルールを一貫して適用しようとする審査担当者の意欲が低下するためです。

Policy Controller ポリシーに照らして変更をテストする

Policy Controller を使用する場合、継続的インテグレーション パイプライン(自動テストの実装をご覧ください)にいくつかのステップを追加して、提案された変更をポリシーに照らして自動的にテストできます。テストを自動化することで、変更を提案する人により迅速で目に見えるフィードバックを提供できます。継続的インテグレーション パイプラインのポリシーに照らして変更をテストしない場合、Config Management 同期エラーのアラートを受け取るには、ロールアウトの監視で説明されているシステムに依存する必要があります。ポリシーに照らして変更をテストすると、変更の提案者に対して違反が明確かつ早期に伝わります。

このテストは、CI パイプラインで Policy Controller を使用するのチュートリアルに沿って、Cloud Build に実装できます。前のセクションの自動テストを実装するで説明したように、Cloud Build を GitHub や Bitbucket と統合できます。このテストは GitLab CI を使用して実装することもできます。実装例については、このリポジトリをご覧ください。

次の対応をおすすめします。

  • Policy Controller を使用している場合は、継続的インテグレーション パイプラインのポリシーに照らして提案されている変更を検証します。

ロールアウトをモニタリングする

このドキュメントでカバーするすべてのガードレールが実装されても、エラーが発生することがあります。一般的なエラーには、次の 2 つの種類があります。

  • Config Sync 自体に問題を引き起こさないものの、ワークロードの正常な動作を妨げるエラー、たとえば制約が多すぎてワークロード コンポーネントによる通信を妨げる NetworkPolicy などによるエラー。
  • 無効な Kubernetes マニフェストや、アドミッション コントローラによって拒否されたオブジェクトなど、Config Sync がクラスタに変更を適用できないエラー。上記のエラーのほとんどは、前述の方法で解決できます。

上記の最初の項目で説明したエラーの検出には、各ワークロードの状態を理解する必要があるため、Config Management のレベルでは検出はほぼ不可能です。そのため、このようなエラーは、アプリケーションが正常に機能していないときにアラートを送信する、既存のモニタリング システムによる検出が最適です。

上記の 2 番目の箇条書きに記述されたエラー(すべてのガードレールを実装している場合にはまれなエラー)を検出するには、特定の設定が必要です。デフォルトでは、Config Management のログにエラーが記録されます(デフォルトでは Cloud Logging に表示されます)。エラーは Config Management のコンソール ページにも表示されます。常にモニタリングしているわけではないので、ログやコンソールだけでは通常はエラーを検出できません。エラー検出を自動化する最も簡単な方法は、nomos status コマンドを実行することです。このコマンドは、クラスタにエラーが含まれているかどうかを調べます。

エラー通知用の自動アラートを使用して、より高度なソリューションを設定することもできます。Config Management は、Prometheus 形式で指標を公開します。詳細については、構成管理のモニタリングをご覧ください。

Config Management の指標をモニタリングしたら、gkeconfig_monitor_errors 指標が 0 より大きい場合に通知するアラートを作成します。詳細については、Cloud Monitoring のアラート ポリシーの管理、Prometheus のアラートルールをご覧ください。

Config Management を使用した安全なロールアウトのメカニズムの概要

次の表は、このドキュメントで前述したさまざまなメカニズムをまとめたものです。これらのメカニズムはいずれも独占的なものではありません。これらのメカニズムの一部または全部を、異なる目的に使用することもできます。

機構 最適な用途 不得意分野 使用例
Git commit ID とタグ 特定の Git commit ID またはタグを使用して、適用するクラスタの変更を正確に制御する。 クラスタ間の長期間にわたる違いに、Git commit ID またはタグを使用しない。クラスタ セレクタを使用する。 すべてのクラスタが 12345 Git commit を適用するよう構成されている。テストする新しい commit abcdef を使用して変更する。単一のクラスタの構成を変更して、この新しい commit を使用した変更を検証する。
Git ブランチ 複数の Git ブランチを使用して、同じ変更を複数の環境に段階的にロールアウトする。 クラスタ間での長期間にわたる違いに、複数の Git ブランチを使用しない。ブランチが著しく分岐し、その後のマージが難しくなる。 まず、ステージング ブランチで変更をマージすると、ステージング クラスタが変更を受け取る。
次に、マスター ブランチで変更をマージすると、本番環境クラスタが変更を受け取る。
クラスタ セレクタと名前空間セレクタ クラスタと名前空間の間の長期間にわたる違いに、セレクタを使用する。 複数の環境にまたがる段階的なロールアウトの場合はセレクタを使用しない。変更をステージングで最初にテストし、本番環境にデプロイする場合は、別の Git ブランチを使用する。 アプリケーション チームが開発クラスタには完全アクセス権を必要する一方で本番環境クラスタには読み取り専用アクセス権でよい場合、ClusterSelector オブジェクトを使用して、関連するクラスタにのみ適切な RBAC ポリシーを適用する。
ピアレビュー ピアレビューを使用して、関連するチームが変更を承認していることを確認する。 審査担当者は、すべてのエラー(特に構文エラーなど)を検出できない。 組織は、複数のシステムに影響する構成変更の確認をセキュリティ チームに委任する。セキュリティ チームのメンバーが変更を確認するようにする。
継続的インテグレーション パイプラインの自動テスト 自動テストを使用して、提案された変更のエラーを見つける。 自動テストは審査担当者を完全に置き換えることはできない。両方使用。 提案されたすべての変更に対して nomos vet コマンドを実行すると、リポジトリが有効な Config Management 構成であることを確認できる。
Policy Controller 組織全体にポリシーを適用し、Kubernetes API のサーバーレベルで保護対策を直接実装する。 Policy Controller を使用してポリシーの作成、更新、削除を行うことはできない(これは Config Management のロール)。Policy Controller ができるのはポリシーの適用のみ。 セキュリティ チームは Config Management を使用して Policy Controller 制約を作成し、アプリケーション チームで直接管理されている名前空間であっても、ユーザーが特権コンテナを作成できないようにする。
Policy Controller の制約に照らして変更をテストする Config Management により変更を適用するときに Policy Controller が変更を拒否していないことを確認する。 継続的インテグレーションのパイプラインで Policy Controller の制約に照らして変更をテストしても、クラスタで Policy Controller を有効にしない理由にならない。 すべての名前空間は、「チーム」ラベルで所有者を識別できるようにする必要がある。新しい名前空間を作成しようとするユーザーが、提案された変更にラベルを追加するのを忘れている。担当者が変更を確認する前に、継続的インテグレーション パイプラインがエラーを検出する。
同期エラーを監視する Config Management によりクラスタに実際に変更が適用されたことを確認する。 同期エラーが発生するのは、Config Management が無効なリポジトリを適用しようとしたときや、Kubernetes API サーバーが一部のオブジェクトを拒否した場合に限られる。Policy Controller ポリシーに制約のすべてが成文化されていない場合、ポリシーに含まれない制約に違反するリソースは検出されない。 ユーザーがすべてのテストとレビューをバイパスし、Config Management リポジトリに無効な変更を commit する。この変更はクラスタに適用できない。同期エラーをモニタリングすると、エラー発生時に通知を受ける。

ロールアウト戦略の例

このセクションでは、この記事の後半で紹介したコンセプトを使用して、組織内のすべてのクラスタにまたがるエンドツーエンドのロールアウト戦略を作成できるようにします。この戦略では、開発、ステージング、本番環境用に別々のフリートがあることを前提としています(フリート例 1 - アプローチ 1 を参照)。

このシナリオでは、特定の Git commit を使用して Config Management Git リポジトリと同期するように各クラスタを構成します。特定のフリートに対する変更をデプロイするには、次の 4 つのステップを実行します。

  1. 最初に新しい commit を使用するようにフリート内の 1 つの(「カナリア」)クラスタを更新します。
  2. テストを実行し、ロールアウトをモニタリングすることで、すべてが想定どおりに動作することを検証します。
  3. そのフリートの残りのクラスタをアップデートします。
  4. すべてが想定どおりに動作することを再度検証します。

変更をすべてのクラスタにデプロイするには、フリートごとにこのプロセスを繰り返します。正確に言えばこの方法は、どのブランチのどの Git commit でも適用できます。ただし、次のプロセスを使用して、審査プロセスの早い段階で問題を特定することをおすすめします。

  1. Config Management Git リポジトリで変更リクエストを開いたら、その変更をいずれかの開発クラスタにデプロイします。
  2. 変更リクエストが受け入れられ、メインのブランチでマージされた場合は、前述のようにすべてのフリート全体で完全なデプロイを実行します。

変更によっては特定のフリートのみを対象とすることもありますが、最終的にはすべての変更をすべてのフリートにデプロイすることをおすすめします。この戦略を採用すると、どのフリートをどの commit と同期させる必要があるか追跡するという問題がなくなります。以前のフリートでは適切なテストが不可能なため、本番環境のフリートのみをターゲットとする変更には特に注意してください。たとえば、カナリア クラスタへのデプロイと残りのクラスタへのデプロイとの間で問題が表面化するまでにより多くの時間がかかるということです。

まとめると、エンドツーエンドのデプロイ全体は次のようになります。

  1. 変更リクエストを開きます。
  2. 自動テストと検証が実行され、個別審査が行われます。
  3. ジョブを手動でトリガーして、開発フリートのカナリア クラスタに変更をデプロイします。このクラスタで自動エンドツーエンド テストが実行されます。
  4. 何も問題ない場合は、メインブランチで変更リクエストをマージします。
  5. マージによって自動ジョブがトリガーされ、開発フリートのカナリア クラスタに新しいメインブランチの先端の commit がデプロイされます。自動化されたエンドツーエンド テストがこのクラスタ内で実行されます(ほぼ同時に作成され、マージされた 2 つの変更リクエストの不適合の可能性を検知)。
  6. 次のジョブが順次実行されます(手動でトリガーするか、所定の時間が経過してからユーザーの不具合のレポートを可能にします)。
    1. 開発フリートのすべてのクラスタにデプロイします。
    2. 開発フリートのクラスタ内でテストと検証を実行します。
    3. ステージング フリートのカナリア クラスタにデプロイします。
    4. ステージング フリートのカナリア クラスタでテストと検証を行います。
    5. ステージング フリートのすべてのクラスタにデプロイします。
    6. ステージング フリートのクラスタでテストと検証を実行します。
    7. 本番環境フリートのカナリア クラスタにデプロイします。
    8. 本番環境フリートのカナリア クラスタでテストと検証を行います。
    9. 本番環境フリートのすべてのクラスタにデプロイします。
    10. 本番環境フリートのクラスタでテストと検証を行います。

完全なロールアウト プロセス。

次のステップ