Kyverno 组件与安装方式总览

官方安装方式

方式来源适用场景
Helmhelm测试
生产
HA
自定义
YAMLgithub.com/kyverno/kyverno/releases/download//install.yaml单文件快速安装
maingithub.com/kyverno/kyverno/raw/main/config/install-latest-testing.yaml官方不建议使用在测试以外的环境
DO NOT use this manifest for anything other than testing or experimental purposes! [1]

官方上的组件:

  • Admission controller(必需):处理 API server 的 webhook 回调,负责校验、变更、Policy Exceptions 与处理引擎。
  • Background controller(可选):处理 generate 与 mutate-existing 规则。
  • Reports controller(可选):处理 Policy Reports。
  • Cleanup controller(可选):处理清理策略。
  • 相关资源:
    • Services(webhook 与指标)
    • 每个 controller 一个 ServiceAccount
    • 两个 ConfigMap,主配置和指标配置
    • webhook 注册与认证用 Secrets
    • Roles 和 Bindings
    • Validating/MutatingWebhookConfigurations
    • CRDs

K8S 版本兼容

Kyverno 版本K8S 版本
v1.19v1.33 - v1.35
v1.18v1.32 - v1.35
v1.17v1.32 - v1.35
v1.161.31 - 1.34
v1.151.30 - 1.33
v1.141.29 - 1.32
v1.131.28 - 1.31
v1.121.26 - 1.29

版本号遵循 “MAJOR-MINOR-PATCH”

  • MAJOR: 对于API版本变更等才会更改;例如每年一次

  • MINOR: 向後相容方式引入的功能;增強和修复;例如每三月一次

  • PATCH: 关键的问题修复,例如每月1次

更多关于 Kyverno 版本兼容问题参考 release-{MAJOR-MINOR-PATCH}.kyverno.io/docs/installation

使用 Helm 进行 生产 与 HA 安装

非生产用默认值即可 [2]

text
1
2
3
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno -n kyverno --create-namespace

高可用命令

text
1
2
3
4
5
helm install kyverno kyverno/kyverno -n kyverno --create-namespace \
  --set admissionController.replicas=3 \
  --set backgroundController.replicas=2 \
  --set cleanupController.replicas=2 \
  --set reportsController.replicas=2

注意事项:

  • kyverno 自身的名称空间默认会被排除,所以kyverno 的 NS 必须是一个独立的,
  • 从 v1.12 起 kube-system 也默认被排除
  • 从 v1.19 起 CRD 由 kyverno-api 子 chart 管理

独立的 Reports Server

Reports Server(可选组件) 是把 policy reports 和 cluster policy reports 从 etcd 挪到 PostgreSQL 中存储

随 kyverno helm chart 安装 Reports server

text
1
2
helm install kyverno kyverno/kyverno -n kyverno --create-namespace \
	--set reportsServer.enabled=true

独立安装 reports-server

text
1
2
helm repo add reports-server https://kyverno.github.io/reports-server
helm install reports-server -n reports-server reports-server/reports-server --create-namespace

Reports Server 自带一个 PostgreSQL,但官方推荐自带数据库以便精细控制,配置主要就是 “主机名/用户/密码/库”

预发布版安装

使用 helm 指定参数 --devel,即可安装 alpha、beta、rc 预发布版,可以指定 version 版本来约束

text
1
2
3
4
5
6
# 查看全部预发布版本
helm search repo kyverno/kyverno --versions --devel
helm install kyverno kyverno/kyverno -n kyverno \
  --create-namespace \
  --version 3.9.0-rc.4 
  --devel

Pod Security Policies

这部分是在安装完 kyverno 可以选择安装的 Pod Security Standard policies (预先编写好的安全策略集,用于检查Kubernetes 官方定义的 Pod 安全标准)[3]

text
1
helm install kyverno-policies kyverno/kyverno-policies -n kyverno

平台差异

使用 helm 安装,针对 ArgoCD / OpenShift / EKS / AKS 不同平台有不同差异

