CI/CD と Azure Arc 対応 Kubernetes での GitOps の原則

クラウドネイティブ構造である Kubernetes には、デプロイと運用にクラウドネイティブのアプローチが必要です。 GitOps では、Git リポジトリに保存されるファイルで、アプリケーションベースのデプロイの目的の状態を宣言します。 アプリケーションには、実行する必要がある Kubernetes オブジェクトがあります。これには、Deployments、Horizontal-Pod-Autoscalers、Services、ConfigMaps が含まれます。 Kubernetes オペレーターは、クラスターで実行され、各クラスターの状態が、Git リポジトリで宣言されている目的の状態になるように継続的に調整します。 これらのオペレーターは、Git リポジトリからファイルを取得し、クラスターに対して目的の状態を適用します。 また、オペレーターは、クラスターが目的の状態を継続的に維持できるようにします。

GitOps を実装すると、以下が実現します。

  • Kubernetes クラスターの状態と構成の全体的な可視性が向上します。
  • 誰が、いつ、どのような理由で変更を行ったかを示す Git 変更履歴を使用して、クラスターへの変更を簡単に監査でき、バージョン履歴を確認できます。
  • クラスターに対して発生する可能性がある誤差が自動的に修正されます。
  • Git revert または Git rollback コマンドを使用して、Kubernetes 構成を以前のバージョンにロールバックできます。 Kubernetes の目的のクラスター構成が Git に保存されるため、ディザスター リカバリー シナリオのクラスター デプロイの再作成も迅速で簡単なプロセスになります。
  • クラスターへのデプロイのアクセス許可を付与するサービス アカウントの数を減らすことで、セキュリティを向上させることができます。
  • クラスターにアプリケーションをデプロイするための CI/CD パイプラインを実装できます。

Azure Arc 対応 Kubernetes の GitOps では、一般的なオープンソース ツール セットである Flux を実装した拡張機能が使用されます。 Flux は、クラスターへの GitOps 構成のデプロイを自動化するオペレーターです。 Flux は、一般的なファイル ソース (Git リポジトリ、Helm リポジトリ、バケット) とテンプレートの種類 (YAML、Helm、Kustomize) のサポートを提供します。 Flux は、マルチテナントとデプロイの依存関係管理などの機能もサポートしています。

アーキテクチャ

次の図は、クラスターでの Flux クラスター拡張機能のインストール プロビジョニング、Azure Arc 対応 Kubernetes クラスターでの GitOps 構成プロセス、GitOps フローに焦点を当てた概念参照アーキテクチャを示しています。

Flux v2 クラスター拡張機能のプロビジョニング プロセス:

Diagram that shows Flux extension installation.

GitOps の構成プロセス:

Diagram that shows how to configure GitOps.

アプリケーションの構成を示す GitOps フロー:

Diagram that shows a typical GitOps workflow.

設計上の考慮事項

Azure Arc 対応 Kubernetes への GitOps の実装を計画する場合、次の設計上の考慮事項を確認してください。

構成

Kubernetes クラスターのさまざまな構成レイヤーと、それらのプロビジョニングに関連する責任について検討してください。

構成レイヤー

  • アプリケーションとそれに関連する Kubernetes オブジェクト (Deployment、Service、HPA、ConfigMap リソースなど) をクラスターにデプロイするために必要なアプリケーション構成。 通常、アプリケーション構成は名前空間レベルの GitOps 構成に適用されるため、単一の名前空間内でのみアプリケーション コンポーネントを構成する必要があります。
  • Kubernetes オブジェクト (Namespaces、ServiceAccounts、Roles、RoleBindings など) とその他のクラスター全体のポリシーの作成に関するクラスター全体の構成。
  • イングレス コントローラー、監視とセキュリティのスタック、クラスターに対して動作するさまざまなエージェントなど、クラスター全体のコンポーネント。

役割

  • アプリケーション開発者は、ソース コードのプッシュ、ビルドのトリガー、コンテナー イメージの作成を担当します。
  • アプリケーション オペレーターは、アプリケーション リポジトリ、構成、環境変数、アプリ固有の Helm チャート、Kustomization などの管理を担当します。
  • クラスター オペレーターは、クラスター ベースラインの設定を担当します。 通常、クラスター全体のコンポーネントとポリシーの設定に携わります。 Namespaces、Service Accounts、RoleBindings、CRDs、クラスター全体のポリシー、イングレス コンポーネントなどの一般的なインフラストラクチャ ツールを格納する 1 つ以上の Git リポジトリ ディレクトリを管理します。

