LabHub
学习 学习路径 课程

KCA — Kyverno 认证助理

立起注入、生成的规则与权限

在 LabHub 中继续学习

目标

用清单实现 mutate 的两种方式和 generate 的两种方式,并在集群中亲自建立 generate 实际运行所需的 RBAC,连同权限一起验证。

为什么重要

generate 规则是 Kyverno 中最容易静默失败的功能。由于 admission 会成功,kubectl 不会报告任何错误,只是目标资源没有生成。原因通常有两种:要么没有匹配 match,要么后台控制器没有权限。在本实验中亲自创建权限并用 auth can-i 检查后,将来遇到生成物不可见时,你会先检查 UpdateRequest 和权限,而不是立即翻查策略 YAML。注入 Sidecar 时同时设置资源限制的习惯,也是同类预防措施。

步骤

  1. 创建 /root/kca-mutate/ 目录,在 mutate-labels.yaml 中填写 kind ClusterPolicymetadata.name kca-add-team-label。创建规则 add-managed-by,在 match 的 kinds 中加入 Deployment,并通过 mutate.patchStrategicMergemetadata.labelskca.io/managed-by 设为 kyverno
  2. 在同一文件中添加规则 inject-sidecar。用 match.any[0].resources.selector.matchLabels 中的 kca.io/inject 选择目标;在 mutate.patchStrategicMerge.spec.template.spec.containers[0] 中加入 name log-collector、image,以及 resources.limits 中的 memorycpu
  3. /root/kca-mutate/mutate-json6902.yaml 中填写 kind ClusterPolicy,使用 spec.rules[0].mutate.patchesJson6902 编写 add 操作,添加注解 kca.io/owner。路径位于 /metadata/annotations/ 下,并且必须转义键名中的斜杠。
  4. /root/kca-mutate/generate-netpol.yaml 中填写 kind ClusterPolicymetadata.name kca-generate-default-deny。match 的 kinds 为 Namespacegenerate.apiVersionnetworking.k8s.io/v1kindNetworkPolicynamedefault-denynamespace 使用接收新命名空间名称的变量;synchronizetrue;在 generate.data.spec.policyTypes 中加入 IngressEgress
  5. /root/kca-mutate/generate-clone.yaml 中填写 kind ClusterPolicymetadata.name kca-clone-baselinegenerate.kindConfigMapnamekca-baselineclone.namespacekca-sharedclone.namekca-baseline-configsynchronizetrue,并且不要使用 data
  6. 在集群中创建命名空间 kca-shared,并在其中实际创建 Role kca-clone-reader。只允许对核心组的 configmaps 执行 getlistwatch,不要加入 delete
  7. 在集群中创建命名空间 kyverno 以及其中的 ServiceAccount kyverno-background-controller;再在 kca-shared 中实际创建 RoleBinding kca-clone-reader,将 Role kca-clone-reader 绑定到该服务账号。
  8. kca-shared 中实际创建 ConfigMap kca-baseline-config。数据包含 log-level=inforetention=7d 两项。然后使用 kubectl auth can-i 确认该服务账号能够读取此命名空间中的 configmaps,但不能读取 secrets。

参考

用 patchStrategicMerge 注入标签

创建 /root/kca-mutate/ 目录,在 mutate-labels.yaml 中填写 kind ClusterPolicymetadata.name kca-add-team-label。创建规则 add-managed-by,在 match 的 kinds 中加入 Deployment,并通过 mutate.patchStrategicMergemetadata.labelskca.io/managed-by 设为 kyverno

在 mutate 块中按对象原有形状写出内容,只会合并对应部分。标签键包含点和斜杠时,请在 YAML 中用引号括起来。

注入 Sidecar 并设置资源限制

在同一文件中添加规则 inject-sidecar。用 match.any[0].resources.selector.matchLabels 中的 kca.io/inject 选择目标;在 mutate.patchStrategicMerge.spec.template.spec.containers[0] 中加入 name log-collector、image,以及 resources.limits 中的 memorycpu

必须为注入的容器设置资源限制。请思考 mutate 先于 validate 执行这一事实为何在这里很重要。同时确保只为标签选中的工作负载注入,而不是所有工作负载。

使用 JSON Patch 添加注解

/root/kca-mutate/mutate-json6902.yaml 中填写 kind ClusterPolicy,使用 spec.rules[0].mutate.patchesJson6902 编写 add 操作,添加注解 kca.io/owner。路径位于 /metadata/annotations/ 下,并且必须转义键名中的斜杠。

JSON Pointer 使用斜杠分隔路径。键名本身包含斜杠时需要特殊转义;如果不知道该写法,路径会指向错误位置。

为每个命名空间生成 default-deny

/root/kca-mutate/generate-netpol.yaml 中填写 kind ClusterPolicymetadata.name kca-generate-default-deny。match 的 kinds 为 Namespacegenerate.apiVersionnetworking.k8s.io/v1kindNetworkPolicynamedefault-denynamespace 使用接收新命名空间名称的变量;synchronizetrue;在 generate.data.spec.policyTypes 中加入 IngressEgress

generate 必须完整指定生成什么(apiVersion/kind)、使用什么名称以及放在哪个命名空间。目标命名空间就是刚创建的命名空间,因此通过变量取得。

使用 clone 方式复制

/root/kca-mutate/generate-clone.yaml 中填写 kind ClusterPolicymetadata.name kca-clone-baselinegenerate.kindConfigMapnamekca-baselineclone.namespacekca-sharedclone.namekca-baseline-configsynchronizetrue,并且不要使用 data

clone 需要指定源资源的命名空间和名称。请确认它不能与 data 同时使用,并找出让副本跟随源资源变化所需的字段。

创建读取复制源的 Role

在集群中创建命名空间 kca-shared,并在其中实际创建 Role kca-clone-reader。只允许对核心组的 configmaps 执行 getlistwatch,不要加入 delete

从这里开始操作真实集群。只需要读取,因此三个动词就足够;核心组资源的 apiGroups 是空字符串。

绑定到后台控制器

在集群中创建命名空间 kyverno 以及其中的 ServiceAccount kyverno-background-controller;再在 kca-shared 中实际创建 RoleBinding kca-clone-reader,将 Role kca-clone-reader 绑定到该服务账号。

目标是 kyverno 命名空间中的服务账号。本实验环境中该命名空间和服务账号都不存在,因此也需要一并创建。

创建源 ConfigMap 并验证权限

kca-shared 中实际创建 ConfigMap kca-baseline-config。数据包含 log-level=inforetention=7d 两项。然后使用 kubectl auth can-i 确认该服务账号能够读取此命名空间中的 configmaps,但不能读取 secrets。

复制源必须真实存在,clone 才能成立。为 kubectl auth can-i 使用 --as 模拟服务账号,即可手动确认权限是否正确绑定。