自动为 Pod 控制器生成规则。
Pod 是 Kubernetes 中最常见的对象类型之一,因此也是大多数类型验证规则的重点。但 Kubernetes 并不推荐直接创建 Pod。相反,Kubernetes 有许多更高级别的控制器直接或间接管理 Pod,即 Deployment、DaemonSet、StatefulSet、Job 和 CronJob 等。编写针对 Pod 的策略时,必须为每个控制器编写策略将是乏味且低效的。Kyverno 通过支持从为 Pod 编写的规则自动生成更高级别控制器的策略规则来解决此问题。
例如,当创建如下所示的验证策略以检查所有镜像是否来自内部可信 registry 时,该策略适用于所有能够生成 Pod 的资源。
apiVersion : kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
spec:
validationFailureAction: enforce
rules:
- name: validate-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Images may only come from our internal enterprise registry."
pattern:
spec:
containers:
- image: "registry.domain.com/*"
一旦上述规则被创建,就可以在自动生成的规则中看到一下配置,这些都是 Kyverno 添加到规则中的。
spec:
background: true
failurePolicy: Fail
rules:
- match:
any:
- resources:
kinds:
- Pod
name: validate-registries
validate:
message: Images may only come from our internal enterprise registry.
pattern:
spec:
containers:
- image: registry.domain.com/*
- match:
any:
- resources:
kinds:
- DaemonSet
- Deployment
- Job
- StatefulSet
name: autogen-validate-registries
validate:
message: Images may only come from our internal enterprise registry.
pattern:
spec:
template:
spec:
containers:
- image: registry.domain.com/*
- match:
any:
- resources:
kinds:
- CronJob
name: autogen-cronjob-validate-registries
validate:
message: Images may only come from our internal enterprise registry.
pattern:
spec:
jobTemplate:
spec:
template:
spec:
containers:
- image: registry.domain.com/*
validationFailureAction: enforce
注意:Kyverno 1.7.0 中,新增了一个容器参数 --autogenInternals
(目前是 beta feature,默认不启用),用于防止回写这些自动生成的规则到 .spec 字段。设置为 true 可以启用该新特性。
自动生成行为是被 pod-policies.kyverno.io/autogen-controllers
注解控制的。
默认情况下,Kyverno 会加入一个注解 pod-policies.kyverno.io/autogen-controllers=DaemonSet,Deployment,Job,StatefulSet,CronJob
,以生成应用于这些控制器的附加规则。你可以通过修改 pod-policies.kyverno.io/autogen-controllers
注解,为自动生成的规则自定义目标 Pod 控制器。例如,如果 policy 的注解设置为 pod-policies.kyverno.io/autogen-controllers=Deployment,Kyverno 将会为 Deployment 自动生成规则。
如果在 match
或 exclude
块中指定以下资源字段/对象时,Kyverno 都会跳过生成 Pod 控制器规则,因为这些过滤器可能不适用于 Pod 控制器:
names
selector
annotations
如果想禁用自动为 Pod 控制器生成规则,将 pod-policies.kyverno.io/autogen-controllers
设置为 none
即可。
当为选定的 Pod 控制器禁用自动生成规则时,Kyverno 仍将 Pod 上的策略匹配应用于由这些控制器生成的 Pod。要免除这些 Pod,请使用带有类似于下面的表达式的前置条件,这可能允许 Job 控制器创建的 Pod 通过。
- key: Job
operator: AnyNotIn
value: "{{ request.object.metadata.ownerReferences[].kind }}"
通过 Metadata 排除
在某些情况下,可能需要中 exclude 块中使用标签或注解来排除 Pod。例如,如下的 match 和 exclude 看用于匹配所有(除了有 policy.test/require-requests-limits=skip 注解)的 Pod。
rules:
- name: validate-resources
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
annotations:
policy.test/require-requests-limits: skip
当 Kyverno 看到上面提到的这些类型的字段时,它会跳过规则的自动生成。另一个选择可能是通过编写一个查找 request.object.metadata.* 的表达式的前置条件来实现相同的效果。作为自动生成的一部分,Kyverno 会查找所有以 request.object 开头的、来自 AdmissionReview 的变量,并翻译后将其应用于每个合适的 Pod 控制器。以 Deployment 为例,在自动生成的规则中会被翻译为 request.object.spec.template.metadata.,这指向 Pod 模板中的 metadata,而不是 Deployment 自身的 metadata。要解决此问题,可以在前置条件的 object 上使用双引号,这样就不会将 request.object.metadata. 翻译成 request.object.spec.template.metadata.*,如下所示:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-requests-limits
spec:
validationFailureAction: enforce
background: true
rules:
- name: validate-resources
match:
any:
- resources:
kinds:
- Pod
preconditions:
all:
- key: "{{ request.\"object\".metadata.annotations.\"policy.test.io/require-requests-limits\" || '' }}"
operator: NotEquals
value: skip
validate:
message: "CPU and memory resource requests and limits are required."
pattern:
spec:
containers:
- resources:
requests:
memory: "?*"
cpu: "?*"
limits:
memory: "?*"
这种方式和上面使用 exclude 块的方式有相同的效果。