リポジトリの構造

Git リポジトリ構造を選択する場合、トレードオフを検討してください。 選択した構造によって、アプリケーションとクラスター全体のコンポーネントを含む Kubernetes クラスターの状態が定義されます。 特定する責任とペルソナに応じて、さまざまなリポジトリ構造オプションに必要なコラボレーションやチームの独立性を考慮することが重要です。

コード リポジトリには任意のブランチ戦略を使用できます。この戦略が継続的インテグレーション (CI) プロセスでのみ使用されるためです。

GitOps 構成リポジトリについては、組織のビジネス ニーズ、サイズ、ツールに基づいて、次の戦略を検討してください。

  • 単一のリポジトリ (環境ごとのブランチ):
    • 環境を表す各ブランチの Git ポリシーとアクセス許可を最も柔軟に制御できます。
    • Kustomize などのツールが Git ブランチでは機能しないため、環境間で共通の構成を共有できない点が欠点です。
  • 単一のリポジトリ (環境ごとのディレクトリ):
    • Kustomize などのツールを使用して、このアプローチを実装できます。これにより、Kubernetes オブジェクトの基本構成と、基本構成をオーバーライドする環境用の一連の成果物 (パッチなど) を定義できます。
    • このアプローチでは、各環境の重複する YAML ファイルを削減できますが、環境間の構成の分離性も低下します。 リポジトリへの 1 つの変更が、すべての環境に一度に影響する可能性があるため、基本ディレクトリへの変更の影響を十分に理解し、注意して行う必要があります。
  • 複数のリポジトリ (それぞれが特定の目的を果たす):
    • これは、アプリケーション、チーム、レイヤー、またはテナントごとに構成リポジトリを分離するために使用できます。
    • これにより、チームはより独立した制御を行うことができます。ただし、クラスターへのデプロイをより一元的に構成、可視化、制御するために、単一のリポジトリでシステム状態を定義するという原則からは離れることになります。
    • マルチテナントのニーズに合わせて、複数のリポジトリを設定することを検討する必要があります。 ロールベースのアクセス制御 (RBAC) とセキュリティが組み込まれているため、特定の名前空間へのデプロイのみ許可するなど、特定リポジトリに割り当てられたチーム/テナントが適用できる構成を制限できます。

リポジトリを構築するその他の方法については、Flux のガイドに関するページを参照してください。

アプリケーションとプラットフォームの構成

プラットフォーム オペレーターとアプリケーション オペレーターには、Kubernetes 構成を管理するためのいくつかのオプションがあります。

  • デプロイする各 Kubernetes API オブジェクトの YAML 仕様を表す生 Kubernetes YAML ファイルは、単一環境では適切に機能します。 生 YAML ファイルを使用する場合の欠点は、複数の環境を組み込み始めるとカスタマイズが困難になることです。これは、YAML ファイルを複製する必要がある一方で、適切な再利用方法がないためです。
  • Helm は、Kubernetes オブジェクトのパッケージ管理ツールです。 これは、クラスター オペレーターがサードパーティ製の既製アプリケーションをインストールするために使用できる有効なオプションです。 テンプレート化によってテンプレートが増えると管理が複雑になる可能性があるため、内部アプリケーションの構成管理ツールとしてテンプレート化はあまり頻繁に使用しないでください。
    • Helm を使用する場合、Flux には、Kubernetes マニフェストを使用して Helm チャートのリリースを宣言によって管理できる Helm コントローラーが含まれます。 このプロセスを管理するために HelmRelease オブジェクトを作成できます。
  • Kustomize は、Kubernetes ネイティブの構成管理ツールであり、テンプレートを使用しない方法でアプリケーション構成をカスタマイズできます。
    • Kustomize を使用する場合、Flux には Kustomize コントローラーが含まれます。これは、Kubernetes マニフェストで定義され、Kustomize で組み立てられる、インフラストラクチャとワークロードの継続的デリバリー パイプラインの実行に特化されています。 このプロセスを管理するための Kustomization オブジェクトを作成できます。
  • Azure Arc 対応 Kubernetes では、コンポーネントのライフサイクルとサポートを自分で管理する必要がなく、Microsoft が管理およびサポートする使用可能な拡張機能の一覧を使用できます。 これらの拡張機能は、Azure Resource Manager を使用して管理されます。 Azure Key Vault シークレット プロバイダーなど、これらの拡張機能の一部には、オープン ソースの代替手段があります。 拡張機能プロセスの外部でコンポーネントを管理すると、コンポーネントをより詳細に制御できますが、サポートとライフサイクル管理にはより多くのオーバーヘッドが必要になります。

