Auto-Gen Rules
Pods are one of the most common object types in Kubernetes and as such are the focus of most types of validation rules. But creation of Pods directly is almost never done as it is considered an anti-pattern. Instead, Kubernetes has many higher-level controllers that directly or indirectly manage Pods, namely the Deployment, DaemonSet, StatefulSet, Job, and CronJob resources. Third-party custom resources may also “wrap” or leverage the Pod template as part of their resources as well. Writing policy that targets Pods but must be written for every one of these controllers would be tedious and inefficient. Kyverno solves this issue by supporting automatic generation of policy rules for higher-level controllers from a rule written exclusively for a Pod. For rules which match on Pods in addition to other kinds, auto-generation is not activated.
For example, when creating a validation policy like below which checks that all images come from an internal, trusted registry, the policy applies to all resources capable of generating Pods.
1apiVersion : kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: restrict-image-registries
5spec:
6 rules:
7 - name: validate-registries
8 match:
9 any:
10 - resources:
11 kinds:
12 - Pod
13 validate:
14 failureAction: Enforce
15 message: "Images may only come from our internal enterprise registry."
16 pattern:
17 spec:
18 containers:
19 - image: "registry.domain.com/*"
Once the policy is created, these other resources can be shown in auto-generated rules which Kyverno adds to the policy under the status
object.
1status:
2 autogen:
3 rules:
4 - exclude:
5 resources: {}
6 generate:
7 clone: {}
8 cloneList: {}
9 match:
10 any:
11 - resources:
12 kinds:
13 - DaemonSet
14 - Deployment
15 - Job
16 - StatefulSet
17 - ReplicaSet
18 - ReplicationController
19 resources: {}
20 mutate: {}
21 name: autogen-validate-registries
22 validate:
23 failureAction: Enforce
24 message: Images may only come from our internal enterprise registry.
25 pattern:
26 spec:
27 template:
28 spec:
29 containers:
30 - image: registry.domain.com/*
31 - exclude:
32 resources: {}
33 generate:
34 clone: {}
35 cloneList: {}
36 match:
37 any:
38 - resources:
39 kinds:
40 - CronJob
41 resources: {}
42 mutate: {}
43 name: autogen-cronjob-validate-registries
44 validate:
45 failureAction: Enforce
46 message: Images may only come from our internal enterprise registry.
47 pattern:
48 spec:
49 jobTemplate:
50 spec:
51 template:
52 spec:
53 containers:
54 - image: registry.domain.com/*
Note
Auto-gen rules also cover ReplicaSet and ReplicationControllers. These two intermediary controllers share the same Pod template schema as DaemonSets, Deployments, StatefulSets, and Jobs. Although these intermediary controllers have rules auto-generated, the Kyverno ConfigMap may need to be updated to remove default resource filters for them.Rule auto-generation behavior is controlled by the policy annotation pod-policies.kyverno.io/autogen-controllers
. You can change the value of the annotation to customize the target Pod controllers for the auto-generated rules. For example, Kyverno generates rules for a Deployment
and Job
if the annotation is defined as pod-policies.kyverno.io/autogen-controllers=Deployment,Job
. To disable auto-generating rules for Pod controllers entirely, set it to the value none
.
In addition to standard Kubernetes Pod controllers, auto-gen also supports custom resources where a Pod template has been embedded. For example, the OpenKruise custom resource CloneSet
embeds a Pod template and may produce auto-gen rules when CloneSet
is included in the value of the pod-policies.kyverno.io/autogen-controllers
annotation.
Kyverno skips generating Pod controller rules whenever the following resources
fields/objects are specified in a match
or exclude
block as these filters may not be applicable to Pod controllers:
names
selector
annotations
Additionally, Kyverno only auto-generates rules when the resource kind specified in a combination of match
and exclude
is no more than Pod
. Mutate rules which match on Pod
and use a JSON patch are also excluded from rule auto-generation as noted here.
When disabling auto-generation rules for select Pod controllers, or when auto-generation does not apply, Kyverno still applies policy matching on Pods to those spawned by those controllers. To exempt these Pods, use preconditions with an expression similar to the below which may allow Pods created by a Job controller to pass.
1- key: Job
2 operator: AnyNotIn
3 value: "{{ request.object.metadata.ownerReferences[].kind }}"
Exclusion by Metadata
In some cases, it may be desirable to use an exclude
block applied to Pods that uses either labels or annotations. For example, the following match
and exclude
statement may be written, the purpose of which would be to match any Pods except those that have the annotation policy.test/require-requests-limits=skip
.
1rules:
2 - name: validate-resources
3 match:
4 any:
5 - resources:
6 kinds:
7 - Pod
8 exclude:
9 any:
10 - resources:
11 annotations:
12 policy.test/require-requests-limits: skip
When Kyverno sees these types of fields as mentioned above it skips auto-generation for the rule. The next choice may be to use preconditions to achieve the same effect but by writing an expression that looks at request.object.metadata.*
. As part of auto-generation, Kyverno will see any variables from AdmissionReview such as that beginning with request.object
and translate it for each of the applicable Pod controllers. The result may be that the auto-generated rule for, as an example, Deployments will get translated to request.object.spec.template.metadata.*
which references the metadata
object inside the Pod template and not the metadata
object of the Deployment itself. To work around this and have preconditions which are not translated for these metadata use cases, double quote the object
portion of the variable as shown below.
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: require-requests-limits
5spec:
6 background: true
7 rules:
8 - name: validate-resources
9 match:
10 any:
11 - resources:
12 kinds:
13 - Pod
14 preconditions:
15 all:
16 - key: "{{ request.\"object\".metadata.annotations.\"policy.test.io/require-requests-limits\" || '' }}"
17 operator: NotEquals
18 value: skip
19 validate:
20 failureAction: Enforce
21 message: "CPU and memory resource requests and limits are required."
22 pattern:
23 spec:
24 containers:
25 - resources:
26 requests:
27 memory: "?*"
28 cpu: "?*"
29 limits:
30 memory: "?*"
The result will have the same effect as the first snippet which uses an exclude
block and have the benefit of auto-generation coverage.
Similar to the automatic translation of expressions beginning with request.object.metadata.*
, Kyverno also auto-generates rules for Pod controllers when a pattern specifies the same structure. For example, the disallow default namespace policy is a validate rule which uses an overlay pattern to ensure that neither a Pod nor any of its controllers can use the default
Namespace.
1pattern:
2 metadata:
3 namespace: "!default"
With auto-gen set to its default, this will get translated in the case of Deployments and others to the following below which is not the desire when expressing such a rule as the namespace
field is not defined under the Pod template when using a Pod controller. This auto-generated pattern will therefore cause all applicable Pod controllers to be in violation of the translated pattern.
1pattern:
2 spec:
3 template:
4 metadata:
5 namespace: "!default"
In such cases, auto-gen should be disabled as described above and one or more rules written to explicitly control the matching resources and the patterns/expressions used against them.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.