制約テンプレート ライブラリを使用する
このページでは、Google が提供する既存の制約テンプレートを使用して Policy Controller の制約を定義する方法について説明します。
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 を理解して記述する必要はありません。代わりに、制約は制約テンプレートを呼び出して固有のパラメータを渡します。
構造化されたリポジトリを使用している場合は、cluster/
ディレクトリに制約を作成することをおすすめします。
制約には次のフィールドがあります。
- 小文字の
kind
は、制約テンプレートの名前と対応します。 metadata.name
は、制約の名前です。match
フィールドは、制約が適用されるオブジェクトを定義します。オブジェクトが制約の対象となるには、指定されたすべての条件を満たす必要があります。match
条件は、次のサブフィールドで定義されます。kinds
は、制約が適用されるリソースの種類です。一致する Kubernetes API グループのリストapiGroups
と、一致する種類のリストkinds
という 2 つのフィールドで指定されます。「*」はすべてに一致します。apiGroup
エントリとkind
エントリが少なくとも 1 つずつ一致すると、kinds
条件が満たされます。scope
は *、Cluster、または Namespace を受け入れ、クラスタ スコープのリソースと名前空間スコープのリソースのどちらか一方、または両方が選択されるかどうかを決定します(デフォルトは *)。namespaces
は、オブジェクトが属することができる名前空間名のリストです。オブジェクトは、これらの名前空間の少なくとも 1 つに属している必要があります。名前空間リソースは、その名前空間自体に属しているものとみなされます。excludedNamespaces
は、オブジェクトが属することができない名前空間のリストです。labelSelector
は、オブジェクトが満たす必要がある Kubernetes ラベル セレクターです。namespaceSelector
は、オブジェクトが属する名前空間のラベル セレクターです。名前空間がオブジェクトを満たさない場合は、一致しません。名前空間リソースは、その名前空間自体に属しているものとみなされます。
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.enforcementAction
を dryrun
に設定すると、オペレーションを妨げることなく、status.violations
フィールドで違反が報告されます。
監査の詳細については、制約を使用して監査するをご覧ください。
制約を同期するときの注意点
制約を同期するときは、次の注意点に留意してください。
結果整合性
制約は Git リポジトリに commit し、ClusterSelector または NamespaceSelector を使用して影響を制限できます。同期には結果整合性があるため、次の注意点に留意してください。
- クラスタ オペレーションによって、同期されていない名前空間を参照する NamespaceSelector の制約がトリガーされると、制約が適用されてオペレーションが完了しません。つまり、不明な名前空間は「フェイル クローズ」します。
- 名前空間のラベルを変更すると、一時的にキャッシュに古いデータが含まれる場合があります。
名前空間の名前やラベルを変更する必要性は最小限に抑えてください。また、名前やラベルが変更された名前空間に影響を与える制約をテストし、期待どおりに機能することを確かめてください。
参照制約用の Policy Controller の構成
参照制約は、名前空間など、監視するオブジェクトの種類を Policy Controller に指示する構成ファイルを作成した後、有効にする必要があります。
次の YAML マニフェストをファイルに保存し、kubectl
で適用します。このマニフェストでは、名前空間と Ingresses を監視するように Policy Controller を構成します。エントリは、group
、version
、kind
に監視するオブジェクトの各タイプの値を指定して、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
が含まれている場合、その制約は参照用です。
参照制約は、Policy Controller ではデフォルトで無効になっています。参照制約は、結果整合性が保証するだけのものであり、これによって生じるリスクがあります。
過負荷の API サーバーでは、Policy Controller のキャッシュの内容が古くなる可能性があり、参照制約を「フェイル オープン」させることになります。つまり、適用アクションが機能していないときに、機能しているように見えるということです。たとえば、重複したホスト名での Ingress の作成が早すぎて、アドミッション コントローラによる重複の検出ができなくなる可能性があります。
制約がインストールされる順序と、キャッシュが更新される順序は、どちらもランダムです。
こうしたリスクを理解したうえで、参照制約のサポートを有効にする場合は、Google Cloud Console で参照制約を有効にできます。詳細については、Policy Controller をインストールするをご覧ください。
また、config-management.yaml
ファイルで policyController.referentialRulesEnabled
を true
に設定することもできます。
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
すべての制約を一覧表示する
クラスタにインストールされているすべての制約を一覧表示するには、次のコマンドを使用します。
kubectl get constraint
また、適用した制約の概要を Google Cloud コンソールで確認することもできます。 詳細については、Policy Controller の指標をご覧ください。
制約を削除する
制約テンプレートを使用するすべての制約を見つけるには、次のコマンドを使用して、制約テンプレートの metadata.name
と同じ kind
を持つすべてのオブジェクトを一覧表示します。
kubectl get CONSTRAINT_TEMPLATE_NAME
制約を削除するには、その kind
と name
を指定します。
kubectl delete CONSTRAINT_TEMPLATE_NAME CONSTRAINT_NAME
制約で使用していた制約テンプレートを削除する場合は、制約の kind
をメモします。
制約を削除すると、API サーバーによって制約に削除済みのマークが付けられ、その後直ちに制約の適用が停止します。
すべての制約テンプレートを削除する
spec.policyController.templateLibraryInstalled
を false
に設定します。この設定により、Anthos Config Management がライブラリを自動的に再インストールすることが防止されます。
すべての制約テンプレートとすべての制約を削除するには、次のコマンドを使用します。
kubectl delete constrainttemplate --all
制約テンプレート ライブラリを復元する
制約テンプレート ライブラリを無効にした場合や、すべての制約テンプレートをアンインストールした場合は、Anthos Config Management の構成ファイルの spec.policyController.templateLibraryInstalled
を true
に設定することでそれを復元できます。
次のステップ
- 制約テンプレート ライブラリのリファレンス ドキュメントを参照する。
- カスタム制約を作成する方法を学習する。
- PodSecurityPolicies の代わりに制約を使用する方法を学習する。
- Policy Controller のトラブルシューティング。