Kyverno 安装与使用

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。
本文缩写(英文全称与中文含义)
缩写 英文全称/名称 中文含义
AKS Azure Kubernetes Service Azure 托管 Kubernetes 服务
API Application Programming Interface 应用程序编程接口
CRD Custom Resource Definition Kubernetes 自定义资源定义
EKS Elastic Kubernetes Service AWS 托管 Kubernetes 服务
RBAC Role-Based Access Control 基于角色的访问控制
YAML YAML Ain’t Markup Language 常用于配置文件的数据序列化语言

Kyverno 是什么#

Kyverno 是 Kubernetes 的策略引擎,可用 YAML 编写资源校验、资源修改、资源生成和镜像校验策略。例如要求工作负载带有团队标签,或限制允许使用的镜像仓库。本文使用 kyverno.io/v1 的 ClusterPolicy,演示从审计到拦截的完整流程。

工具 主要作用 示例
Kyverno 在资源准入阶段执行策略,并检查已有资源 拒绝不符合规范的 Pod
Falco 检测节点和容器运行时的异常行为 容器内出现可疑文件操作时告警

安装准备#

准备可访问的 Kubernetes 测试集群、kubectl 和 Helm,以及创建 CRD、集群角色和 Webhook 的权限。先确认操作的集群:

kubectl config current-context
kubectl version
kubectl get nodes
helm version

Kyverno 与 Kubernetes 的兼容范围随版本变化,应先查看官方版本兼容信息。下面查询并手动选择 Chart 版本;Chart 版本与 Kyverno 应用版本不是同一概念。

使用 Helm 安装#

Kyverno 应安装在专用命名空间中。以下是测试环境安装流程,生产环境的副本和平台设置请参考官方安装文档。

helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm search repo kyverno/kyverno --versions

# 将占位值替换为上一步选定且与集群兼容的 Chart 版本。
export KYVERNO_CHART_VERSION='<选定的 Chart 版本>'
helm show chart kyverno/kyverno --version "$KYVERNO_CHART_VERSION"
helm show values kyverno/kyverno --version "$KYVERNO_CHART_VERSION" > kyverno-default-values.yaml

创建 kyverno-values.yaml:

admissionController:
  replicas: 1
backgroundController:
  replicas: 1
cleanupController:
  replicas: 1
reportsController:
  replicas: 1

安装并等待控制器就绪:

helm upgrade --install kyverno kyverno/kyverno --namespace kyverno --create-namespace --version "$KYVERNO_CHART_VERSION" -f kyverno-values.yaml --wait --timeout 5m

kubectl -n kyverno get deployments,pods
kubectl get crd clusterpolicies.kyverno.io

生产环境可将 admission controller 设置为 3 副本,其余控制器设置为 2 副本,并按所选 Chart 检查反亲和性、资源配置和 PodDisruptionBudget。API Server 还必须能连接 Kyverno Webhook;EKS、AKS 等环境需要核对平台网络设置。

示例:要求 Pod 带有 app 标签#

1. 创建测试命名空间和审计策略#

kubectl create namespace kyverno-demo

将以下内容保存为 require-app-label.yaml。虽然 ClusterPolicy 是集群级资源,但这里通过 namespaces 将匹配范围限制为测试命名空间。关闭自动生成控制器规则,使示例只针对 Pod,方便观察结果。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: demo-require-app-label
  annotations:
    pod-policies.kyverno.io/autogen-controllers: none
spec:
  background: true
  rules:
    - name: require-app-label
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - kyverno-demo
      validate:
        failureAction: Audit
        message: "Pod 必须设置非空的 metadata.labels.app 标签。"
        pattern:
          metadata:
            labels:
              app: "?*"
kubectl apply -f require-app-label.yaml
kubectl wait --for=condition=Ready clusterpolicy/demo-require-app-label --timeout=60s

Audit 允许请求通过并记录违规,Enforce 拒绝不合规的新建请求。这里使用规则级 validate.failureAction;旧的 spec.validationFailureAction 已弃用。模式匹配和既有资源的行为详见校验规则文档。

2. 创建不合规 Pod,查看审计结果#

保存为 pod-without-label.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: missing-app
  namespace: kyverno-demo
spec:
  containers:
    - name: sleeper
      image: busybox:1.37.0
      command: ["sh", "-c", "sleep 3600"]
kubectl apply -f pod-without-label.yaml
kubectl -n kyverno-demo get pods
kubectl -n kyverno-demo get policyreports
kubectl -n kyverno-demo get policyreports -o yaml

预期:Pod 创建成功,随后报告中出现该策略的 fail 结果。报告生成是异步的,刚创建时可能暂时没有结果。background: true 也会检查匹配的已有资源,但不会自动删除或修复它们。报告字段和存储方式以所选版本为准,详见Policy Reports。

3. 切换到拦截模式#

将 require-app-label.yaml 中的 failureAction: Audit 改为 failureAction: Enforce,然后重新应用。必须修改源文件,避免下次应用时意外恢复为审计模式。

kubectl apply -f require-app-label.yaml
kubectl wait --for=condition=Ready clusterpolicy/demo-require-app-label --timeout=60s

