Webhook Lifecycle Management#
Kyverno dynamically creates and maintains Kubernetes MutatingWebhookConfiguration and ValidatingWebhookConfiguration resources to intercept admission requests. These configurations must be cleaned up when Kyverno shuts down or is uninstalled — otherwise stale webhooks block cluster operations. Cleanup happens via two independent paths: in-process cleanup during pod termination, and Helm pre-delete hooks during chart uninstallation.
Managed-By Label#
Every webhook configuration created by Kyverno is stamped with the label webhook.kyverno.io/managed-by=kyverno (constants: kyverno.LabelWebhookManagedBy / kyverno.ValueKyvernoApp ). This label is applied unconditionally by the objectMeta helper in pkg/controllers/webhook/utils.go, which merges it over any caller-supplied labels. All cleanup operations use this label as their selector, so any webhook configuration missing this label is left untouched.
Named Webhook Configurations#
The following webhook configurations are managed by Kyverno (defined in pkg/config/config.go):
| Resource | Name |
|---|---|
ValidatingWebhookConfiguration | kyverno-resource-validating-webhook-cfg |
ValidatingWebhookConfiguration | kyverno-policy-validating-webhook-cfg |
ValidatingWebhookConfiguration | kyverno-exception-validating-webhook-cfg |
ValidatingWebhookConfiguration | kyverno-cel-exception-validating-webhook-cfg |
ValidatingWebhookConfiguration | kyverno-global-context-validating-webhook-cfg |
ValidatingWebhookConfiguration | kyverno-cleanup-validating-webhook-cfg |
ValidatingWebhookConfiguration | kyverno-ttl-validating-webhook-cfg |
MutatingWebhookConfiguration | kyverno-resource-mutating-webhook-cfg |
MutatingWebhookConfiguration | kyverno-policy-mutating-webhook-cfg |
MutatingWebhookConfiguration | kyverno-verify-mutating-webhook-cfg |
Path 1: In-Process Cleanup on Shutdown#
When a Kyverno pod shuts down, the webhook server's Stop() method calls cleanup(ctx), which conditionally deletes all managed webhooks. The condition is runtime.IsGoingDown() : it returns true when the Kyverno Deployment has a deletion timestamp set or its spec.replicas is scaled to zero. Debug mode bypasses this check (always returns false).
When going down, cleanup() issues DeleteCollection calls with the webhook.kyverno.io/managed-by=kyverno label selector for both ValidatingWebhookConfigurations and MutatingWebhookConfigurations . It also deletes the kyvernopre-lock and kyverno-health coordination leases.
Note: The
cleanup()is gated behindIsGoingDown(), so normal pod restarts and rolling updates do not delete webhooks.
Path 2: Helm Pre-Delete Hooks (Uninstall)#
When Kyverno is removed via helm uninstall, two Jobs run in sequence using hook weights (both gated on webhooksCleanup.enabled: true in values.yaml):
-
Scale-to-zero (
pre-delete-scale-to-zero.yaml, hook-weight90): runsreadiness-checker scale-deploy, scaling all Kyverno deployments to 0 replicas. This causes the running pods'cleanup()to fire viaIsGoingDown()(replicas == 0). -
Delete webhooks (
pre-delete-remove-webhooks.yaml, hook-weight100): runsreadiness-checker delete-webhooks, which lists and individually deletes allMutatingWebhookConfigurationsandValidatingWebhookConfigurationsmatching the label selector. This catches any configurations that survived in-process cleanup.
Both Jobs use the admission-controller ServiceAccount , restartPolicy: Never, and backoffLimit: 2 . The hook-delete-policy is before-hook-creation,hook-succeeded,hook-failed, so old Job objects are cleaned up automatically .
readiness-checker delete-webhooks Command#
The runDeleteWebhooks() function in cmd/readiness-checker/main.go accepts a --label flag (default: webhook.kyverno.io/managed-by=kyverno) and:
- Lists all
MutatingWebhookConfigurationswith that selector and deletes each . - Lists all
ValidatingWebhookConfigurationswith that selector and deletes each .
The label flag makes it possible to target a custom label selector at deploy time, though the default covers the standard Kyverno installation.
Key Source Files#
| File | Purpose |
|---|---|
cmd/readiness-checker/main.go | delete-webhooks command implementation |
pkg/webhooks/server.go | In-process Stop() / cleanup() |
pkg/utils/runtime/utils.go | IsGoingDown() logic |
pkg/controllers/webhook/utils.go | objectMeta() label injection |
pkg/config/config.go | Webhook configuration name constants |
charts/kyverno/templates/hooks/pre-delete-remove-webhooks.yaml | Helm pre-delete Job (delete-webhooks) |
charts/kyverno/templates/hooks/pre-delete-scale-to-zero.yaml | Helm pre-delete Job (scale-to-zero) |