TT Lab
はじめる
学ぶ 学習パス コース

KCA — Kyverno認定アソシエイト

validate規則と組み込みポリシーを比べる

TT Labで続きを見る

目標

Kyverno ClusterPolicyでラベル必須とタグ禁止のルールを作成し、同じ検査をKubernetes組み込みのValidatingAdmissionPolicyでも実際のクラスターに載せて、2つのアプローチの違いを確認します。

なぜ重要なのか

ポリシーエンジンを導入するかどうかを判断するには、組み込み機能の射程を知っておく必要があります。フィールド1つをCELで検査するだけならValidatingAdmissionPolicyで十分で、そうすれば運用するコンポーネントが1つ減り、Webhook証明書の更新を気にする場面も1つ減ります。Kyvernoを正当化するのは、generateやmutate、イメージ検証のように、組み込みポリシーにできないことです。このラボで2つのマニフェストを並べて作ってみると、その境界がどこにあるかが手に残ります。もう1つ、ルールごとに強制レベルを変える練習は、実際の導入手順の核心です。

ステップ

  1. /root/kca-validate/ディレクトリを作成し、policy.yamlにapiVersionとしてkyverno.io/v1、kindとしてClusterPolicy、metadata.nameとしてkca-require-app-labelを書き、spec.rules[0].nameをcheck-app-labelにしてください。
  2. spec.rules[0].match.any[0].resources.kindsにPodとDeploymentを入れ、同じ場所のnamespacesにkca-appを入れてください。
  3. spec.rules[0].validate.messageを埋め、validate.patternでmetadata.labelsのapp.kubernetes.io/nameが空でない値であることを要求してください。
  4. spec.rules[0].validate.failureActionをEnforceにしてください。ポリシーレベルのspec.validationFailureActionは使わないでください。
  5. 2つ目のルールdeny-latest-tagを追加してください。validate.messageを埋め、validate.deny.conditions.all[0]にコンテナイメージを指すkey、operator、valueを入れたうえで、このルールのvalidate.failureActionはAuditにしてください。
  6. spec.rules[0].exclude.any[0].resources.namespacesにkube-systemとkyvernoを入れてください。
  7. クラスターにValidatingAdmissionPolicy kca-require-app-labelを実際に作成してください。spec.failurePolicyはFail、spec.matchConstraintsはappsグループのdeploymentsをCREATEとUPDATEで捉え、spec.validations[0].expressionはapp.kubernetes.io/nameラベルの存在を検査するCELにしてください。
  8. クラスターにネームスペースkca-appをラベルkca=enforced付きで作成し、ValidatingAdmissionPolicyBinding kca-require-app-label-bindingを実際に作成してください。spec.policyNameにはkca-require-app-label、spec.validationActionsにはDeny、spec.matchResources.namespaceSelector.matchLabelsにはkca: enforcedを入れてください。

参考

ClusterPolicyの骨組みを作る

/root/kca-validate/ディレクトリを作成し、policy.yamlにapiVersionとしてkyverno.io/v1、kindとしてClusterPolicy、metadata.nameとしてkca-require-app-labelを書き、spec.rules[0].nameをcheck-app-labelにしてください。

ClusterPolicyはkyverno.ioグループのクラスタースコープのリソースです。rulesは配列で、各ルールには必ず名前が必要です。

何を選ぶのか

spec.rules[0].match.any[0].resources.kindsにPodとDeploymentを入れ、同じ場所のnamespacesにkca-appを入れてください。

match.anyは配列で、各要素の中のresourcesにkinds・namespaces・names・selectorを入れます。対象の種類とネームスペースを一緒に絞ると、Webhookを通るリクエスト数が減ります。

パターンマッチングで必須ラベルを要求する

spec.rules[0].validate.messageを埋め、validate.patternでmetadata.labelsのapp.kubernetes.io/nameが空でない値であることを要求してください。

patternは、検査するオブジェクトの形をそのまま描いたうえで、値の位置に演算子を入れます。空でない値を要求する演算子が何だったか、思い出してください。

ルール単位で強制レベルを決める

spec.rules[0].validate.failureActionをEnforceにしてください。ポリシーレベルのspec.validationFailureActionは使わないでください。

ポリシーレベルのフィールドはdeprecatedなので、残しておいてはいけません。強制レベルはvalidateブロックの中に下りてきており、指定しなければデフォルトは観察モードです。

deny.conditionsで2つ目のルールを追加する

2つ目のルールdeny-latest-tagを追加してください。validate.messageを埋め、validate.deny.conditions.all[0]にコンテナイメージを指すkey、operator、valueを入れたうえで、このルールのvalidate.failureActionはAuditにしてください。

条件はkey、operator、valueの3つの欄です。allとanyのどちらで束ねるかは、条件が複数あるときに意味が分かれます。このルールだけを観察モードにしてください。

システムネームスペースを除外する

spec.rules[0].exclude.any[0].resources.namespacesにkube-systemとkyvernoを入れてください。

excludeの構造はmatchと同じです。ポリシーがKyverno自身やコントロールプレーンの構成要素を止めてしまうと、復旧が難しくなります。

同じルールを組み込みポリシーで書く

クラスターにValidatingAdmissionPolicy kca-require-app-labelを実際に作成してください。spec.failurePolicyはFail、spec.matchConstraintsはappsグループのdeploymentsをCREATEとUPDATEで捉え、spec.validations[0].expressionはapp.kubernetes.io/nameラベルの存在を検査するCELにしてください。

ValidatingAdmissionPolicyはCRDではなくKubernetes組み込みのリソースなので、そのままapplyすれば作成できます。式はCELで、objectで検査対象にアクセスします。

バインディングと対象ネームスペース

クラスターにネームスペースkca-appをラベルkca=enforced付きで作成し、ValidatingAdmissionPolicyBinding kca-require-app-label-bindingを実際に作成してください。spec.policyNameにはkca-require-app-label、spec.validationActionsにはDeny、spec.matchResources.namespaceSelector.matchLabelsにはkca: enforcedを入れてください。

組み込みポリシーは、ポリシーとバインディングの2つのオブジェクトが1組です。バインディングがなければ、ポリシーは存在するだけで、どのリクエストも処理せず、どんな動作をするかもバインディングが決めます。