# 删除之前审计模式下创建的 Pod,再验证新建请求。
kubectl -n kyverno-demo delete pod missing-app
kubectl apply -f pod-without-label.yaml

预期:最后一个命令被 Webhook 拒绝,并返回必须设置 app 标签的信息。策略传播可能需要短暂时间;若仍能创建,检查策略状态和当前模式后重新验证。

4. 创建合规 Pod#

保存为 pod-with-label.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: with-app
  namespace: kyverno-demo
  labels:
    app: demo
spec:
  containers:
    - name: sleeper
      image: busybox:1.37.0
      command: ["sh", "-c", "sleep 3600"]
kubectl apply -f pod-with-label.yaml
kubectl -n kyverno-demo get pods --show-labels

预期:准入通过。Pod 能否最终运行还取决于镜像拉取、调度和集群中的其他策略。

日常使用与排错#

kubectl get clusterpolicies
kubectl describe clusterpolicy demo-require-app-label
kubectl -n kyverno get pods
kubectl -n kyverno logs deployment/kyverno-admission-controller --all-containers=true --tail=100
kubectl -n kyverno logs deployment/kyverno-reports-controller --all-containers=true --tail=100
kubectl -n kyverno get events --sort-by=.lastTimestamp
现象 检查方向
策略未拦截 是否仍为 Audit,资源种类和命名空间是否匹配,策略是否 Ready
修改 Deployment 未立即被拒绝 本文关闭了自动生成规则,仅验证 Pod;排查 ReplicaSet 事件中的 Pod 创建失败
Webhook 超时 admission controller 是否就绪,API Server 到 Service/Pod 的网络及证书是否正常
没有 PolicyReport reports controller 是否健康、是否匹配资源,并等待异步报告生成
failureAction 字段不被识别 检查 Kyverno 应用版本与 CRD 是否匹配,不要混用旧 CRD 和新文档

更多问题可参考官方排错指南。正式推广策略时,先在小范围运行 Audit 并修复违规,再切换到 Enforce;策略 YAML 与 Helm values 一起纳入版本控制。

企业 Hands-on:订单工作负载准入#

前面的标签示例用于理解规则。企业演练采用 Add-ons 基线 的真实 orders 工作负载;平台团队控制 Namespace 标签和策略,业务团队不能修改 ClusterPolicy/PolicyException。

先把以下保存为 orders-resource-policy.yaml,在审计模式验证存量业务与发布流水线:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: orders-resource-contract
spec:
  background: true
  rules:
    - name: require-container-resources
      match:
        any:
          - resources:
              kinds: [Pod]
              namespaces: [orders]
      validate:
        failureAction: Audit
        message: Every application container must declare CPU/memory requests and a memory limit.
        pattern:
          spec:
            containers:
              - name: "*"
                resources:
                  requests: {cpu: "?*", memory: "?*"}
                  limits: {memory: "?*"}
kubectl apply --dry-run=server -f orders-resource-policy.yaml
kubectl apply -f orders-resource-policy.yaml
kubectl -n orders get policyreports
kubectl get clusterpolicy orders-resource-contract -o yaml

本规则检查声明是否存在,不验证容量数值合理性;数值范围由 LimitRange/Quota 和压测预算共同约束。initContainer、注入 sidecar、Job/CronJob 也须纳入资源预算,并检查 Kyverno autogen 的控制器规则是否按预期生成。

在 staging 的真实业务 Git 分支删除一个容器的 memory limit,运行发布流水线:Audit 时必须产生违规报告;恢复字段,确认报告收敛。审核存量资源和例外后将 failureAction 改为 Enforce,重放同一错误发布,应被准入拒绝且旧副本继续接流;再发布合规版本并跑完整订单链路。

企业额外规则按独立策略交付:受信任镜像仓库/签名、禁用特权与危险挂载、必要标签、跨 namespace 身份限制。先校验签名源可用性和离线策略,不能一开全局 verifyImages 就阻塞所有系统组件。

故障演练 通过标准
重建一个 admission controller Pod 其余副本接管,发布延迟在预算内
业务用户修改策略或创建例外 RBAC 拒绝;例外仅平台授权,记录到期时间和补偿控制
策略误拦截 通过受控平台身份恢复该规则为 Audit;不全局关闭所有 webhook
审计控制器不可用 有监控告警,恢复后存量报告补齐;报告“无结果”不被当作合规

保留 policy/CRD/Chart 版本、正负用例和报告证据;监控准入延迟、拒绝率、webhook 可用性。生产推广从一个团队 namespace 开始,确认 fail-closed 的故障处理路径与应急身份后再扩大。

原实验的升级与清理#

升级前核对目标版本的兼容矩阵、升级说明和 CRD 迁移要求,更新 KYVERNO_CHART_VERSION,再执行前面的 helm upgrade --install。不要只替换控制器镜像。

删除本文创建的测试资源:

kubectl delete clusterpolicy demo-require-app-label
kubectl delete namespace kyverno-demo

仅当不再需要 Kyverno 时卸载:

helm uninstall kyverno --namespace kyverno

卸载前应确认其他策略的影响。CRD 和相关数据是否保留取决于 Chart 版本及配置,不要直接批量删除 CRD;删除 CRD 会同时删除对应的自定义资源。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