制約テンプレート ライブラリを使用する

このページでは、Google が提供する既存の制約テンプレートを使用して Policy Controller の制約を定義する方法について説明します。

このページは、監査または適用のために自動化や、宣言型構成のテンプレート化により、クラウド プラットフォーム内で実行されているすべてのリソースが組織のコンプライアンス要件を確実に満たすようにする IT 管理者とオペレーターを対象としています。Google Cloud のコンテンツで参照する一般的なロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

Policy Controller を使用すると、1 つ以上の制約オブジェクトを定義することにより、Kubernetes クラスタにポリシーを適用できます。制約がインストールされると、API サーバーへのリクエストは制約と照合され、準拠していない場合は拒否されます。以前から存在する準拠していないリソースは、監査時に報告されます。

すべての制約は、制約のスキーマとロジックを定義する制約テンプレートが基盤となります。制約テンプレートは、Google やサードパーティから提供されるものを使用することも、独自に作成することもできます。新しいテンプレートの作成の詳細については、制約テンプレートを作成するをご覧ください。

始める前に

制約テンプレート ライブラリを調べる

制約を定義するときは、拡張する制約テンプレートを指定します。Google が開発した一般的な制約テンプレートのライブラリがデフォルトでインストールされており、多くの組織では Rego で直接カスタム制約テンプレートを作成する必要はありません。Google が提供する制約テンプレートには、configmanagement.gke.io/configmanagement というラベルが付いています。

制約を一覧表示するには、次のコマンドを使用します。

kubectl get constrainttemplates \
    -l="configmanagement.gke.io/configmanagement=config-management"

制約テンプレートを記述して必須パラメータを確認するには、次のコマンドを使用します。

kubectl describe constrainttemplate CONSTRAINT_TEMPLATE_NAME

また、ライブラリ内のすべての制約テンプレートを表示することも可能です。

制約を定義する

制約は YAML を使用して定義します。Rego を理解して記述する必要はありません。代わりに、制約は制約テンプレートを呼び出して固有のパラメータを渡します。

階層リポジトリで Config Sync を使用している場合は、cluster/ ディレクトリに制約を作成することをおすすめします。

制約には次のフィールドがあります。

  • 小文字の kind は、制約テンプレートの名前と対応します。
  • metadata.name は、制約の名前です。
  • match フィールドは、制約が適用されるオブジェクトを定義します。オブジェクトが制約の対象となるには、指定されたすべての条件を満たす必要があります。match 条件は、次のサブフィールドで定義されます。
    • kinds は、制約が適用されるリソースの種類です。一致する Kubernetes API グループのリスト apiGroups と、一致する種類のリスト kinds という 2 つのフィールドで指定されます。「*」はすべてに一致します。apiGroup エントリと kind エントリが少なくとも 1 つずつ一致すると、kinds 条件が満たされます。
    • scope には *、Cluster、Namespaced のいずれかを指定します。これにより、クラスタ スコープのリソースと Namespace スコープのリソースのどちらが選択されるかが決定されます(デフォルトは *)。
    • namespaces は、オブジェクトが属することができる Namespace 名のリストです。オブジェクトは、これらの名前空間の少なくとも 1 つに属している必要があります。名前空間リソースは、その名前空間自体に属しているものとみなされます。
    • excludedNamespaces は、オブジェクトが属することができない名前空間のリストです。
    • labelSelector は、オブジェクトが満たす必要がある Kubernetes ラベル セレクターです。
    • namespaceSelector は、オブジェクトが属する Namespace のラベル セレクターです。Namespace がオブジェクトの条件を満たしていない場合は、一致しません。Namespace リソースは、その Namespace 自体に属しているものとみなされます。
  • parameters フィールドは、制約テンプレートが想定するものに基づいて、制約の引数を定義します。

次の ns-must-have-geo という制約は、Google が提供する制約テンプレート ライブラリに含まれている K8sRequiredLabels という制約テンプレートを呼び出します。この制約は、なんらかの値が設定されている geo ラベルが名前空間にあるかどうかを検証するよう、制約テンプレートが使用するパラメータを定義しています。

# ns-must-have-geo.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-geo
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels:
      - key: "geo"

制約を作成するには、kubectl apply -f を使用します。

kubectl apply -f ns-must-have-geo.yaml

制約を監査する

制約が正しく構成、インストールされている場合、制約を実際に適用する構成か、テストするだけの構成かにかかわらず、status.byPod[].enforced フィールドは true に設定されます。

