Kyvernoで作成したポリシーを"実環境のリソースでリハーサル(dry-run)"する
目的
Kyverno で作成したポリシーが、既にデプロイされているリソースにどう影響するかを事前にリハーサル(dry-run)する方法を紹介します。
Kyverno とは何か
Kyverno は Kubernetes のポリシーエンジンで Cloud Native Computiong Foundation の Incubating プロジェクトです。
Kyverno の特徴や、使い方については分かり易い記事がたくさんあるのでそちらにお任せして、本記事ではポリシーの dry-run についての How To を書こうと思います。
※ 以下のスライドで、使い方網羅的に分かりやすくまとめられております。
Kyverno の dry-run
Kyverno で提供されている Kyverno CLI を用いることで、ポリシー適用前にリソースへの動作検証を行うことができます。
dry-run の対象は、実環境にデプロイされているリソース、静的なマニフェストファイルいずれも可能です。
Kyverno CLI のインストール
いくつかインストール方法が用意されておりますが、本記事では Krew を使いインストールし検証を行いました。
$ kubectl krew install kyverno
$ kubectl kyverno version
Version: 1.9.0
Time: 2023-02-01T09:34:42Z
Git commit ID: a1534cc2f581bbc93c15fa5ac42fe5c59f03d66a
バイナリファイルも配布されています。kustomize を使ったマニフェストファイルへの動作検証を行う場合はこちらの Kyverno CLI を使うことが推奨されています。
git clone https://github.com/kyverno/kyverno
cd kyverno
make build-cli
mv ./cmd/cli/kubectl-kyverno/kyverno /usr/local/bin/kyverno
dry-run の方法
Kyverno CLI を使った dry-run は以下のコマンドで簡単に実行できます。
動作検証を行う対象(実環境のリソース or マニフェストファイル)や適用範囲などを限定して実行することができます。
$ kubectl kyverno <Policy> -r <Resource> --cluster -n <Namespace>
No. | Policy | Resource | Cluster | Namespace | 対象 |
---|---|---|---|---|---|
① | policy.yaml | yaml | false | マニフェストファイル | |
② | policy.yaml | リソース名 | true | 実環境:リソース指定 | |
③ | policy.yaml | true | 実環境:クラスタ全体 | ||
④ | policy.yaml | リソース名 | true | namespace名 | 実環境:リソースとnamespace指定 |
⑤ | policy.yaml | true | namespace名 | 実環境:namespace指定 |
- ① マニフェストファイルへの動作検証
マニフェストファイルに対してポリシーの動作検証をしたい場合は以下です。$ kubectl kyverno policy.yaml --resource resource.yaml
- ② 実環境のリソースに対して、リソース指定して動作検証
ポリシーで指定しているrule.match.any.resources.kind[]
リソースの名前を指定します。例えばポリシーの対象がPod
で、test
という Pod に対して動作検証をしたい場合は以下です。$ kyverno apply policy.yaml -r test --cluster
- ③ 実環境のリソース(クラスタ全体)に対して動作検証
kubectl の current-context のクラスタのリソースを対象に動作検証を行います。$ kyverno apply policy.yaml --cluster
- ④ 実環境のリソースに対して、リソースとnamespaceを指定して動作検証
② に対して、さらに namespace を指定して動作検証を行います。$ kyverno apply policy.yaml -r test --cluster -n default
- ⑤ 実環境のリソースに対して、namespace を指定して動作検証
ポリシーで指定しているrule.match.any.resources.kind[]
リソースを namespace を絞って動作検証を行います。
この場合、ポリシー内でrule.[match or exclude].any.resources.namespaces[]
の指定はできません。$ kyverno apply policy.yaml --cluster -n default
dry-run してみる
以下のような適当なポリシーを用意します。
app.kubernetes.io/name
ラベルが付与されていない Pod をデプロイさせないポリシーです。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-for-labels
match:
any:
- resources:
kinds:
- Pod
validate:
message: "label 'app.kubernetes.io/name' is required"
pattern:
metadata:
labels:
app.kubernetes.io/name: "?*"
上記 require-labels
ポリシーに従う Pod と反する Pod をデプロイします。
# ポリシーに従う Pod
$ kubectl run nginx-labeled --image=nginx --labels app.kubernetes.io/name=nginx -n default
pod/nginx-labeled created
# ポリシーに反する Pod
$ kubectl run nginx-non-labeled --image=nginx -n default
pod/nginx-non-labeled created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-labeled 2/2 Running 0 57s
nginx-non-labeled 2/2 Running 0 71s
この環境で require-labels
ポリシー を dry-run してみます。
$ kubectl kyverno apply require-labels.yaml --cluster -n default
Applying 1 policy rule to 2 resources...
policy require-labels -> resource playground/Pod/nginx-non-labeled failed:
1. check-for-labels: validation error: label 'app.kubernetes.io/name' is required. rule check-for-labels failed at path /metadata/labels/app.kubernetes.io/name/
pass: 1, fail: 1, warn: 0, error: 0, skip: 4
結果を見ると、ポリシーに従う Pod は pass, ポリシーに反する Pod は fail となっていることがわかります。
このように、require-labels
ポリシーを適用した際の既存リソースへの動作検証ができます🥳
skip: 4
となっている部分は、kyverno の Auto-Gen ルールに対する結果となります。
Kubernetes では Pod を直接作成することは少なく、Deployment や DaemonSet などの上位リソースから間接的に生成されます。
従って、Kyverno では Pod を resource.kind[]
に指定した場合、その上位リソースを検証範囲としたルールが自動生成される便利な仕様となっています。
今回のポリシーでは、resource.kind[]
に Pod を指定しているため Auto-Gen ルールが追加適用されたが、一致するリソースがないため skip
としてカウントされています。
最後に
Kyverno で作ったポリシーを dry-run する方法についてまとめました。
Kyverno CLI を使ってポリシーの実環境へのリハーサルを行うことで、既存リソースへの影響を把握した上で、安全にポリシー適用を行うことができます。
Discussion