平台问题做法
ArgoCD本地清单与 Kyverno写入字段不一致,出现 OutOfSync;app.kubernetes.io/instance 标签与 Kyverno chart 冲突开启 ServerSideDiff(v2.10 起):Application 加注解 argocd.argoproj.io/compare-options: ServerSideDiff=true,IncludeMutationWebhook=true,或在 argocd-cmd-params-cm 全局配置;syncOptions 用 ServerSideApply=true,避免 Replace=true;设 config.preserve=false;改用其他资源追踪方式;可用 webhookLabels 给 webhook 加标签
OpenShiftchart 自带的 Pod securityContext 符合 PSS restricted,但可能与 SCC 不兼容,报 “unable to validate against any security context constraint”把需要的 securityContext 字段设为 null,让 OpenShift 套用 SCC;OpenShift 4.11+ 的 restricted-v2 可不改 chart 直接部署
EKS(VPC CNI)选 “Operability” 方案时,不排除 kube-system 且有 Fail 模式策略匹配 Pod,节点全部删除后 VPC CNI DaemonSet Pod 可能起不来安装时从 webhook 排除 kube-system;自 Kyverno 1.12 起默认已排除,可以忽略
AKSAdmission Enforcer 会移除可能影响系统 Namespace 的 webhook,与 Kyverno 反复争抢设 Helm 选项 config.webhookAnnotations,加注解 "admissions.enforcer/disabled": true;自 1.12 起已默认设置

ConfigMap

Kyverno 主配置为 “Kyverno Namespace” 的 ConfigMap 里(默认名 kyverno);默认配置可用 Deployment 环境变量 INIT_CONFIG 改名),运行时动态读取变更。

ConfigMap内容

key默认值含义
defaultRegistrydocker.io镜像未写 registry 时使用的默认 registry;可带路径后缀,如 registry.example.com/myorg
enableDefaultRegistryMutation"true"满足条件时用 defaultRegistry 更新内部上下文
excludeGroupssystem:serviceaccounts:kube-system,system:nodes排除的用户组,逗号分隔
excludeUsernames'!system:kube-scheduler'排除的用户名,! 表示取消排除
excludeRoles未定义排除的 Role
excludeClusterRoles未定义排除的 ClusterRole
generateSuccessEvents"false"是否生成成功事件
matchConditions无webhook 层用 CEL 缩小转发给 Kyverno 的请求;需 Kubernetes 1.27+ 且启用 AdmissionWebhookMatchConditions
resourceFilters内置列表(Node、Event 等)[kind,namespace,name] 条目,webhook 不评估;对后台扫描默认不生效(见 skipResourceFilters)
updateRequestThreshold1000mutateExisting 与 generate 策略产生的 UpdateRequest 总数阈值
webhooks排除 kube-system 与 kyverno NamespaceJSON 格式的 namespaceSelector 对象,决定哪些 Namespace 不发 AdmissionReview
webhookAnnotations未定义给 webhook 加注解(AKS 用)
webhookLabels未定义给 webhook 加标签

默认的 configmap

yaml
1
2
3
4
5
6
7
apiVersion: v1
kind: ConfigMap
metadata:
  name: kyverno
  namespace: kyverno
data:
  webhooks: '[{"namespaceSelector":{"matchExpressions":[{"key":"kubernetes.io/metadata.name","operator":"NotIn","values":["kube-system"]},{"key":"kubernetes.io/metadata.name","operator":"NotIn","values":["kyverno"]}]}}]'

证书管理

证书主要负责 Kubernetes kube-apiserver 与 Kyverno admission-webhook 之间的 HTTPS/TLS 通信。默认由 Kyverno 自动生成、管理和轮换证书,正常情况下不需要额外部署 cert-manager

默认的证书管理机制

配置项默认值说明
CA1 年签署并验证 Webhook 服务证书
子证书150 天Webhook 服务实际使用的证书
密钥算法RSA 2048默认公钥算法及密钥长度
证书检查频率每 12 小时检查托管证书有效期
Secret 事件触发检查Secret 发生相关事件时进行检查
续期15 天提前 N 天完成新证书替换

安装时设置密钥算法

text
1
2
3
4
5
helm install kyverno kyverno/kyverno \
  --namespace kyverno \
  --create-namespace \
  --set admissionController.tlsKeyAlgorithm=ECDSA \
  --set cleanupController.tlsKeyAlgorithm=ECDSA

Kyverno 支持的证书管理模式

模式自动续期是否需要额外组件
自主管理支持不需要
Helm 部署时生成自签证书不支持自动续期不需要
cert-manager支持需要 cert-manager
自带 CA/TLS SecretKyverno 不负责续期取决外部管理方式

自定义证书 [4]

1. 生成自签名 Root CA

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 生成 RSA 2048 私钥
openssl genpkey -algorithm RSA \
  -pkeyopt rsa_keygen_bits:2048 \
  -out rootCA.key

# 生成自签名 CA 证书,有效期 5 年
openssl req -x509 -new -sha256 \
  -key rootCA.key \
  -out rootCA.crt \
  -days 1825 \
  -subj "/CN=kyverno-ca" \
  -addext "basicConstraints=critical,CA:TRUE" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"

