Config Sync を使用した Kubernetes GitOps のベスト プラクティス

このページでは、Config Sync を最大限に活用できるように Kubernetes の CI / CD GitOps パイプラインの計画と設計を行う際の出発点となる情報を提供します。

GitOps 自体は、Kubernetes 構成を大規模に管理する組織とって普遍的なベスト プラクティスです。しかし、そのソリューションの設計には多くの選択肢があります。これらの選択肢の利点とトレードオフを理解することで、将来的なアーキテクチャの再設計を回避できます。

このページで説明するベスト プラクティスをすべて採り入れる必要はありません。どのベスト プラクティスを採用するかは状況によって異なります。このページは、GitOps アーキテクチャを設定する際に十分な情報に基づいて判断できるようにすることを目的としています。

一元化されたプライベート パッケージ リポジトリを使用する

パブリック パッケージまたは内部パッケージ(Helm や kpt など)に一元化されたリポジトリを使用すると、チームでパッケージを見つけやすくなります。Artifact Registry や Git リポジトリなどのサービスを使用できます。

プラットフォーム チームは、アプリケーション チームが一元化されたリポジトリのパッケージのみを使用できるようにするポリシーを実装できます。また、一元化されたリポジトリを審査済みのパッケージ セットとして使用することもできます。

リポジトリへの書き込み権限を付与する対象は少数のエンジニアに限定できます。組織の他のメンバーには読み取りアクセス権を付与できます。パッケージを一元化されたリポジトリにプロモートし、更新をブロードキャストするプロセスを実装することをおすすめします。

次の表に、一元化されたプライベート パッケージ リポジトリを使用する利点と欠点を示します。

利点

欠点

  • 定義された頻度でパブリック パッケージを取り込みます。接続やアップストリームのチャーンによる中断を回避できます。
  • 共有パッケージを確認してスキャンします。
  • 使用中の機能とサポートされている機能を簡単に確認できます。たとえば、一元化されたリポジトリに保存されている標準の Redis デプロイメントをチームで見つけやすくなります。
  • デフォルト値、ラベルの追加、コンテナ イメージ リポジトリなどの内部標準を満たすように、アップストリーム パッケージを変更します。
  • 誰かが一元化されたリポジトリを維持する必要があります。
  • アプリケーション チームで行うプロセスが増えます。

wet リポジトリを作成する

クラスタまたは Namespace の望ましい状態に対応する YAML 出力を使用してリポジトリを作成します。wet リポジトリまたは完全にハイドレートされたリポジトリの変更は、差分を使用して簡単に確認できるようにする必要があります。レビュー プロセスを通じて wet リポジトリのみを変更することをおすすめします(例: GitHub での pull リクエスト)。

次の表に、wet リポジトリを作成する利点と欠点を示します。

利点

欠点

  • 差分を簡単に調べることができます。
  • 構成の望ましい状態を確認するための処理は必要ありません。
  • 完全にハイドレーションされた構成では、繰り返しのある YAML になることがあります。

構成の検証をシフトレフトする

Config Sync が同期を開始して問題をチェックするまで、不要な Git commit と長いフィードバック ループが発生する可能性があります。kubeval などの kpt バリデータの機能を使用すると、構成ファイルがクラスタに適用される前に、さまざまな問題が見つかる可能性があります。

次の表に、構成ファイルの適用前に問題をチェックする利点と欠点を示します。

利点

欠点

  • 変更リクエストで構成の変更を表示すると、エラーがリポジトリに波及することを回避できます。
  • 共有された構成の問題の影響を軽減できます。
  • 問題の捕捉に役立つツールとプロセスを commit プロセスに追加する必要があります。

ブランチではなくフォルダを使用する

構成のバリアントには、ブランチではなくフォルダを使用します。フォルダを使用すると、tree コマンドでバリアントを表示できます。たとえば、ブランチを使用すると、prod ブランチと stage ブランチ間の差分が次の構成変更の対象なのか、stage ブランチと prod ブランチ間に永続的な相違があるのかを判別できません。

次の表に、ブランチではなくフォルダを使用する利点と欠点を示します。

利点

