Kyverno — Kubernetes 策略即代码引擎
安装与配置
# === Helm 安装(推荐)===
helm repo add kyverno https://kyverno.github.io/kyverno/ # 添加 Kyverno Helm 仓库
helm repo update # 更新仓库索引
helm install kyverno kyverno/kyverno \
--namespace kyverno --create-namespace # 在 kyverno 命名空间安装(最新 v1.18)
# === 验证安装 ===
kubectl get pods -n kyverno # 查看 Kyverno Pod 是否运行
kubectl get crd | grep kyverno # 查看 Kyverno 注册的 CRD
# === 安装 Kyverno CLI(本地策略测试)===
brew install kyverno # macOS 用 Homebrew 安装 CLI
# 或下载二进制
curl -LO https://github.com/kyverno/kyverno/releases/latest/download/kyverno-cli_linux_amd64.tar.gz
tar -xzf kyverno-cli_linux_amd64.tar.gz # 解压 CLI 二进制
sudo mv kyverno /usr/local/bin/ # 移动到系统路径
kyverno version # 验证 CLI 版本
核心用法
# --- 示例1: 要求所有 Pod 必须有标签 ---
apiVersion: kyverno.io/v1 # Kyverno 策略 API 版本
kind: ClusterPolicy # 集群级策略(所有命名空间生效)
metadata:
name: require-labels # 策略名称
spec:
validationFailureAction: Enforce # Enforce=拒绝不合规资源, Audit=仅记录
rules:
- name: check-app-label # 规则名称
match:
any:
- resources:
kinds:
- Pod # 匹配 Pod 资源
validate:
message: "标签 'app' 是必需的" # 拒绝时的提示信息
pattern:
metadata:
labels:
app: "?*" # 要求 app 标签存在且非空
# --- 示例2: 自动注入默认标签(Mutate 变更)---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-labels
spec:
rules:
- name: add-team-label
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
labels:
team: "default" # 自动给所有 Pod 加上 team=default 标签
# --- 示例3: 禁止使用 latest 标签的镜像 ---
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
spec:
validationFailureAction: Enforce
rules:
- name: validate-image-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "禁止使用 :latest 标签的镜像"
pattern:
spec:
containers:
- image: "!*:latest" # 镜像标签不能是 latest
参数详解
| 参数/字段 | 说明 |
|---|
validationFailureAction | Enforce(拒绝不合规)或 Audit(仅记录) |
match.any[].resources.kinds | 匹配的资源类型(Pod、Deployment 等) |
match.any[].resources.namespaces | 限定生效的命名空间 |
exclude | 排除特定资源/命名空间不受策略约束 |
validate.pattern | 验证资源必须匹配的模式 |
mutate.patchStrategicMerge | 策略合并方式修改资源 |
generate | 自动生成资源(如 NetworkPolicy、ConfigMap) |
verifyImages | 验证容器镜像签名(配合 Cosign) |
实战案例
# === 完整流程:编写策略 → 测试 → 部署 ===
# 第1步:编写策略文件 require-requests.yaml
cat <<'EOF' > require-requests.yaml
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-requests-limits
spec:
validationFailureAction: Enforce
rules:
- name: validate-resources
match:
any:
- resources:
kinds:
- Pod
validate:
message: "容器必须设置 CPU 和内存的 requests"
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
EOF
# 第2步:用 CLI 本地测试(不需要集群)
kyverno apply require-requests.yaml \
--resource test-pod.yaml # 对测试资源运行策略检查
# 第3步:部署策略到集群
kubectl apply -f require-requests.yaml # 应用策略
# 第4步:测试效果——创建一个不合规的 Pod
kubectl run test --image=nginx # 会被拒绝,因为没有设置 requests
# 第5步:查看策略报告
kubectl get policyreport -A # 查看所有命名空间的策略报告
常见报错与解决
| 报错 | 原因 | 解决方案 |
|---|
admission webhook denied | 资源违反了 Enforce 模式的策略 | 修改资源使其合规,或将策略改为 Audit |
webhook timeout | Kyverno 处理超时 | 检查 Kyverno Pod 健康状态和资源限制 |
policy not found | 策略 CRD 未安装 | 确认 Kyverno 已正确安装 |
context deadline exceeded | 外部 API 调用超时 | 检查网络连通性和 API 服务状态 |
ClusterPolicy is deprecated | v1.17 废弃了旧策略类型 | 迁移到 CEL 策略类型(MutatingPolicy 等) |
速查表
| 操作 | 命令/文件 |
|---|
| 安装 Kyverno | helm install kyverno kyverno/kyverno -n kyverno |
| 查看策略列表 | kubectl get clusterpolicy |
| 查看策略报告 | kubectl get policyreport -A |
| 本地测试策略 | kyverno apply policy.yaml --resource resource.yaml |
| 运行策略测试套件 | kyverno test . |
| 删除策略 | kubectl delete clusterpolicy <name> |
| 查看 Kyverno 日志 | kubectl logs -n kyverno deploy/kyverno-admission-controller |
| 策略模式切换 | 修改 validationFailureAction: Audit/Enforce |