継続的インテグレーションと継続的デリバリー (CI/CD) のフロー

次のセクションでは、アプリケーション パイプラインとコンポーネントの更新プロセスに関する考慮事項を示します。

アプリケーション パイプライン

  • CI プロセスに含める必要があるアプリケーションのビルド、テスト、検証について検討してください。 これには、環境デプロイ用のリリース候補 (RC) を作成するために必要となる、セキュリティ、統合、パフォーマンスに関連するリンティングとテストを含めることができます。
  • 従来のプッシュ デプロイ方法を使用し、デプロイ パイプラインから Kubernetes API を直接呼び出すことで、CI パイプライン内のビルド コンテナー イメージとクラスター内のそのデプロイの間のギャップを埋めることができます。

GitOps リポジトリの構成を手動で変更するのを回避するために、プル要求 (PR) を開くアクセス許可があるサービス アカウントで CD パイプラインを実行することや、新しいコンテナー イメージの変更を構成リポジトリに直接コミットすることができます。 これらの変更により、アプリケーションに必要なすべての YAML オブジェクトをプロビジョニングすることもできます。

次のプロセス図は、GitOps をサポートする変更が組み込まれた従来のアプリケーション CI プロセスを示しています。

Diagram that shows the standard GitOps process.

クラスター全体のコンポーネント更新プロセス

  • クラスター オペレーターはクラスター全体のコンポーネントを管理する必要があるため、アプリケーションとサービスのデプロイに使用される CD パイプラインからは、これは行われない場合が多いです。 変更を一方の環境から他方の環境にスムーズに移せるようにするために、クラスター オペレーター固有の昇格プロセスを定義することを検討してください。
  • Azure Arc 対応 Kubernetes クラスターに同じ GitOps 構成を大規模に適用する必要がある場合は、Azure Policy を適用することを検討してください。この Azure Policy で、Flux 拡張機能を自動的にインストールし、既存の Azure Arc 対応 Kubernetes クラスターに GitOps 構成を適用し、また新しいクラスターが Azure Arc にオンボードされたら、その新しいクラスターにも GitOps 構成を適用します。

構成を更新したら、多くの場合、目的の環境に変更が正常に適用されたか確認する必要があります。 Flux で通知を定義して、CI/CD ツール、メール、または ChatOps ツールと統合し、正常な変更やデプロイの失敗に関するアラートを自動的に送信できます。 デプロイの状態情報は、Azure portal、k8s-configuration CLI、ARM API でも確認できます。

セキュリティに関する考慮事項

Azure Arc 対応 Kubernetes への GitOps の実装を計画する場合、次のセキュリティ上の考慮事項を確認してください。

リポジトリ認証

  • GitOps ではパブリックまたはプライベートの Git リポジトリを使用できますが、Kubernetes の構成は機密事項であるため、SSH キーまたは API キーによる認証を必要とするプライベート リポジトリを使用することをお勧めします。 Kubernetes クラスターがプライベート ネットワークにアクセスできる限り、GitOps では、そのプライベート ネットワーク内からしかアクセスできない Git リポジトリも処理されます。ただし、このセットアップでは、Azure Repos や GitHub などのクラウドベースの Git プロバイダーを使用する機能も制限されます。
  • HTTPS プロトコルと SSH プロトコルの両方によって、ソース管理ツールへの接続に使用できる安全で信頼できる接続が提供されます。 また多くの場合、HTTPS は設定が簡単で、使用されるポートもファイアウォールで開く必要がありません。

