Kubernetes策略引擎Kyverno安装指南:从入门到生产实践 如果你维护过一套多团队共用的 Kubernetes 生产集群下面这些场景你一定不陌生开发提交的 Deployment 忘了写resources限制一下把节点内存打满新接入的命名空间没有按规范打标签导致监控和计费对不上某个工作负载悄悄以 root 权限在跑直到安全巡检才发现。我之前处理这些问题的办法很原始——要么靠人肉 review要么用脚本轮询 API 做检查费时费力还容易漏。后来在 k8s 平台上逐步引入 Kyverno 这个组件整套策略管控流程才算真正跑起来。这篇文章就记录我在 Kubernetes 集群中完整安装 Kyverno 的过程包括选型思路、版本匹配、安装步骤、验证方法以及我踩过的坑和排查技巧。适合正在做平台建设、安全合规、想要把“准入控制”这件事落到实处的 k8s 管理员、SRE 和 DevOps 工程师参考。1. 为什么要装 Kyverno策略引擎解决的是 k8s 平台的“门禁”问题1.1 Kyverno 到底是什么为什么我选它而不是 GatekeeperKyverno 是一个运行在 Kubernetes 集群内部的策略引擎由 Nirmata 团队开源目前是 CNCF 的孵化项目。它的核心能力是在资源创建、更新、删除的准入阶段拦截请求按照你定义的策略自动做校验validate、变更mutate、生成generate、清理cleanup等操作。用人话说它就是一个门禁系统——只有符合规则的工作负载才允许进集群。第一次接触 Kyverno 的人通常会拿它和 OPA Gatekeeper 做对比。坦率讲Gatekeeper 确实是老牌方案背后有强大的 OPA 生态但它的策略必须用 Rego 语言编写。Rego 的学习曲线有多陡峭写过的人都知道——我最初研究 Gatekeeper 时花了一周时间才把deny规则写得顺手而且一旦策略复杂起来调试成本非常高。Kyverno 的策略则是纯 YAML和kubectl原生工作流完全一致你可以直接把策略文件丢给开发 review几乎不需要额外解释。这个差异在落地时非常关键因为大多数平台团队的成员并不是全职的策略开发人员YAML 策略的可读性和维护成本要友好太多。另外Kyverno 的策略模型是“贴近资源”的。它允许你在match里直接写kind: Pod、kind: Deployment规则里直接写资源字段的匹配模式不需要先学习一套抽象语法。我见过很多团队从 Gatekeeper 迁到 Kyverno核心原因就是“策略本身变成了一种任何人都能读懂的规范”。当然我并不是说 Gatekeeper 一无是处如果你的团队已经有成熟的 OPA 技术栈继续用没问题但如果是从零开始做策略治理我会毫不犹豫推荐 Kyverno。1.2 安装前必须理解的核心机制Admission Webhook、CRD、PolicyReport安装 Kyverno 之前我建议你先理解三件事不然出了问题会很懵。第一是 Admission Webhook。Kubernetes 允许通过动态准入控制Dynamic Admission Control拦截 API 请求Kyverno 安装时会注册两类 webhookMutatingAdmissionWebhook和ValidatingAdmissionWebhook。前者在资源持久化之前允许“修改”资源比如自动给 Pod 注入 sidecar后者负责“校验”符合策略就放行不符合就拒绝。Kyverno 的策略本质上就是借助这种机制实现的。第二是 CRD。Kyverno 的核心策略对象是ClusterPolicy集群级和Policy命名空间级它们都是 CRD。安装 Kyverno 时Helm chart 会自动创建这些 CRD。你可能会问为什么不直接用 ConfigMap 存策略因为 CRD 能天然支持校验、状态子资源、RBAC 隔离还能被kubectl get clusterpolicy直接查看这对日常运维太重要了。第三是 PolicyReport。Kyverno 会把策略执行结果聚合为PolicyReport针对命名空间和ClusterPolicyReport针对集群通过kubectl get cpolr就能看到某条策略匹配了多少资源、哪些通过、哪些失败。这个报告机制是 Kyverno 又一个很有竞争力的特性不用额外搭一套系统就能审计。你需要记住一个完整请求链Pod 创建请求 - API Server 调用 mutating webhook - Kyverno 执行 mutate 规则如注入 sidecar- API Server 再调用 validating webhook - Kyverno 执行 validate 规则如检查镜像标签- 通过后写入 etcd。这个概念贯穿整个安装和排障过程后面章节我都会反复引用。2. 环境准备与安装方案选型2.1 版本怎么匹配别再装完才发现不兼容我第一次装 Kyverno 就吃过版本不兼容的亏。当时集群是 Kubernetes 1.25我直接拉了一个最新 chart结果启动后 webhook 反复注册失败日志里一堆failed to call webhook。后来查了兼容性矩阵才发现旧集群里装了要求较新 Kubernetes API 的版本两者的语义不匹配。所以第一步一定是先确认集群版本kubectl version --short我当前实验环境是 Kubernetes 1.28 的三节点集群1 个 master 2 个 worker结合社区支持情况选用了 Kyverno 1.12.1。这里给出一份我整理的版本对照参考Kyverno 版本建议 Kubernetes 版本说明v1.10.x1.23 ~ 1.27较老的稳定线功能完整度不错v1.11.x1.24 ~ 1.28引入 PolicyReport 聚合增强推荐 1.25v1.12.x1.25 ~ 1.29支持 Pod Security 标准集成功能全面v1.13.x1.26 ~ 1.30持续更新特性最多但对集群版本要求更高建议以官方兼容性矩阵为准。一个经验法则如果你的 Kubernetes 版本是 1.26 以下就不要盲目追求最新版 Kyverno选 1.11.x 或 1.12.x 反而更稳。另外如果你是用 Rancher/RKE2 或二进制方式搭建的集群还要确认 API Server 启动参数里没有关闭 admission webhook 相关特性通常默认是开着的但离线内网环境偶尔会有自定义配置。2.2 三种安装方式对比Helm、YAML、OperatorKyverno 官方提供了三种安装方式我实际都用过分别说下感受。第一种是 Helm Chart这是我推荐的方式。kyverno/kyverno这个 chart 是官方维护的参数很丰富比如可以设置副本数、资源限制、service account、证书管理方式等。升级回滚也简单适合生产环境。第二种是纯 YAML 安装即从 GitHub Releases 下载install.yaml然后kubectl create -f。这种方式的优点是干净、直接适合离线环境或快速验证缺点是不方便改参数比如你想开启高可用多副本就得手动改 YAML 文件。不过如果你是用二进制搭建的集群且没有 Helm这种方式也无妨。第三种是 Kyverno Operator官方其实不太建议普通用户直接上 Operator它更多面向需要自动化管理多个 Kyverno 实例的场景。普通集群直接用 Helm 就够了不要为了炫技去装 Operator增加维护负担。我最终选择 Helm 安装除了运维便利还有一个重要原因是Helm 能自动管理 webhook 的证书轮换配置。Kyverno 默认会生成一个自签 CA 和证书用于 webhook 通信如果证书过期而你没有处理机制策略执行会直接“静默失败”。Helm chart 里内置了证书管理逻辑可以自动轮换这是纯 YAML 方式很容易忽略的地方。安装前还需要确认集群能访问外网镜像仓库Kyverno 的镜像如ghcr.io/kyverno/kyverno需要拉取成功。如果是在离线环境需要提前把镜像打到本地仓库并修改 chart 的image参数。3. Kyverno 完整安装步骤实录3.1 添加 Helm 仓库与创建命名空间我的操作习惯是先把 chart 仓库加好顺便看一眼版本列表确认版本号再安装。helm repo add kyverno https://kyverno.github.io/kyverno/ helm repo update helm search repo kyverno/kyverno正常情况下你会看到类似输出NAME CHART VERSION APP VERSION DESCRIPTION kyverno/kyverno 3.2.x 1.12.1 Kubernetes Native Policy Management注意这里 chart version 和 app version 不一样我参考的是 app version。接下来创建命名空间。Kyverno 官方默认使用kyverno命名空间其实名字不重要你用policy-system也可以但为了和社区文档保持一致我建议就用kyverno。kubectl create namespace kyverno有些资料会让你先kubectl create ns再helm install我个人的习惯是直接把--create-namespace参数带上这样即使命名空间不存在也能自动创建后续在 CI/CD 流程里也少一步。3.2 执行 Helm 安装一条命令加上高可用参数基础安装命令非常简单helm install kyverno kyverno/kyverno -n kyverno --create-namespace但如果你直接这么装会发现默认只启动 1 个副本。在生产环境我强烈建议加上副本数和资源限制参数helm install kyverno kyverno/kyverno -n kyverno \ --create-namespace \ --set replicaCount3 \ --set resources.limits.memory1Gi \ --set resources.limits.cpu500m这里解释一下为什么副本数要设置 3。Kyverno 的 webhook 拦截路径是所有 Pod 创建和更新请求的必经之路如果组件本身是单点一旦它挂了集群里所有新建工作负载都会失败。虽然可以通过 webhook 的failurePolicy设置为Ignore来降低影响但生产环境的安全基线一般要求Fail校验失败就拒绝这种时候高可用就是硬需求。安装完成后可以使用helm list -n kyverno确认 release 状态等下一步验证 Pod 起来。这里还有一个小技巧如果你想先看看 chart 会创建哪些对象可以用helm template预渲染 YAML 输出到文件再逐步 review尤其是对安全要求高的环境这个习惯能帮你避免很多“装完不知道多了什么权限”的尴尬。3.3 验证安装结果Pod、Service、Webhook 三连查安装完成后验证是重中之重。我先查 Pod 状态kubectl get pods -n kyverno -o wide正常你会看到kyverno-xxx-xxxxx和kyverno-cleanup-controller-xxx-xxxxx这些 Pod 都处于Running。其中 cleanup controller 负责定期清理过期的策略报告和 webhook 配置别把它当成多余的组件。然后查 Service 和 Endpointskubectl get svc -n kyverno kubectl get endpoints -n kyvernokyverno-svc这个 Service 是 webhook 回调的入口必须保证 Endpoints 里有 Pod 的 IP。如果这里为空说明 Service Selector 或 Pod 标签不匹配后面 webhook 必然失败。最重要的是检查 webhook 配置是否注册成功kubectl get validatingwebhookconfiguration | grep kyverno kubectl get mutatingwebhookconfiguration | grep kyverno你会看到类似kyverno-resource-validating-webhook-cfg、kyverno-resource-mutating-webhook-cfg等条目。如果这些条目不存在说明 Kyverno 启动时注册 webhook 失败了需要立刻看日志。这一步很多人会跳过恰恰是安装后最容易出问题的地方。3.4 创建第一条 ClusterPolicy 验证策略引擎装完之后如果不实际跑一条策略你根本不知道策略引擎是否真正在工作。我来创建一个最简单的策略强制命名空间下的 Pod 必须带有team标签如果没有就打上默认标签。apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: default-team-label spec: validationFailureAction: Enforce background: true rules: - name: inject-team-label match: any: - resources: kinds: - Pod mutate: patchStrategicMerge: metadata: labels: team: default这里暂时用mutate而不是validate目的是先测试“自动变更”链路是否正常。保存为default-team-label.yaml然后创建kubectl apply -f default-team-label.yaml创建后查看策略状态kubectl get clusterpolicy default-team-label配置背景扫描background后Kyverno 会自动对集群里已有的 Pod 做一次扫描看是否满足变更规则。你可以随便创建一个不带team标签的 Pod验证是否被自动打上标签kubectl run test-pod --imagenginx kubectl get pod test-pod -o jsonpath{.metadata.labels.team}如果输出default说明 mutating webhook 链路完全正常。这里我要特别强调validationFailureAction字段要理解清楚Enforce表示不符合策略就拒绝Audit表示只记录不拦截。第一次实验建议先用Audit避免误伤线上资源。3.5 用 policyreport 观察策略执行结果Kyverno 安装后在后台还跑着一个很重要的能力策略报告。也就是我在 1.2 节提到的ClusterPolicyReport。kubectl get cpolr正常情况下你会看到类似下面的内容NAME KIND RESULTS cpolr-default-team-label Pod 3 pass如果结果显示fail说明有资源不满足策略如果结果显示error大概率是策略写错了比如字段路径不匹配。查看具体报告详情kubectl get cpolr cpolr-default-team-label -o yaml报告里会列出每个被扫描资源的通过/失败原因。这一步是 Kyverno 的“杀手级”体验你不用额外部署审计系统直接就能在集群里看到策略执行情况。我安装完成后的标准动作就是创建一条测试策略 - 查看cpolr- 确认日志无报错 - 继续后续配置。4. 安装完成后的“必须做”几件事4.1 先审计再强制validationFailureAction 的切换顺序安装好 Kyverno 后最容易犯的错误是一上来就把所有策略设为Enforce。我见过不止一个团队因为“强制拒绝”上线太激进导致某个业务 Pod 凌晨创建失败然后半夜打电话找平台的同事。正确的做法是先在Audit模式下运行一段时间让策略引擎只记录不拦截。在Audit模式下Kyverno 会把不合规的资源记入 policyreport但不会阻止请求。你每天看一眼报告统计确认没有高危资源被遗漏再逐步把策略改成Enforce。这个切换顺序对生产环境价值很大——你可以在不影响业务的前提下把策略漏洞一个个暴露出来。具体切换方式很简单修改策略的spec.validationFailureAction字段即可spec: validationFailureAction: Enforce需要注意的是mutate类规则不支持Audit因为变更操作要么执行、要么不执行没有“只记录”的状态。你如果想测试 mutate 规则会不会影响业务建议先在测试环境验证或者用kyverno apply在本地模拟执行。4.2 策略报告持久化与告警接入默认情况下PolicyReport 是实时聚合的但如果 Pod 重启或策略报告过多报告可能被清理。生产环境我建议把关键策略报告接入日志或告警系统。一种常见做法是定期导出kubectl get cpolr -o json | jq .items[].results[] | {policy: .policy, message: .message, status: .result}把结果推送到 Elasticsearch 或 Loki结合 Grafana 做定时巡检。另一种方式是使用 Kyverno 的 webhook 事件通知功能配合 Alertmanager 在策略执行失败时发送告警。我在一个实践项目里就这么干过每周一早上定时拉取上周失败的策略报告结合工单系统自动生成整改任务效果非常好。4.3 高可用部署、证书管理与资源限制的进阶配置安装完成后还有三件进阶配置我建议你花时间做。第一确认副本数真的生效。有些用户设置了replicaCount3但kubectl get pods -n kyverno只看到 1 个 Pod很可能是 chart 默认值覆盖了你的参数或者 PDBPodDisruptionBudget限制导致调度失败。使用helm get values kyverno -n kyverno查看实际生效配置。第二证书管理。Kyverno 默认用自签证书并且会定期轮换这个机制大多数场景够用。但如果你们公司安全规范要求证书由内部 CA 统一签发可以关闭内置证书生成改用 cert-manager 管理。相关参数是webhook.selfSignedByDefault。不过我建议除非有明确合规要求否则不要去动证书机制自签证书的方案经过社区大量验证踩坑概率低。第三资源请求与限制。Kyverno 官方默认的资源请求不高但在大规模集群上策略数量多、扫描任务重时很容易出现 OOM。我建议根据集群规模把内存限制从默认值调大比如 1Gi 以上并同步调整resources.requests.cpu到 100m ~ 200m避免限流导致 webhook 超时。如果有节点专门用于系统组件建议给 Kyverno 打上nodeSelector让它只在稳定的系统节点上运行。5. 常见问题与排查技巧实录5.1 webhook 调用失败怎么办症状创建 Pod 时收到Internal error occurred: failed calling webhook validate.kyverno.svc或者干脆超时。排查思路按照“链路三段式”走Webhook 配置是否存在执行kubectl get validatingwebhookconfiguration | grep kyverno如果为空说明 Kyverno 启动时注册失败看组件日志kubectl logs -n kyverno -l app.kubernetes.io/namekyverno --tail100Service 是否解析正常进入任意 Pod 尝试wget或curl访问https://kyverno-svc.kyverno.svc如果解析不了检查 Service 名称和命名空间。Endpoints 是否有 Pod IPkubectl get endpoints -n kyverno如果ENDPOINTS为空重点检查 Pod 是否Running、标签是否匹配 Service Selector。我之前遇到的一个典型案例是集群网络插件是自定义的Pod 之间跨节点通信被 NetworkPolicy 限制了导致 API Server 所在节点无法访问 Kyverno Pod 的 443 端口。排查了半天最后发现是网络策略问题而不是 Kyverno 本身故障。所以遇到 webhook 调用失败先别急着怀疑 Kyverno通路是否可达才是首要检查项。5.2 策略“不生效”时从哪里查起很多人在配置策略后发现“完全不生效”比如规则写了必须带某个标签但没带标签的 Pod 照样创建成功。这种问题多半是以下几个原因。第一策略写错了match范围。比如写了match: resources: kinds: - Deployment但测试时直接kubectl run创建 Pod此时kubectl run底层创建的是 Pod不会匹配 Deployment 规则。建议先kubectl explain Pod.metadata确认字段层级再写策略。第二validationFailureAction为Audit。Audit 模式只报告不拒绝所以创建照样成功。用kubectl get cpolr看看是不是已经在报告里记录了fail如果记录了说明策略在执行只是没拦截。第三Kyverno 自带的 ResourceFilters 把目标命名空间过滤掉了。默认配置会过滤kube-system、kube-public、kyverno等系统命名空间如果你的业务跑在kube-system里策略自然不生效。查看方式kubectl -n kyverno get configmap kyverno -o yaml里面的resourceFilters字段就是全局过滤规则。顺便说一句我自己习惯把 Kyverno 自身的命名空间过滤掉避免它误改自己的 Pod引发连锁故障。5.3 升级、卸载与版本回滚注意事项Kyverno 升级相对简单但有几个坑要避开。升级前先备份现有策略kubectl get clusterpolicy -o yaml clusterpolicies-backup.yaml kubectl get policy -A -o yaml policies-backup.yaml然后执行helm upgrade kyverno kyverno/kyverno -n kyverno --version 新版本如果升级后发现cpolr查不到数据或 webhook 异常可以用helm rollback回滚helm history kyverno -n kyverno helm rollback kyverno revision -n kyverno卸载时不要只helm uninstall。便宜的做法是helm uninstall kyverno -n kyverno kubectl delete namespace kyverno但 webhook configuration 有时不会自动清理干净尤其当你手动改过配置时。建议卸载后手动检查一下kubectl delete validatingwebhookconfiguration -l app.kubernetes.io/part-ofkyverno kubectl delete mutatingwebhookconfiguration -l app.kubernetes.io/part-ofkyverno最后别忘了把测试用的 ClusterPolicy 和 PolicyReport 也一并清理避免残留对象影响后续重新安装。5.4 一个容易忽略的隐患backgroundScan 对存量资源的影响Kyverno 默认开启后台扫描安装后会定期对集群已有资源执行策略检查。这个机制在策略落地时非常有用但也可能引发“存量资源全部暴露问题”的错觉。第一次安装完 Kyverno创建一条严格策略后cpolr可能瞬间出现大量fail记录这些记录不是新故障而是存量历史负债。我的建议是大范围策略上线前先利用 policyreport 做一次存量合规分析把修复任务拆成批次不要让 Kyverno 的失败报告直接触发告警风暴。如果你只想扫描新建资源可以把background: false写进策略里这样策略只对创建/更新操作生效。在升级或变更策略期间如果发现 Kyverno 所在节点 CPU 飙高可以检查是不是大量后台扫描任务集中在同一时间执行。调整策略数量、错开改动时间或者调高资源限额都能缓解。写在最后的几个实践体会这套 Kyverno 安装流程我在测试环境和生产环境反复跑过多次。印象最深的一件事是有次在生产集群装完组件后因为业务方急着需要强制镜像签名校验我直接上了一组Enforce策略结果当天下午就有两三个服务发布失败。后来引导他们看了cpolr里的失败原因发现大部分是历史镜像没有签名。花了整整一个晚上补齐签名。那之后我给自己立了个规矩新环境装完 Kyverno先空跑一周Audit把报告里的问题全部消掉再逐步收紧策略。如果你也想在生产环境落地 Kyverno我建议把策略文件纳入 Git 仓库管理走 MR 评审流程做到任何策略改动都有记录。同时把ClusterPolicyReport的导出任务写成 CronJob定时推送到团队的消息群让平台组每天能直观看到策略执行的合规情况。别忘了定期升级 Kyverno 版本以获取安全修复和新特性但在升级前一定先看helm history确保有可靠回滚点。最后分享一个小技巧配置阶段多用kyverno apply命令在本地验证策略不用反复往集群里提交资源既快又安全。把这条命令加入你的日常工具链之后你写策略的信心会提升一大截。