CI パイプラインでの会社のポリシーに基づくアプリの検証

組織で Anthos Config Management とポリシー コントローラを使用して Anthos クラスタ全体のポリシーを管理している場合は、継続的インテグレーション(CI)パイプラインでアプリのデプロイ構成を検証できます。このチュートリアルでは、この結果を達成する方法について説明します。アプリに CI パイプラインを構築するデベロッパーや、複数のアプリチーム用に CI パイプライン テンプレートを作成するプラットフォーム エンジニアにとって、アプリの検証は有効な手段となります。

ポリシーは、組織のセキュリティとコンプライアンスの重要な部分です。Anthos Config Management の一部である Policy Controller を使用すると、すべてのクラスタに対してこれらのポリシーを一元的かつ宣言的に管理できます。デベロッパーは、ポリシーの一元的かつ宣言型な性質を利用できます。これらの特性を利用して、開発ワークフローの早い段階でポリシーに基づいてアプリを検証できます。デプロイ中ではなく CI パイプラインでのポリシー違反について学習すると、主に 2 つの利点があります。1 つはセキュリティのシフトレフトが可能なことです。そして、フィードバック ループを厳格化することで、違反の修正に要する時間とコストが削減されます。

Anthos Config Management と Policy Controller の管理を担当しており、特定のアプリではなく CI パイプラインを構築する場合は、CI パイプラインでの Policy Controller の使用をご覧ください。

このチュートリアルでは、Cloud Build を CI ツールとして使用し、デモンストレーションのポリシーを含むサンプル GitHub リポジトリを使用します。

リソース

このチュートリアルでは、いくつかの Kubernetes ツールを使用します。このセクションでは、これらのツールの概要、各コンポーネント間の相互作用、他のツールに置き換えることができるかどうかについて説明します。

