メインコンテンツまでスキップ

シンプルなポリシーの作成

Kyvernoには2種類のポリシーリソースがあります:クラスター全体のリソースに使用されるClusterPolicyと、名前空間付きリソースに使用されるPolicyです。Kyvernoポリシーの理解を深めるために、まずはDeploymentに対するラベル要件から始めましょう。

以下は、PodテンプレートにCostCenterラベルを持たないDeploymentをブロックするClusterPolicyのサンプルです:

~/environment/eks-workshop/modules/security/kyverno/simple-policy/require-labels-policy.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
validationFailureAction: Enforce
rules:
- name: check-team
match:
any:
- resources:
kinds:
- Deployment
validate:
allowExistingViolations: false
message: "Label 'CostCenter' is required on the Deployment pod template"
pattern:
spec:
template:
metadata:
labels:
CostCenter: "?*"
A

spec.validationFailureActionは、検証されるリソースを許可して報告する(Audit)か、ブロックする(Enforce)かをKyvernoに指示します。デフォルトはAuditですが、この例ではEnforceに設定されています

B

rulesセクションには、検証する1つ以上のルールが含まれています

C

matchステートメントはチェックの範囲を設定します。この場合、すべてのDeploymentリソースが対象になります

D

validateステートメントは、定義された内容を肯定的にチェックしようとします。このステートメントがリクエストされたリソースと比較して真の場合、許可されます。偽の場合は、ブロックされます

E

allowExistingViolations: falseは、既に違反しているDeploymentへの更新もブロックされることを保証します。デフォルトでは、Kyvernoはポリシーが適用される前に存在していた非準拠リソースへの更新を許可し、ワークロードの中断を回避します。これをfalseに設定することで、このギャップを閉じ、すべてのアドミッションリクエストに対してポリシーを厳密に適用します

F

messageは、このルールが検証に失敗した場合にユーザーに表示されるメッセージです

G

patternオブジェクトは、リソースでチェックされるパターンを定義します。この場合、Deployment spec内のPodテンプレートラベルでspec.template.metadata.labelsCostCenterがあるかをチェックします

次のコマンドを使用してポリシーを作成します:

~$kubectl apply -f ~/environment/eks-workshop/modules/security/kyverno/simple-policy/require-labels-policy.yaml
 
clusterpolicy.kyverno.io/require-labels created

次に、uiのDeploymentを確認し、Podテンプレートのラベルを見てください:

~$kubectl -n ui get deployment ui -o jsonpath='{.spec.template.metadata.labels}' | jq
{
  "app.kubernetes.io/component": "service",
  "app.kubernetes.io/created-by": "eks-workshop",
  "app.kubernetes.io/instance": "ui",
  "app.kubernetes.io/name": "ui"
}

Podテンプレートには必要なCostCenterラベルが欠けています。では、uiのDeploymentの強制的なロールアウトを試みてみましょう:

~$kubectl -n ui rollout restart deployment/ui
error: failed to patch: admission webhook "validate.kyverno.svc-fail" denied the request:
 
resource Deployment/ui/ui was blocked due to the following policies
 
require-labels:
  check-team: 'validation error: Label ''CostCenter'' is required on the Deployment
    pod template. rule check-team failed at path /spec/template/metadata/labels/CostCenter/'

ロールアウトは、require-labels Kyvernoポリシーによりアドミッションウェブフックがリクエストを拒否したため、失敗しました。

次に、以下のKustomizationパッチを使用して、uiのDeploymentに必要なラベルCostCenterを追加します:

~/environment/eks-workshop/modules/security/kyverno/simple-policy/ui-labeled/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui
spec:
template:
metadata:
labels:
CostCenter: IT
~$kubectl apply -k ~/environment/eks-workshop/modules/security/kyverno/simple-policy/ui-labeled
namespace/ui unchanged
serviceaccount/ui unchanged
configmap/ui unchanged
service/ui unchanged
deployment.apps/ui configured
~$kubectl -n ui rollout status deployment/ui
deployment "ui" successfully rolled out
~$kubectl -n ui get deployment ui -o jsonpath='{.spec.template.metadata.labels}' | jq
{
  "CostCenter": "IT",
  "app.kubernetes.io/component": "service",
  "app.kubernetes.io/created-by": "eks-workshop",
  "app.kubernetes.io/instance": "ui",
  "app.kubernetes.io/name": "ui"
}

ポリシーが満たされ、ロールアウトが成功しました。

ミューテーションルール

上記の例では、validationFailureActionで定義されたデフォルトの動作でバリデーションポリシーがどのように機能するかを確認しました。しかし、Kyvernoはポリシー内でミューテーションルールを管理するためにも使用でき、APIリクエストを変更して、Kubernetesリソースに指定された要件を満たしたり強制したりすることができます。リソースの変更はバリデーションの前に行われるため、バリデーションルールはミューテーションセクションによって実行された変更と矛盾しません。

以下はミューテーションルールを定義したポリシーのサンプルです:

~/environment/eks-workshop/modules/security/kyverno/simple-policy/add-labels-mutation-policy.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-labels
spec:
rules:
- name: add-labels
match:
any:
- resources:
kinds:
- Deployment
mutate:
patchStrategicMerge:
spec:
template:
metadata:
labels:
CostCenter: IT
A

match.any.resources.kinds: [Deployment]は、このClusterPolicyをクラスター全体のすべてのDeploymentリソースに対象としています

B

mutateはリソースの作成中に変更を行います(validateがブロック/許可するのに対して)。patchStrategicMerge.spec.template.metadata.labels.CostCenter: ITは、すべてのDeploymentのPodテンプレートラベルに自動的にCostCenter: ITを追加します

以下のコマンドを使用して上記のポリシーを作成しましょう:

~$kubectl apply -f ~/environment/eks-workshop/modules/security/kyverno/simple-policy/add-labels-mutation-policy.yaml
 
clusterpolicy.kyverno.io/add-labels created

ミューテーションウェブフックを検証するために、ラベルを明示的に追加せずにcartsのDeploymentをロールアウトしてみましょう:

~$kubectl -n carts rollout restart deployment/carts
deployment.apps/carts restarted
~$kubectl -n carts rollout status deployment/carts
deployment "carts" successfully rolled out

ポリシー要件を満たすためにcartsのDeploymentのPodテンプレートにCostCenter=ITラベルが自動的に追加されたことを検証します:

~$kubectl -n carts get deployment carts -o jsonpath='{.spec.template.metadata.labels}' | jq
{
  "CostCenter": "IT",
  "app.kubernetes.io/component": "service",
  "app.kubernetes.io/created-by": "eks-workshop",
  "app.kubernetes.io/instance": "carts",
  "app.kubernetes.io/name": "carts"
}

ラベルはcartsのDeploymentのPodテンプレートに自動的に注入されました。KyvernoポリシーでpatchStrategicMergeおよびpatchesJson6902パラメータを使用して、Amazon EKSクラスター内の既存のリソースを変更することも可能です。

これはKyvernoを使用してDeploymentを検証および変更するシンプルな例でした。今後のラボでは、Pod Security Standardsの適用やコンテナイメージレジストリの制限など、より高度なユースケースを探索します。