痛点
Kubernetes 集群治理离不开准入控制策略——限制特权容器、强制资源 Limits、禁止 latest 标签等。传统方案 OPA Gatekeeper 功能强大,但 Rego 语言学习曲线陡峭,运维团队写一条策略往往要翻半天文档。ValidatingAdmissionPolicy(CEL)虽是原生方案,但仅支持验证、不支持资源变更(Mutate),且需要 K8s 1.30+ 才 GA。
核心矛盾:运维需要快速落地策略,但现有工具要么门槛高,要么能力不够。
Kyverno 用纯 YAML/JSON 编写策略,零学习新语言成本,同时覆盖 Validate/Mutate/Generate/Cleanup 四大场景,已成为 CNCF Graduated 项目。
方案
Kyverno 采用 Kubernetes-native 设计——策略本身就是 CRD(ClusterPolicy / Policy),运维像写 Deployment 一样写策略,kubectl apply 即生效。
核心能力矩阵:
| 能力 | OPA Gatekeeper | Kyverno | ValidatingAdmissionPolicy |
|---|---|---|---|
| 验证 (Validate) | ✅ Rego | ✅ YAML | ✅ CEL |
| 变更 (Mutate) | ❌ | ✅ | ❌ |
| 生成 (Generate) | ❌ | ✅ | ❌ |
| 清理 (Cleanup) | ❌ | ✅ | ❌ |
| 语言 | Rego | YAML | CEL |
| 最低 K8s 版本 | 1.16 | 1.25 | 1.30 |
实操步骤
第 1 步:安装 Kyverno(Helm)
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno \
--namespace kyverno --create-namespace \
--set replicaCount=3 \
--set admissionController.replicas=3 \
--set backgroundController.replicas=2 \
--set resources.limits.memory=512Mi \
--set resources.limits.cpu=500m
生产环境建议至少 3 副本保证高可用,避免单点导致 API Server 请求阻塞。
第 2 步:禁止特权容器(Validate 策略)
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged-containers
annotations:
policies.kyverno.io/severity: high
spec:
validationFailureAction: Enforce # Audit 仅告警,Enforce 直接拒绝
background: true
rules:
- name: deny-privileged
match:
any:
- resources:
kinds:
- Pod
validate:
message: "特权容器被禁止,请移除 securityContext.privileged 或设为 false"
pattern:
spec:
containers:
- securityContext:
privileged: "!true"
kubectl apply -f disallow-privileged.yaml
# 测试:尝试创建特权 Pod
kubectl run test --image=nginx --overrides='{"spec":{"containers":[{"name":"test","image":"nginx","securityContext":{"privileged":true}}]}}'
# 预期输出: Error - admission webhook denied the request
第 3 步:自动注入资源 Limits(Mutate 策略)
开发者经常忘记设置资源限制,Kyverno 可自动注入默认值:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-resources
spec:
rules:
- name: add-default-limits
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
spec:
containers:
- (name): "*"
resources:
limits:
+(memory): "512Mi"
+(cpu): "500m"
requests:
+(memory): "128Mi"
+(cpu): "100m"
+() 语法表示「仅在字段不存在时添加」,不会覆盖已设置的值。
第 4 步:自动生成 NetworkPolicy(Generate 策略)
每个新 Namespace 自动创建默认拒绝入站流量的 NetworkPolicy:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-default-deny-networkpolicy
spec:
rules:
- name: default-deny-ingress
match:
any:
- resources:
kinds:
- Namespace
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
generate:
synchronize: true
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
name: default-deny-ingress
namespace: "{{request.object.metadata.name}}"
data:
spec:
podSelector: {}
policyTypes:
- Ingress
synchronize: true 确保策略源变更时自动同步到所有已生成资源。
第 5 步:策略报告与合规巡检
Kyverno 后台扫描已有资源并生成 PolicyReport CRD:
# 查看集群级策略报告
kubectl get clusterpolicyreport -o wide
# 查看某 Namespace 违规详情
kubectl get policyreport -n production -o yaml | grep -A5 "result: fail"
# 配合 Prometheus 采集策略指标
# Kyverno 内置 /metrics 端点,关键指标:
# kyverno_admission_requests_total{action="enforce|audit"}
# kyverno_policy_results_total{rule_result="pass|fail|warn"}
避坑指南
坑 1:Webhook 超时导致 API Server 请求全挂
Kyverno 宕机时 Webhook failurePolicy 默认 Fail,会阻塞所有资源创建。生产环境建议:
# Helm values
admissionController:
failurePolicy: Ignore # 宕机时放行,优于全集群不可用
同时配置 PDB 确保至少 2 副本存活。
坑 2:Mutate 策略顺序问题
多条 Mutate 策略可能互相冲突。用 spec.rules[].preconditions 做条件判断,并通过 Policy 的 annotation pod-policies.kyverno.io/autogen-controllers 控制自动生成逻辑。
坑 3:Background Scan 对大集群性能影响
超过 5000 Pod 的集群,首次全量扫描会占用大量内存。解决方案:
# 限制后台扫描并发
backgroundController:
resources:
limits:
memory: 1Gi
# 或按 Namespace 分批启用
spec:
background: false # 先关闭后台扫描,仅对新资源生效
总结
Kyverno 的核心优势是零新语言成本——YAML 写策略、kubectl 管理、CRD 存储,完全融入 K8s 原生工作流。对于已有 OPA Gatekeeper 的团队,建议渐进迁移:先用 Kyverno 的 Mutate/Generate 能力补充 OPA 的短板,再逐步替换 Validate 策略。
推荐落地路径: Audit 模式上线 → PolicyReport 观测违规 → 逐步切 Enforce → 配合 CI 在 PR 阶段预检(kyverno apply --cluster=false)。