デフォルトでは制約は適用され、制約に違反するクラスタのオペレーションは完了しなくなります。制約の spec.enforcementActiondryrun に設定すると、オペレーションを妨げることなく、status.violations フィールドで違反が報告されます。

監査の詳細については、制約を使用して監査するをご覧ください。

制約を同期するときの注意点

Config Sync または別の GitOps スタイルのツールを使用して、Git リポジトリなどの一元化されたソースに制約を同期する場合は、制約を同期する際に次のことに注意してください。

結果整合性

Git リポジトリなどの信頼できるソースに制約を適用し、ClusterSelector または NamespaceSelector を使用して影響を制限できます。同期には結果整合性があるため、次の注意点に留意してください。

  • クラスタ オペレーションによって、同期されていない名前空間を参照する NamespaceSelector の制約がトリガーされると、制約が適用されてオペレーションが完了しません。つまり、不明な名前空間は「フェイル クローズ」します。
  • 名前空間のラベルを変更すると、一時的にキャッシュに古いデータが含まれる場合があります。

Namespace の名前やラベルを変更する必要性は最小限に抑えてください。また、名前やラベルが変更された Namespace に影響を与える制約をテストし、期待どおりに機能することを確かめてください。

参照制約用に Policy Controller を構成する

参照制約は、監視するオブジェクトの種類(Namespace など)を Policy Controller に指示する構成を作成した後、有効にする必要があります。

次の YAML マニフェストをファイルに保存し、kubectl で適用します。このマニフェストでは、名前空間と Ingresses を監視するように Policy Controller を構成します。エントリは、groupversionkind に監視するオブジェクトの各タイプの値を指定して、spec.sync.syncOnly の下に作成します。

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"
      - group: "extensions"
        version: "v1beta1"
        kind: "Ingress"

参照制約を有効にする

参照制約では、その定義内の別のオブジェクトを参照します。たとえば、クラスタ内に一意のホスト名を持つ Ingress オブジェクトを求める制約を作成できます。制約テンプレートの Rego に文字列 data.inventory が含まれている場合、その制約は参照用です。

Google Cloud コンソールを使用して Policy Controller をインストールすると、参照制約はデフォルトで有効になります。Google Cloud CLI を使用して Policy Controller をインストールする場合は、Policy Controller のインストール時に参照制約を有効にするかどうかを選択できます。参照制約は、結果整合性が保証するだけのものであり、これによって生じるリスクがあります。

  • 過負荷の API サーバーでは、Policy Controller のキャッシュの内容が古くなる可能性があり、参照制約を「フェイル オープン」させることになります。つまり、適用アクションが機能していないときに、機能しているように見えるということです。たとえば、重複したホスト名での Ingress の作成が早すぎて、アドミッション コントローラによる重複の検出ができなくなる可能性があります。

  • 制約がインストールされる順序と、キャッシュが更新される順序は、どちらもランダムです。

既存のクラスタを更新して、参照制約を許可できます。

コンソール

参照の制約を無効にするには、次の手順を完了します。

  1. Google Cloud コンソールで [GKE Enterprise] に移動し、[体制の管理] の下にある [ポリシー] を選択します。

    [ポリシー] に移動

  2. [設定] タブのクラスタ テーブルで、[構成の編集] 列にある [編集 ] を選択します。
  3. [Policy Controller の構成を編集] メニューを開きます。
  4. [現在評価されているオブジェクト以外のオブジェクトを参照する制約テンプレートを有効にする] チェックボックスをオンにします。
  5. [変更を保存] をクリックします。

gcloud Policy Controller

参照制約を有効にするには、次のコマンドを実行します。

gcloud container fleet policycontroller update \
    --memberships=MEMBERSHIP_NAME \
    --referential-rules

MEMBERSHIP_NAME は、参照ルールを有効にする登録済みクラスタのメンバーシップ名に置き換えます。複数のメンバーシップを指定する場合は、カンマ区切りで指定します。

gcloud ConfigManagement

参照制約のサポートを有効にするには、config-management.yaml ファイルで policyController.referentialRulesEnabledtrue に設定します。

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: true

参照制約を無効にする

参照制約を無効にすると、参照制約を使用するテンプレートもすべて、そのテンプレートを使用する制約とともにクラスタから削除されます。

コンソール

