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.