2. 生成 Admission Controller TLS 证书

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 生成私钥
openssl genpkey -algorithm RSA \
  -pkeyopt rsa_keygen_bits:2048 \
  -out tls.key

# 生成 CSR
openssl req -new -sha256 \
  -key tls.key \
  -out tls.csr \
  -subj "/CN=kyverno-svc"

# 创建 X.509 扩展文件
cat > tls.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:kyverno-svc,DNS:kyverno-svc.kyverno,DNS:kyverno-svc.kyverno.svc
EOF

# 使用 Root CA 签发证书
openssl x509 -req \
  -in tls.csr \
  -CA rootCA.crt \
  -CAkey rootCA.key \
  -CAcreateserial \
  -out tls.crt \
  -days 1800 \
  -sha256 \
  -extfile tls.ext

3. 生成 Cleanup Controller TLS 证书

两个 Controller 使用各自独立的 TLS 私钥和证书,但由同一 Root CA 签发。Admission Controller (kyverno-svc),Cleanup Controller (kyverno-cleanup-controller) [5]

tip

admonition controller 证书必须包含 SAN:

  • kyverno-svc
  • kyverno-svc.kyverno
  • kyverno-svc.kyverno.svc

cleanup controller :

  • kyverno-cleanup-controller
  • kyverno-cleanup-controller.kyverno
  • kyverno-cleanup-controller.kyverno.svc
text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 生成私钥
openssl genpkey -algorithm RSA \
  -pkeyopt rsa_keygen_bits:2048 \
  -out cleanup-tls.key

# 生成 CSR
openssl req -new -sha256 \
  -key cleanup-tls.key \
  -out cleanup-tls.csr \
  -subj "/CN=kyverno-cleanup-controller"

# 创建 X.509 扩展文件
cat > cleanup-tls.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:kyverno-cleanup-controller,DNS:kyverno-cleanup-controller.kyverno,DNS:kyverno-cleanup-controller.kyverno.svc
EOF

# 使用相同 Root CA 签发证书
openssl x509 -req \
  -in cleanup-tls.csr \
  -CA rootCA.crt \
  -CAkey rootCA.key \
  -CAcreateserial \
  -out cleanup-tls.crt \
  -days 1800 \
  -sha256 \
  -extfile cleanup-tls.ext

4. 证书验证

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 查看 CA
openssl x509 -in rootCA.crt \
  -noout -subject -issuer -dates

# 查看 Admission 证书及 SAN
openssl x509 -in tls.crt \
  -noout -subject -issuer -dates -ext subjectAltName

# 查看 Cleanup 证书及 SAN
openssl x509 -in cleanup-tls.crt \
  -noout -subject -issuer -dates -ext subjectAltName

# 验证两个证书的 CA 签名及服务端用途
openssl verify -CAfile rootCA.crt \
  -purpose sslserver \
  tls.crt cleanup-tls.crt

5. 创建相关 Kubernetes Secret

text
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 创建命名空间
kubectl create namespace kyverno \
  --dry-run=client -o yaml | kubectl apply -f -

# Admission Controller TLS
kubectl -n kyverno create secret tls \
  kyverno-svc.kyverno.svc.kyverno-tls-pair \
  --cert=tls.crt \
  --key=tls.key

# Admission Controller CA
kubectl -n kyverno create secret generic \
  kyverno-svc.kyverno.svc.kyverno-tls-ca \
  --from-file=rootCA.crt

# Cleanup Controller TLS
kubectl -n kyverno create secret tls \
  kyverno-cleanup-controller.kyverno.svc.kyverno-tls-pair \
  --cert=cleanup-tls.crt \
  --key=cleanup-tls.key

# Cleanup Controller CA
kubectl -n kyverno create secret generic \
  kyverno-cleanup-controller.kyverno.svc.kyverno-tls-ca \
  --from-file=rootCA.crt
tip
rootCA.key 不需要上传到 Kubernetes Secret。

6. 完成证书创建后,安装kyverno

tip
Kyverno 检测到自定义证书 Secret 后使用现有证书,否则回退到默认的自动管理方式。自定义证书模式下,Kyverno 不会自动轮换这批外部证书。
text
1
2
3
helm upgrade --install kyverno kyverno/kyverno \
  --namespace kyverno \
  --create-namespace

Reference

[1] Install main (latest)

[2] Non-Production Installation

[3] Pod Security Standards

[4] Custom certificates

[5] generate-a-self-signed-ca-and-signed-certificate-key-pairs