このチュートリアルで使用するツールは次のとおりです。

  • Policy Controller: Policy Controller は、Anthos Config Management の一部である Google Cloud サービスです。これは、オープンソース プロジェクトの Open Policy Agent - Gatekeeper に基づいています。Policy Controller は、Kubernetes クラスタで作成されたオブジェクトに関するポリシーを適用します(たとえば、特定のオプションの使用の禁止や特定のラベルの使用の強制)。これらのポリシーは「制約」と呼ばれます。制約は、Kubernetes カスタム リソースとして定義されます。Config Sync では、Git リポジトリでそれらの制約を宣言し、従来の開発ワークフローをポリシー管理プロセスに適用できます。Config Sync は、スタンドアロン プロダクトとしても、Anthos Config Management の一部としても提供されます。実装には、Policy Controller の代わりに Open Policy Agent の Gatekeeper を使用できます。

  • GitHub: このチュートリアルでは、GitHub を使用して Git リポジトリをホストします。1 つはサンプルアプリ用、もう 1 つは Anthos Config Management(Policy Controller のポリシーの制約を含むもの)です。便宜上、2 つのリポジトリは 1 つの Git リポジトリの 2 つの異なるフォルダにしています。実際には、これらは異なるリポジトリです。任意の Git ソリューションを使用できます。

  • Cloud Build: Google Cloud の CI ソリューションです。このチュートリアルでは、これを使用して検証テストを実行します。実装の詳細は CI システムによって異なりますが、このチュートリアルで説明するコンセプトは、任意のコンテナベースの CI システムで使用できます。

  • Kustomize: Kubernetes 構成のカスタマイズ ツールです。ベース構成を取り入れ、カスタマイズすることで機能します。これにより、Kubernetes の構成に対して DRY(Don't Repeat Yourself)アプローチを適用できます。Kustomize では、すべての環境に共通する要素をベース構成に保持し、環境ごとにカスタマイズを行います。このチュートリアルでは、Kustomize の構成をアプリ リポジトリに保存し、CI パイプライン内で構成をビルドします(たとえば、カスタマイズを適用します)。このチュートリアルで説明するコンセプトは、クラスタに適用する準備が整った Kubernetes 構成を生成する任意のツールで使用できます(Helm テンプレート コマンドなど)。

  • Kpt: Kubernetes 構成のワークフローを構築するためのツールです。Kpt を使用すると、Kubernetes 構成の取得、表示、カスタマイズ、更新、検証、適用ができます。これは Git ファイルと YAML ファイルに対応しているため、Kubernetes エコシステムのほとんどのツールと互換性があります。このチュートリアルでは、CI パイプラインで kpt を使用して Anthos Config Management リポジトリから制約を取得し、その制約に対して Kubernetes 構成を検証します。

パイプライン

このチュートリアルで使用する CI パイプラインを次の図に示します。

Policy Controller の CI パイプライン

このパイプラインは Cloud Build で動作し、コマンドはサンプルアプリのリポジトリのコピーを含むディレクトリで実行されます。パイプラインは、kustomize で最終的な Kustomize 構成を生成することから始まります。次に、kpt を使用して Anthos Config Management リポジトリから検証する制約を取得します。最後に、kpt を使用して Kubernetes 構成をこれらの制約に対して検証します。この最後のステップを達成するために、この検証を実行する gatekeeper-validate という特定の構成関数を使用します。このチュートリアルでは、CI パイプラインを手動でトリガーしていますが、実際には Git リポジトリへの git push の後に実行するように構成します。

目標

  • Cloud Build を使用してサンプルアプリの CI パイプラインを実行する。
  • ポリシー違反があるとパイプラインが失敗することを確認する。
  • ポリシーを遵守するように、サンプルアプリのリポジトリを変更する。
  • CI パイプラインを再度実行する。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

  • Cloud Build

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。

このチュートリアルの終了後は、作成したリソースを削除するとそれ以上の請求が発生しなくなります。詳細については、クリーンアップ セクションをご覧ください。

始める前に

  1. Google Cloud プロジェクトを選択または作成します。Google Cloud Console で、[リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクトに対する課金を有効にします

  3. このチュートリアルのコマンドを実行するには、Cloud Shell を開きます。

    Cloud Shell に移動

  4. Cloud Shell で gcloud config get-value project コマンドを実行します。

    たとえば、コマンドで選択したプロジェクトの ID が返されない場合は、プロジェクトが使用されるように Cloud Shell を構成します。

    gcloud config set project PROJECT_ID
    

    PROJECT_ID は、実際のプロジェクト ID に置き換えます。

  5. Cloud Shell で、必要な Cloud Build API を有効にします。

    gcloud services enable cloudbuild.googleapis.com
    

サンプルアプリの構成を検証する

このセクションでは、提供されているサンプル リポジトリに対して、Cloud Build を使用して CI パイプラインを実行します。このパイプラインは、サンプルアプリ リポジトリにある Kubernetes 構成を、サンプル Anthos Config Management リポジトリにある制約に対して検証します。

アプリの構成を検証するには:

  1. Cloud Shell で、サンプルアプリ リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git
    
  2. Cloud Build で CI パイプラインを実行します。ビルドのログが Cloud Shell に直接表示されます。

    cd anthos-config-management-samples/ci-app/app-repo
    gcloud builds submit .
    

    実行するパイプラインは、次のファイルで定義されます。

    steps:
    - id: 'Prepare config'
      # This step builds the final manifests for the app
      # using kustomize and the configuration files
      # available in the repository.
      name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
      entrypoint: '/bin/sh'
      args: ['-c', 'mkdir hydrated-manifests && kubectl kustomize config/prod > hydrated-manifests/prod.yaml']
    - id: 'Download policies'
      # This step fetches the policies from the Anthos Config Management repository
      # and consolidates every resource in a single file.
      name: 'gcr.io/kpt-dev/kpt'
      entrypoint: '/bin/sh'
      args: ['-c', 'kpt pkg get https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git/ci-app/acm-repo/cluster@1.0.0 constraints
                      && kpt fn source constraints/ hydrated-manifests/ > hydrated-manifests/kpt-manifests.yaml']
    - id: 'Validate against policies'
      # This step validates that all resources comply with all policies.
      name: 'gcr.io/config-management-release/policy-controller-validate'
      args: ['--input', 'hydrated-manifests/kpt-manifests.yaml']

    Policy Controller では、制約は制約テンプレートのインスタンス化です。制約テンプレートには、制約の実装に使用される実際の Rego コードが含まれています。gcr.io/kpt-fn/gatekeeper 関数を使用するには、制約テンプレートと制約の定義の両方が必要です。サンプル ポリシー リポジトリには両方が含まれますが、実際には異なる場所に保存されていることがあります。必要に応じて kpt pkg get コマンドを使用して、制約テンプレートと制約の両方をダウンロードします。

  3. 数分後、次のエラーが発生し、パイプラインが失敗することを確認します。

    [...]
    Step #2 - "Validate against policies": [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies": [FAIL] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies":   Results:
    Step #2 - "Validate against policies":     [ERROR] Deployment objects should have an 'owner' label indicating who created them. violatedConstraint: deployment-must-have-owner in object "apps/v1/Deployment/nginx-deployment" in file "prod.yaml"
    Step #2 - "Validate against policies":   Stderr:
    Step #2 - "Validate against policies":     "[error] apps/v1/Deployment/nginx-deployment : Deployment objects should have an 'owner' label indicating who created them."
    Step #2 - "Validate against policies":     "violatedConstraint: deployment-must-have-owner"
    Step #2 - "Validate against policies":     ""
    Step #2 - "Validate against policies":   Exit code: 1
    [...]
    

    構成に違反する制約は、次のファイルに定義されています。これは K8sRequiredLabels という Kubernetes カスタム リソースです。

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: deployment-must-have-owner
    spec:
      match:
        kinds:
          - apiGroups: ["apps"]
            kinds: ["Deployment"]
      parameters:
        labels:
          - key: "owner"
        message: "Deployment objects should have an 'owner' label indicating who created them."

    この制約に対応する制約テンプレートについては、GitHub の requiredlabels.yaml をご覧ください。

  4. Kubernetes 構成全体を自分でビルドし、owner ラベルが実際に存在しないことを確認します。構成を作成するには:

    kubectl kustomize config/prod
    

会社のポリシーを遵守するようにアプリを修正する

このセクションでは、Kustomize を使用してポリシー違反を修正します。

  1. Cloud Shell で、ベースの Kustomization ファイルに commonLabels セクションを追加します。

    cat <<EOF >> config/base/kustomization.yaml
    commonLabels:
      owner: myself
    EOF
    
  2. 完全な Kubernetes 構成を作成し、owner ラベルが存在していることを確認します。

    kubectl kustomize config/prod
    
  3. Cloud Build で CI パイプラインを再度実行します。

    gcloud builds submit .
    

    次の出力が表示され、パイプラインが成功します。

    [...]
    Step #2 - "Validate against policies": [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies": [PASS] "gcr.io/kpt-fn/gatekeeper:v0"
    [...]
    

クリーンアップ

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