Documentskyverno
Webhook Lifecycle Management
Webhook Lifecycle Management
Type
Topic
Status
Published
Created
Jul 7, 2026
Updated
Jul 7, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

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):

ResourceName
ValidatingWebhookConfigurationkyverno-resource-validating-webhook-cfg
ValidatingWebhookConfigurationkyverno-policy-validating-webhook-cfg
ValidatingWebhookConfigurationkyverno-exception-validating-webhook-cfg
ValidatingWebhookConfigurationkyverno-cel-exception-validating-webhook-cfg
ValidatingWebhookConfigurationkyverno-global-context-validating-webhook-cfg
ValidatingWebhookConfigurationkyverno-cleanup-validating-webhook-cfg
ValidatingWebhookConfigurationkyverno-ttl-validating-webhook-cfg
MutatingWebhookConfigurationkyverno-resource-mutating-webhook-cfg
MutatingWebhookConfigurationkyverno-policy-mutating-webhook-cfg
MutatingWebhookConfigurationkyverno-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 behind IsGoingDown(), 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):

  1. Scale-to-zero (pre-delete-scale-to-zero.yaml, hook-weight 90): runs readiness-checker scale-deploy, scaling all Kyverno deployments to 0 replicas. This causes the running pods' cleanup() to fire via IsGoingDown() (replicas == 0).

  2. Delete webhooks (pre-delete-remove-webhooks.yaml, hook-weight 100): runs readiness-checker delete-webhooks, which lists and individually deletes all MutatingWebhookConfigurations and ValidatingWebhookConfigurations matching 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:

  1. Lists all MutatingWebhookConfigurations with that selector and deletes each .
  2. Lists all ValidatingWebhookConfigurations with 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#

FilePurpose
cmd/readiness-checker/main.godelete-webhooks command implementation
pkg/webhooks/server.goIn-process Stop() / cleanup()
pkg/utils/runtime/utils.goIsGoingDown() logic
pkg/controllers/webhook/utils.goobjectMeta() label injection
pkg/config/config.goWebhook configuration name constants
charts/kyverno/templates/hooks/pre-delete-remove-webhooks.yamlHelm pre-delete Job (delete-webhooks)
charts/kyverno/templates/hooks/pre-delete-scale-to-zero.yamlHelm pre-delete Job (scale-to-zero)