Tegnap kijött a Kyverno 1.17, a lényeg pedig az, hogy a CEL-alapú policy típusok mostantól GA státuszúak. Ha eddig JMESPath-os ClusterPolicy erőforrásokkal dolgoztál, készülj. Hivatalosan deprecated-ek, és a v1.20-ban (2026 október) kikerülnek.
Ma egy teljes napot rászántam egy éles cluster migrálására, amiben kb. 60 szabályzat volt. Így nézett ki a gyakorlatban.
Miért fontos ez?
A Kyverno évek óta JMESPath kifejezéseket használ. Működnek, de Kyverno-specifikusak. A CEL (Common Expression Language) az, amit maga a Kubernetes is használ a ValidatingAdmissionPolicy-hoz az 1.30-as verzió óta. A CEL-re váltással a Kyverno igazodik az upstreamhez, és érezhetően jobb teljesítményt kap.
A régi módszer:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-labels
spec:
rules:
- name: check-team-label
match:
any:
- resources:
kinds:
- Pod
validate:
message: "A 'team' label kötelező."
pattern:
metadata:
labels:
team: "?*"
Az új:
apiVersion: policies.kyverno.io/v1
kind: ValidatingPolicy
metadata:
name: require-labels
spec:
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
operations: ["CREATE", "UPDATE"]
validations:
- expression: "has(object.metadata.labels) && 'team' in object.metadata.labels && object.metadata.labels['team'] != ''"
message: "A 'team' label kötelező."
Bőbeszédűbb? Igen. De ugyanaz a nyelv, amit a natív Kubernetes admission policy-knál is használsz, így egy DSL-lel kevesebbet kell fejben tartani.
A migráció: mi történt valójában
1. lépés: Kyverno frissítés
helm repo update kyverno
helm upgrade kyverno kyverno/kyverno \
--namespace kyverno-system \
--version 1.17.0 \
--set admissionController.replicas=3
Maga az upgrade tiszta volt. Nincs CRD ütközés, a helm upgrade-en kívül nem kellett restart. A régi és az új API verzió egyszerre működik, szóval az első napon semmi nem törik el.
2. lépés: Leltár
Mielőtt bármit piszkáltam volna, kigyűjtöttem, mi van:
kubectl get clusterpolicy -o name | wc -l
# 47
kubectl get policy -A -o name | wc -l
# 15
62 policy összesen. Kategorizáltam:
- Csak validáció (38): egyenes út a
ValidatingPolicy-hoz - Mutáció (16): mostantól
MutatingPolicy, itt lett trükkös - Generálás (8):
GeneratingPolicy, többnyire ConfigMap és NetworkPolicy generátorok
3. lépés: Az átírás
A validációs policy-knál az új kyverno.io-s migrációs útmutató egész jó. A legtöbb pattern közvetlenül lefordítható:
JMESPath pattern → CEL kifejezés
# Régi: pattern alapú
validate:
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
# Új: CEL kifejezés
validations:
- expression: >-
object.spec.containers.all(c,
has(c.resources) &&
has(c.resources.limits) &&
'memory' in c.resources.limits
)
message: "Minden containernek kell memory limit."
Az all() makró a legjobb barátod, amikor containereken iterálsz.
4. lépés: Mutációs policy-k, itt égtem meg
A régi patchStrategicMerge egyszerű volt. Szó szerint leírtad a YAML-t, amit be akartál injektálni. Az új MutatingPolicy CEL mutációkat használ, amik inkább JSONPatch-ek CEL-ben kifejezve:
apiVersion: policies.kyverno.io/v1
kind: MutatingPolicy
metadata:
name: inject-sidecar-proxy
spec:
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
operations: ["CREATE"]
mutations:
- patchType: JSONPatch
jsonPatch:
expression: >-
[
JSONPatch{op: "add", path: "/metadata/labels/injected-proxy", value: "true"},
JSONPatch{op: "add", path: "/spec/containers/-",
value: object{
"name": "proxy-sidecar",
"image": "envoyproxy/envoy:v1.32-latest",
"ports": [object{"containerPort": 15001}]
}
}
]
Buktató #1: Ha tömbbe patchelsz (pl. container hozzáadás), a /spec/containers/- path működik, de az érték összerakása CEL-ben más, mint sima JSON-ban. Az object{} literál szintaxisát egy ideig tartott megfejteni. A doksi még nem túl bőkezű a komplex, beágyazott objektumos példákkal.
Buktató #2: A patchStrategicMerge-nek nincs közvetlen CEL megfelelője. Ha arra építettél, hogy a strategic merge szemantika szerint olvadnak össze a dolgok (pl. meglévő env változókhoz hozzáadás felülírás nélkül), akkor explicit JSONPatch műveletekre kell átalakítanod. Ez kb. 4 óra volt a napomból.
Namespace-szintű szabályzatok: a multi-tenancy győzelem
A feature, ami a legjobban feldobott: NamespacedMutatingPolicy és NamespacedGeneratingPolicy. Eddig csak cluster adminok írhattak mutációs szabályokat. Mostantól a namespace tulajdonosok is definiálhatják a sajátjaikat:
apiVersion: policies.kyverno.io/v1
kind: NamespacedMutatingPolicy
metadata:
name: team-defaults
namespace: team-alpha
spec:
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
operations: ["CREATE"]
mutations:
- patchType: JSONPatch
jsonPatch:
expression: >-
[
JSONPatch{op: "add", path: "/metadata/labels/cost-center", value: "alpha-2026"}
]
Nálunk minden csapat namespace-nek van egy dedikált service accountja RBAC-kel a saját Namespaced*Policy erőforrásaihoz. A platform csapat továbbra is a cluster-szintű policy-kat kezeli. Tiszta szétválasztás.
Új CEL függvények, amiket érdemes ismerni
A Kyverno 1.17 tényleg hasznos CEL kiterjesztéseket hoz:
# Érték hash-elése (titkokhoz vagy checksum összehasonlításhoz)
sha256("my-config-data")
# x509 tanúsítványok dekódolása és vizsgálata inline
x509.decode(object.data["tls.crt"]).notAfter
# Időalapú szabályzatok (pl. telepítés tiltása munkaidőn kívül)
time.now().getDayOfWeek() >= 1 && time.now().getDayOfWeek() <= 5
# Beágyazott JSON/YAML parse-olása annotációkból
json.unmarshal(object.metadata.annotations["config"]).replicas > 0
Az x509.decode() zseniális tanúsítvány-validációs policy-khoz. Eddig egy custom controllerrel csináltuk, most háromsoros policy.
Teljesítmény: érezhetően gyorsabb
Tudományos benchmarkom nincs, de a webhook válaszidők a Prometheus dashboardjainkon leestek. Migráció előtt a p99 admission webhook latency kb. 45ms volt. CEL policy-kra váltás után: nagyjából 18ms. A CEL kifejezések egyszer fordulnak le és cache-elődnek, a JMESPath meg minden kiértékeléskor interpretálódott.
Egy clusternél, ami percenként ~200 pod-ot hoz létre, ez összeadódik.
Migrációs checklist
Ha tervezed, itt van, amit az első napon szerettem volna tudni:
- Ne kapkodj. Mindkét API egyszerre működik. 2026 októberig van időd.
- Kezdd a validációs policy-kkal. Ezek a legegyszerűbben konvertálhatók.
- A mutációs policy-kat először
Auditmódban teszteld. A viselkedés finoman eltérhet apatchStrategicMerge-től. - Használj
kubectl apply --dry-run=server-t a CEL szintaktikai hibák kiszűrésére, mielőtt élesbe mennének. - Nézd meg az új policy katalógust. A Kyverno 300+ minta policy-t szállít, immár CEL változatokkal.
- Figyeld a deprecation ütemtervet. v1.18 (2026 április) = már csak kritikus javítások a régi API-khoz.
Összegzés
Ez tipikusan olyan upgrade, ami gyorsan megtérül. A CEL igazodás az upstream Kuberneteshez kevesebb kontextusváltást, jobb teljesítményt és valódi multi-tenancy támogatást jelent. A migráció nem fájdalommentes, különösen a mutációs policy-knál, de jól kezelhető, ha fázisokban csinálod.
Ha még Kyverno < 1.16-ot futtatsz, érdemes egyenesen 1.17-re ugrani, most, hogy minden GA. Nincs értelme béta CEL API-kat adoptálni, ha stabilak is elérhetők.
Kezdj el migrálni. A régi API-k nem lesznek itt örökké.