欠点

  • ブランチよりもフォルダのほうが簡単に検出できます。
  • 多くの CLI や GUI ツールでは、フォルダの差分を調べることは可能ですが、Git プロバイダ以外ではブランチの差分取得はあまり一般的ではありません。
  • フォルダの場合は、永続的な違いとプロモートされていない違いをより簡単に区別できます。
  • 1 つの変更リクエストで複数のクラスタと Namespace に変更をロールアウトできます。ブランチの場合は、異なるブランチに対して複数の変更リクエストを行う必要があります。
  • 変更リクエストで同じファイルに構成変更をプロモートすることはできません。

ClusterSelectors の使用を最小限に抑える

ClusterSelectors を使用すると、構成の特定部分をクラスタのサブセットに適用できます。RootSync または RepoSync を構成する代わりに、適用されているリソースを変更したり、クラスタにラベルを追加できます。ただし、ClusterSelectors の数が増えると、クラスタの最終状態の把握が複雑になる可能性があります。

Config Sync を使用すると、複数の RootSyncsRepoSyncs を一度に同期できます。つまり、関連する構成を別のリポジトリに追加して、目的のクラスタに同期できます。

次の表に、ClusterSelectors を使用しない利点と欠点を示します。

利点

欠点

  • クラスタで決定を行うのではなく、クラスタ上の構成をフォルダにまとめるほうが簡単です。
  • 実際にクラスタに適用される内容を理解する際の心理的負担を軽減できます。
  • ラベルを使用するとクラスタにトレイトを簡単に追加できますが、新しい RepoSync を作成するのは複雑です。

Config Sync を使用した Job の管理を回避する

Config Sync は Job を適用できますが、次の理由から Job は GitOps のデプロイには適していません。

  • 変更不可のフィールド: 多くの Job フィールドは変更不可です。変更不可のフィールドを変更するには、オブジェクトを削除してから再作成する必要があります。ただし、オブジェクトをソースから削除しない限り、Config Sync はオブジェクトを削除しません。

  • 意図しない Job の実行: Job を Config Sync と同期した後、対象の Job がクラスタから削除された場合、Config Sync は選択した状態からのずれを考慮し、Job を再作成します。Job の有効期間(TTL)を指定すると、信頼できる情報源から削除しない限り Job は自動的に削除され、Config Sync によって Job が自動的に再作成および再起動されます。Config Sync によって Job が再実行されるため、多くの場合、これは意図した結果ではありません。

  • 調整に関する問題: 通常、Config Sync は適用後にオブジェクトの調整を待機します。ただし、Job は実行を開始すると調整されたとみなされます。つまり、Config Sync は Job の完了を待たずに、他のオブジェクトの適用を続行します。ただし、後で Job が失敗した場合は、調整に失敗したとみなされます。場合によっては、これにより他のリソースの同期がブロックされ、修正するまでエラーが発生する可能性があります。また、同期に成功し、調整のみが失敗する場合もあります。

こうした理由から、Job を Config Sync と同期することはおすすめしません。

ほとんどの場合、Job やその他の状況タスクは、ライフサイクル管理を処理するサービスによって管理する必要があります。この場合、Job 自体ではなく、Config Sync で対象のサービスを管理できます。

次の表に、Config Sync を使用して Job を管理しない場合の利点と欠点を示します。

利点

欠点

  • GitOps の互換性が向上します。Job は変更不可フィールドが原因で、GitOps の宣言型バージョン管理アプローチでは適切に機能しません。
  • 予期しない結果を低減できます。Config Sync によって削除された Job が自動的に再作成され、予期せず実行されるリスクを排除できます。
  • 同期エラーを低減できます。潜在的な同期の競合や、失敗した Job によってトリガーされるエラーを回避できます。
  • 手動での Job 管理。Job を管理するには、別のサービスを見つける必要があります。

非構造化リポジトリを使用する

Config Sync では、リポジトリを編成するための 2 つの構造(非構造化と階層型)がサポートされています。非構造化は、最もニーズに適した方法でリポジトリを整理できるため、推奨されるアプローチです。これに対して、階層型リポジトリは特定の構造を適用します。たとえば、CRD は特定のディレクトリに配置する必要があります。このため、構成ファイルを共有する必要がある場合に問題が生じる可能性があります。たとえば、あるチームが CRD を含むパッケージを公開した場合、そのパッケージを使用する別のチームは CRD を cluster ディレクトリに移動する必要があるため、プロセスのオーバーヘッドが増加します。

次の表に、非構造化リポジトリを使用する利点と欠点を示します。

利点

