Bonjour,
Dans cet article, je vais vous présenter un autre « policy engine » pour Kubernetes. Dans un précédent article, j’avais pu vous présenter la solution OPA Gatekeeper. Dans cet article, nous porterons une attention particulière au projet Kyverno. Ce projet est supporté par la CNCF Foundation dans la catégorie « Sandbox ».
Les principaux avantages d’utiliser la solution Kyverno versus OPA Gatekeeper sont:
- Ne pas ré-apprendre un nouveau langage, les policies Kyverno sont des resources Kubernetes. Comme pour OPA Gatekeeper, ces policies peuvent être déployées en mode « audit » ou « enforce ».
- En plus de la validation, Kyverno supporte également la mutation et la génération de resources.
Dans cet exemple, je vous présente comment déployer la solution Kyverno ainsi que comment créer et déployer une policy qui a comme objectif de forcer l’application d’un label lors de la création d’un resource group. J’avais pu vous présenter un exemple similaire au sein de l’article: AKS | OPA
Déployer Kyverno:
max@Azure:~$ kubectl create -f https://raw.githubusercontent.com/kyverno/kyverno/main/definitions/release/install.yaml namespace/kyverno created customresourcedefinition.apiextensions.k8s.io/clusterpolicies.kyverno.io created customresourcedefinition.apiextensions.k8s.io/clusterpolicyreports.wgpolicyk8s.io created customresourcedefinition.apiextensions.k8s.io/clusterreportchangerequests.kyverno.io created customresourcedefinition.apiextensions.k8s.io/generaterequests.kyverno.io created customresourcedefinition.apiextensions.k8s.io/policies.kyverno.io created customresourcedefinition.apiextensions.k8s.io/policyreports.wgpolicyk8s.io created customresourcedefinition.apiextensions.k8s.io/reportchangerequests.kyverno.io created serviceaccount/kyverno-service-account created clusterrole.rbac.authorization.k8s.io/kyverno:admin-policies created clusterrole.rbac.authorization.k8s.io/kyverno:admin-policyreport created clusterrole.rbac.authorization.k8s.io/kyverno:admin-reportchangerequest created clusterrole.rbac.authorization.k8s.io/kyverno:customresources created clusterrole.rbac.authorization.k8s.io/kyverno:generatecontroller created clusterrole.rbac.authorization.k8s.io/kyverno:policycontroller created clusterrole.rbac.authorization.k8s.io/kyverno:userinfo created clusterrole.rbac.authorization.k8s.io/kyverno:webhook created clusterrolebinding.rbac.authorization.k8s.io/kyverno:customresources created clusterrolebinding.rbac.authorization.k8s.io/kyverno:generatecontroller created clusterrolebinding.rbac.authorization.k8s.io/kyverno:policycontroller created clusterrolebinding.rbac.authorization.k8s.io/kyverno:userinfo created clusterrolebinding.rbac.authorization.k8s.io/kyverno:webhook created configmap/init-config created service/kyverno-svc created deployment.apps/kyverno created
Créer notre policy:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-ns-labels
spec:
validationFailureAction: enforce
rules:
- name: require-ns-labels
match:
resources:
kinds:
- Namespace
validate:
message: "The label my-app is required."
pattern:
metadata:
labels:
my-app: "?*"
max@Azure:~/clouddrive$ kubectl apply -f ns-label.yaml clusterpolicy.kyverno.io/require-ns-labels created
Test:
max@Azure:~/clouddrive$ kubectl create namespace maxime Error from server: admission webhook "validate.kyverno.svc" denied the request: resource Namespace//maxime was blocked due to the following policies require-ns-labels: require-ns-labels: 'validation error: The label my-app is required. Rule require-ns-labels failed at path /metadata/labels/' max@Azure:~/clouddrive$ kubectl apply -f namespace.yaml namespace/maxime created max@Azure:~/clouddrive$ kubectl get ns --show-labels NAME STATUS AGE LABELS default Active 31m kube-node-lease Active 31m kube-public Active 31m kube-system Active 31m addonmanager.kubernetes.io/mode=Reconcile,control-plane=true,kubernetes.io/cluster-service=true kyverno Active 20m maxime Active 2m36s my-app=maxapp
Lister les policies:
max@Azure:~/clouddrive$ kubectl get cpol
NAME BACKGROUND ACTION
require-ns-labels true enforce
max@Azure:~/clouddrive$ kubectl describe cpol require-ns-labels
Name: require-ns-labels
Namespace:
Labels:
Annotations: pod-policies.kyverno.io/autogen-controllers: DaemonSet,Deployment,Job,StatefulSet,CronJob
API Version: kyverno.io/v1
Kind: ClusterPolicy
Metadata:
Creation Timestamp: 2020-12-31T20:39:24Z
Generation: 1
Managed Fields:
API Version: kyverno.io/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:validationFailureAction:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2020-12-31T20:39:24Z
API Version: kyverno.io/v1
Fields Type: FieldsV1
fieldsV1:
f:spec:
f:rules:
f:status:
.:
f:averageExecutionTime:
f:resourcesBlockedCount:
f:ruleStatus:
f:rulesAppliedCount:
f:rulesFailedCount:
Manager: kyverno
Operation: Update
Time: 2020-12-31T20:46:35Z
Resource Version: 4981
Self Link: /apis/kyverno.io/v1/clusterpolicies/require-ns-labels
UID: 0c6e3e76-307b-4f6e-884c-73708e740bde
Spec:
Background: true
Rules:
Match:
Resources:
Kinds:
Namespace
Name: require-ns-labels
Validate:
Message: The label my-app is required.
Pattern:
Metadata:
Labels:
My - App: ?*
Validation Failure Action: enforce
Status:
Average Execution Time: 165.212µs
Resources Blocked Count: 2
Rule Status:
Applied Count: 2
Average Execution Time: 165.212µs
Failed Count: 2
Resources Blocked Count: 2
Rule Name: require-ns-labels
Rules Applied Count: 2
Rules Failed Count: 2
Events:
Supprimer une policy:
max@Azure:~/clouddrive$ kubectl delete cpol require-ns-labels
clusterpolicy.kyverno.io "require-ns-labels" deleted
maxl@Azure:~/clouddrive$ kubectl get cpol
No resources found
Créer une policy en audit mode:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: audit-ns-labels
spec:
validationFailureAction: audit
rules:
- name: audit-ns-labels
match:
resources:
kinds:
- Namespace
validate:
message: "The label my-app is required."
pattern:
metadata:
labels:
my-app: "?*"
max@Azure:~/clouddrive$ kubectl apply -f ns-label.yaml
clusterpolicy.kyverno.io/require-ns-labels created
max@Azure:~/clouddrive$ kubectl create namespace maxime
namespace/maxime created
max@Azure:~/clouddrive$ kubectl get cpol
NAME BACKGROUND ACTION
audit-ns-labels true audit
max@Azure:~/clouddrive$ kubectl describe cpol audit-ns-labels
Name: audit-ns-labels
Namespace:
Labels:
Annotations: pod-policies.kyverno.io/autogen-controllers: DaemonSet,Deployment,Job,StatefulSet,CronJob
API Version: kyverno.io/v1
Kind: ClusterPolicy
Metadata:
Creation Timestamp: 2020-12-31T21:02:50Z
Generation: 1
Managed Fields:
API Version: kyverno.io/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:spec:
.:
f:validationFailureAction:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2020-12-31T21:02:50Z
API Version: kyverno.io/v1
Fields Type: FieldsV1
fieldsV1:
f:spec:
f:rules:
f:status:
.:
f:averageExecutionTime:
f:ruleStatus:
f:rulesFailedCount:
Manager: kyverno
Operation: Update
Time: 2020-12-31T21:04:35Z
Resource Version: 7592
Self Link: /apis/kyverno.io/v1/clusterpolicies/audit-ns-labels
UID: 13bc5039-f6ac-4214-aa1a-40ddd932b39c
Spec:
Background: true
Rules:
Match:
Resources:
Kinds:
Namespace
Name: audit-ns-labels
Validate:
Message: The label my-app is required.
Pattern:
Metadata:
Labels:
My - App: ?*
Validation Failure Action: audit
Status:
Average Execution Time: 26.002µs
Rule Status:
Average Execution Time: 26.002µs
Failed Count: 2
Rule Name: audit-ns-labels
Rules Failed Count: 2
Events:
Vous pouvez retrouver une suite d’exemples de policies à l’adresse ci-dessous: https://github.com/kyverno/kyverno/tree/main/samples
En conclusion, nous pouvons constater que Kyverno est une solution très intéressante et simple d’utilisation. A noter qu’une fonctionnalité de reporting est en cours de développement. Je reviendrai vous présenter cette fonctionnalité dans un prochain article.
Maxime.