リポジトリとブランチのセキュリティ

  • 構成リポジトリでブランチのアクセス許可とポリシーを設定します。 Git リポジトリは Kubernetes デプロイの中心となるため、ブランチ内のコードを読み取って更新できるユーザーを制御するアクセス許可を設定すること、およびチームのコードの品質と変更を管理するポリシーを実装することが重要です。 これを行わない場合、GitOps ワークフローで、組織の標準に準拠していないコードが配布される可能性があります。
  • プル要求 (PR) パイプラインでは、必要に応じて、ブランチ ポリシーを使用して YAML 構成を検証することやテスト環境をデプロイすることができます。 ゲートを使用して、構成エラーを排除でき、デプロイのセキュリティと信頼性を向上させることができます。
  • アクセス許可を割り当てる場合、リポジトリ読み取りアクセス権、PR 作成アクセス権、PR 承認アクセス権が必要なのは、組織内のどのユーザーであるか考慮してください。

シークレットの管理

  • プレーン テキストや base64 でエンコードされたシークレットは Git リポジトリに保存しないでください。 代わりに、Azure Key Vault などの外部シークレット プロバイダーを使用することを検討してください。 シークレット ストア CSI ドライバーの Azure Key Vault プロバイダーを使用すると、CSI ボリュームを使用して Azure Kubernetes Service (AKS) クラスターに Azure Key Vault をシークレット ストアとして統合できます。 このサービスは、Azure Arc 対応 Kubernetes 拡張機能を通じて利用できます。 HashiCorp Vault は、サード パーティーが管理する代替のシークレット プロバイダーです。
  • シークレットを管理するもう 1 つの方法は、公開キーと秘密キーの概念から動作する Bitnami のシールド シークレットを使用する方法です。 これにより、オペレーターは、公開キーを使用して一方向で暗号化されたシークレットを Git に保存できます。このシークレットは、クラスターで実行される SealedSecrets コントローラーで使用される秘密キーを通じてのみ複合化できます。

設計の推奨事項

Azure Arc 対応 Kubernetes への GitOps の実装を計画する場合、次の設計上の推奨事項を確認してください。

次の図に含まれる参照アーキテクチャは、Azure Arc 対応 Kubernetes の Flux 拡張機能を使用して GitOps プロセスを実装するために必要な責任、リポジトリ、パイプラインを示しています。

Diagram that shows a GitOps Reference flow.

リポジトリ

この設計には、次の 3 つの Git リポジトリが含まれます。

  • アプリケーション コード リポジトリ
    • このリポジトリには、アプリケーション コード、パイプライン定義、構成スクリプトが保存されます。
    • 理解しやすく、実行時間の長い不要なブランチの数を制限する開発ブランチ戦略を使用してください。
  • アプリケーション構成リポジトリ
    • このリポジトリには、ConfigMaps、Deployments、Services、HPA オブジェクトなどの Kubernetes オブジェクトを含むアプリケーション構成が保存されます。 このリポジトリは、アプリケーションごとに異なるディレクトリを使用した構造にします。 Flux により、このリポジトリとターゲット ブランチからクラスターに変更が同期されます。
    • アプリケーション開発者やオペレーターが環境ごとに初期構成を簡単に作成できるツールを組み込んでください。 アプリケーション オペレーターは、構成を簡素化するために、Helm などのパッケージ マネージャーや Kustomize などの構成ツールを使用する Kubernetes 固有のアプリケーション構成を定義する必要があります。
    • 各環境の種類を表すブランチを作成します。 これにより、非運用環境や運用環境など、各特定環境に対する変更をきめ細かく制御できます。
    • アプリケーションを特定の名前空間にデプロイする場合、GitOps 構成内の名前空間スコープ機能を使用して、特定の名前空間のみに構成を適用します。
  • クラスター全体の構成リポジトリ
    • クラスター オペレーターの管理のために、イングレス コントローラー、名前空間、RBAC、監視、セキュリティ スタックなどのクラスター全体のコンポーネントを定義します。 Flux により、このリポジトリとターゲット ブランチからクラスターに変更が同期されます。
    • このリポジトリは、コンポーネントごとに異なるディレクトリを使用した構造にします。
    • 各環境の種類を表すブランチを作成します。 これにより、非運用環境や運用環境など、各特定環境に対する変更をきめ細かく制御できます。
    • クラスター オペレーターは、構成を簡素化するために、Helm などのパッケージ マネージャーや Kustomize オーバーレイなどの構成ツールを使用する必要があります。