Google Cloud コンソールを使用して Policy Controller をインストールすると、参照制約はデフォルトで有効になります。参照の制約を無効にするには、次の手順を完了します。

  1. Google Cloud コンソールで [GKE Enterprise] に移動し、[体制の管理] の下にある [ポリシー] を選択します。

    [ポリシー] に移動

  2. [設定] タブのクラスタ テーブルで、[構成の編集] 列にある [編集 ] を選択します。
  3. [Policy Controller の構成を編集] メニューを開きます。
  4. [現在評価されているオブジェクト以外のオブジェクトを参照する制約テンプレートを有効にする] チェックボックスをオフにします。
  5. [変更を保存] をクリックします。

gcloud Policy Controller

参照制約のサポートを無効にするには、次のコマンドを実行します。

gcloud container fleet policycontroller update \
    --memberships=MEMBERSHIP_NAME \
    --no-referential-rules

MEMBERSHIP_NAME は、参照ルールを有効にする登録済みクラスタのメンバーシップ名に置き換えます。複数のメンバーシップを指定する場合は、カンマ区切りで指定します。

gcloud ConfigManagement

クラスタの参照制約を無効にするには、config-management.yaml ファイルで policyController.referentialRulesEnabledfalse に設定します。

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: false

すべての制約を一覧取得する

クラスタにインストールされているすべての制約を一覧表示するには、次のコマンドを使用します。

kubectl get constraint

また、適用した制約の概要を Google Cloud コンソールで確認することもできます。 詳細については、Policy Controller の指標をご覧ください。

制約を削除する

制約テンプレートを使用するすべての制約を見つけるには、次のコマンドを使用して、制約テンプレートの metadata.name と同じ kind を持つすべてのオブジェクトを一覧表示します。

kubectl get CONSTRAINT_TEMPLATE_NAME

制約を削除するには、その kindname を指定します。

kubectl delete CONSTRAINT_TEMPLATE_NAME CONSTRAINT_NAME

制約を削除すると、API サーバーによって制約に削除済みのマークが付けられ、その後直ちに制約の適用が停止します。

すべての制約テンプレートを削除する

コンソール

制約テンプレート ライブラリを無効にするには、次の操作を行います。

  1. Google Cloud コンソールで [GKE Enterprise] に移動し、[体制の管理] の下にある [ポリシー] を選択します。

    [ポリシー] に移動

  2. [設定] タブのクラスタ テーブルで、[構成の編集] 列にある [編集 ] を選択します。
  3. [ポリシー バンドルを追加 / 編集] メニューで、テンプレート ライブラリとすべてのポリシー バンドルをオフ にします。
  4. [変更を保存] をクリックします。

gcloud Policy Controller

制約テンプレート ライブラリを無効にするには、次のコマンドを実行します。

gcloud container fleet policycontroller content templates disable \
    --memberships=MEMBERSHIP_NAME

MEMBERSHIP_NAME は、制約テンプレート ライブラリを無効にする登録済みクラスタのメンバーシップ名に置き換えます。複数のメンバーシップを指定する場合は、カンマ区切りで指定します。

gcloud ConfigManagement

[spec.policyController.templateLibraryInstalled] を [false] に設定します。これにより、Policy Controller によるライブラリの自動再インストールを防ぐことができます。

すべての制約テンプレートとすべての制約を削除するには、次のコマンドを使用します。

kubectl delete constrainttemplate --all

制約テンプレート ライブラリを復元する

コンソール

制約テンプレート ライブラリを有効にするには、次の操作を行います。

  1. Google Cloud コンソールで [GKE Enterprise] に移動し、[体制の管理] の下にある [ポリシー] を選択します。

    [ポリシー] に移動

  2. [設定] タブのクラスタ テーブルで、[構成の編集] 列にある [編集 ] を選択します。
  3. [ポリシー バンドルを追加 / 編集] メニューで、テンプレート ライブラリをオン に切り替えます。ポリシー バンドルの一部またはすべてを有効にすることもできます。
  4. [変更を保存] をクリックします。

gcloud Policy Controller

制約テンプレート ライブラリを復元するには、次のコマンドを実行します。

gcloud container fleet policycontroller content templates enable \
    --memberships=MEMBERSHIP_NAME

MEMBERSHIP_NAME を登録済みクラスタのメンバーシップ名に置き換えて、制約テンプレート ライブラリを有効にします。複数のメンバーシップを指定する場合は、カンマ区切りで指定します。

gcloud ConfigManagement

制約テンプレート ライブラリを無効にするか、すべての制約テンプレートをアンインストールした場合は、Policy Controller の構成ファイルで spec.policyController.templateLibraryInstalledtrue に設定することにより復元できます。

Operator Pod を再起動するには、次のコマンドを使用します。

kubectl delete pod -n config-management-system -l k8s-app=config-management-operator

次のステップ