欠点

  • 共有構成パッケージは、CRD やその他のクラスタ全体の定義が含まれている場合でも再利用できます。
  • リポジトリの構造はチームによって異なるため、プロセスやガイドラインがなければ、フリート全体のツールの実装が困難になる可能性があります。

階層型リポジトリを変換する方法については、階層型リポジトリを非構造化リポジトリに変換するをご覧ください。

コードと構成のリポジトリを分離する

モノリポジトリをスケールアップする場合は、各フォルダに固有のビルドが必要です。通常、コードの担当者とクラスタ構成の担当者では、権限と懸念事項が異なります。コードとリポジトリを分離することにより、リポジトリごとに独自の権限と構造を設定できます。

次の表に、コードと構成リポジトリを分離する利点と欠点を示します。

利点

欠点

  • commit のループ回避できます。たとえば、コード リポジトリに commit すると CI リクエストがトリガーされ、イメージが生成され、コードの commit が必要になる場合があります。
  • アプリケーション コードとクラスタ構成の担当者に異なる権限を付与できます。
  • アプリケーション コードと同じリポジトリにないため、アプリ構成の検出件数が減少します。
  • 多数のリポジトリが存在する場合、管理に時間がかかる場合があります。

別個のリポジトリを使用して変更を分離する

モノリポジトリをスケールアップする場合は、フォルダごとに異なる権限が必要です。このため、リポジトリを分離することで、セキュリティ、プラットフォーム、アプリケーションの構成間にセキュリティ境界を設定できます。また、本番環境と非本番環境でリポジトリを分離することをおすすめします。

次の表に、別個のリポジトリを使用して変更を分離する利点と欠点を示します。

利点

欠点

  • 組織にプラットフォーム、セキュリティ、アプリケーションのチームがある場合、チームごとに変更の頻度と権限が異なります。
  • 権限はリポジトリ レベルで保持されます。CODEOWNERS ファイルを使用すると、組織は読み取り権限を維持したまま、書き込み権限を制限できます。
  • Config Sync は Namespace ごとに複数の同期をサポートしているため、複数のリポジトリを混在させることができます。
  • 多くのリポジトリの管理は独自のタスクになります。したがって、クラスタごとに新しいリポジトリを作成する場合、クラスタの設定 / 破棄の問題にはリポジトリの管理を含める必要があります。

パッケージのバージョンを固定する

Helm と Git のいずれを使用する場合でも、構成パッケージのバージョンは、明示的なロールアウトなしで誤って移動しないように固定する必要があります。

次の表に、パッケージ バージョンを固定する利点と欠点を示します。

利点

欠点

  • パッケージのバージョンが固定されていないと、共有構成の更新で意図しない大きな影響が生じる可能性があります。
  • ロールアウトでは、共有パッケージの更新時にチェックが必要です。

Workload Identity を使用する

GKE クラスタで Workload Identity を有効にすると、Kubernetes ワークロードは安全かつ管理しやすい方法で Google サービスにアクセスできます。

次の表に、Workload Identity を使用する利点と欠点を示します。

利点

欠点

  • シークレットとパスワードに関する複雑さと潜在的な問題を低減します。
  • Google Cloud 以外のサービス(GitHub や GitLab など)は Workload Identity をサポートしていません。

アーキテクチャの概要

大まかには、少なくとも 4 種類のリポジトリが必要になります。

  1. 共有構成が保存されているパッケージ リポジトリ。これは、Artifact Registry に保存されている Helm チャートにすることもできます。
  2. プラットフォーム チームがクラスタと Namespace のフリート全体の構成を保存するプラットフォーム リポジトリ。
  3. アプリケーション構成リポジトリ。
  4. アプリケーション コード リポジトリ。

次の図は、これらのリポジトリのレイアウトを示しています。

パッケージとプラットフォームのリポジトリで推奨されるアーキテクチャ。アプリケーション構成リポジトリとアプリケーション コード リポジトリに向かうフローになっています。

次の図は、アプリケーション コードからアプリケーション構成リポジトリへの構成フローを示しています。開発チームは、アプリケーションとアプリケーション構成のコードをリポジトリに push します。アプリケーションと構成ファイルの両方のコードが同じ場所に保存され、アプリケーション チームがこれらのリポジトリを管理できます。アプリケーション チームはコードをビルドに push できます。

推奨のアプリケーション ビルド。アプリケーション コードとアプリケーション構成がビルドに push されています。

次のステップ