CI/CD と構成の更新プロセス

CI/CD とコンテナー イメージの更新

  • CI パイプライン
    • 開発チームは、アプリケーションのビルド、リンティング、テスト、コンテナー レジストリへのプッシュを含むプロセスを通じて CI パイプラインを定義する必要があります。
  • CD パイプライン
    • アプリケーション構成リポジトリに対する変更を対象としたスクリプトを実行する CD パイプラインを作成します。 このスクリプトで、ターゲット環境が元の一時ブランチを作成し、イメージ タグのバージョンに変更を加え、その変更をコミットし、ターゲット環境ブランチに対するプル要求を開きます。 この CD パイプラインでは、適切な GitOps 構成リポジトリとブランチをターゲットとする適切な環境変数を含む環境ステージを使用できます。
    • すべての環境への不要なプル要求を制限するために、環境ステージに対して手動承認手順を定義します。
  • 環境のピア レビューまたは承認を強制するために、アプリケーション構成リポジトリでブランチ ポリシーを有効にします。 これには、必要なレビューの最小数や下位の環境の自動承認を含めることができます。 また、組織の標準を満たすために、必要に応じて、サード パーティによる統合と承認も検討してください。

クラスター全体とアプリケーションの構成の更新

  • クラスター オペレーターとアプリケーション オペレーターはそれぞれ、それぞれの構成リポジトリで構成を定義します。 これらのユーザーは、構成をプッシュするためのパイプライン ツールを必要としません。 代わりに、ネイティブの Git コミットと PR プロセスを使用して構成を定義し、環境を表すブランチに変更をプッシュします。
  • 新しい構成の定義では、最初に開発などの下位環境で構成を定義し、その後、マージとプル要求を使用して上位環境に昇格します。 必要に応じて、特定環境に固有の構成の更新をチェリーピックします。

フィードバックとアラート

  • GitOps 構成を同期できないとき、またはエラーがスローされたときにアラートを生成するように Flux 通知を構成します。 アプリケーション オペレーターは、どの時点でアプリケーションのデプロイが成功し、正常であるか判別するために、アラートを構成する必要があります。 クラスター オペレーターは、どの時点でクラスター全体のコンポーネントの調整が失敗したか、およびどの時点で Git リポジトリとの同期で問題が発生したか判別するために、アラートを構成する必要があります。
  • GitOps コネクタを実装して、Flux エージェントからのフィードバックを CI/CD ツールに統合します。

セキュリティに関する推奨事項

  • Azure Arc 対応 Kubernetes クラスターのガバナンスとセキュリティに関する推奨事項を確認してください。
  • 認証と承認が必要なプライベート Git リポジトリを使用することで、クラスター構成への不必要なアクセスを回避します。認証と承認は、任意の構成リポジトリを定義するために使用できます。
  • Git プロバイダーが SSH プロトコルと SSH キーをサポートしている場合は、それらを使用して Git リポジトリにアクセスします。 アウトバウンド接続の制限のために SSH が使用できない場合、または Git プロバイダーが必要な SSH ライブラリをサポートしていない場合は、専用のサービス アカウントを使用し、Flux で使用するために API キーをそのアカウントに関連付けます。 GitHub を使用するときに SSH の代替手段が必要な場合、認証のための個人用アクセス トークンを作成できます。
  • クラスターの責任に一致するブランチ ポリシーとアクセス許可を構成します。 変更を承認するレビュー担当者の最小数を設定します。
  • YAML の構成と構文を検証し、必要に応じてテスト Kubernetes クラスターをデプロイするように PR パイプラインを構成します。 マージを受け入れる前に、このパイプラインを正常に実行することを必須とするブランチ ポリシーを設定します。
  • シークレット ストア CSI ドライバーの Azure Key Vault プロバイダーを使用してシークレットを実装します。これにより、CSI ボリュームを介して Azure Arc 対応 Kubernetes クラスターに Azure Key Vault をシークレット ストアとして統合できます。
  • Flux 拡張機能では、名前空間とクラスター スコープの構成がサポートされています。 構成によって 1 つの名前空間以外へのアクセスを禁止する場合は、名前空間スコープを選択します。

次のステップ

ハイブリッドおよびマルチクラウドのクラウド導入について詳しくは、次の記事を参照してください。