Kyverno CLI
The Kyverno Command Line Interface (CLI) is designed to validate policies and test the behavior of applying policies to resources before adding the policy to a cluster. It can be used as a kubectl
plugin or as a standalone CLI.
Installing the CLI
You can use Krew to install the Kyverno CLI:
1# Install Kyverno CLI using kubectl krew plugin manager
2kubectl krew install kyverno
3
4# test the Kyverno CLI
5kubectl kyverno version
6
Install via AUR (archlinux)
You can install the Kyverno CLI via your favorite AUR helper (e.g. yay)
yay -S kyverno-git
Building the CLI
You can also build the CLI binary from the Git repository, and then move the binary into a directory in your PATH.
1git clone https://github.com/kyverno/kyverno.git
2cd github.com/kyverno/kyverno
3make cli
4mv ./cmd/cli/kubectl-kyverno/kyverno /usr/local/bin/kyverno
CLI Commands
When using the Kyverno CLI with kustomize, it is recommended to use the “standalone” version (binaries here) as opposed to the version embedded inside kubectl
.
Apply
Applies policies on resources, and supports applying multiple policies on multiple resources in a single command. The command also supports applying the given policies to an entire cluster. The current kubectl
context will be used to access the cluster.
Note
Kyverno CLI in bothapply
and validate
commands supports files from URLs both as policies and resources.
Displays mutate results to stdout, by default. Use the -o <path>
flag to save mutated resources to a file or directory.
Apply to a resource:
kyverno apply /path/to/policy.yaml --resource /path/to/resource.yaml
Apply to all matching resources in a cluster:
kyverno apply /path/to/policy.yaml --cluster > policy-results.txt
The resources can also be passed from stdin:
kustomize build nginx/overlays/envs/prod/ | kyverno apply /path/to/policy.yaml --resource -
Apply multiple policies to multiple resources:
kyverno apply /path/to/policy1.yaml /path/to/folderFullOfPolicies --resource /path/to/resource1.yaml --resource /path/to/resource2.yaml --cluster
Saving the mutated resource in a file/directory:
kyverno apply /path/to/policy.yaml --resource /path/to/resource.yaml -o <file path/directory path>
Apply policy with variables:
Use the --set
flag to pass the values for variables in a policy while applying on a resource.
kyverno apply /path/to/policy.yaml --resource /path/to/resource.yaml --set <variable1>=<value1>,<variable2>=<value2>
Use --values_file
for applying multiple policies on multiple resources and pass a file containing variables and its values. Variables specified can be of various types include AdmissionReview fields, ConfigMap context data (Kyverno 1.3.6), and API call context data (Kyverno 1.3.6).
Note
When passing ConfigMap array data into the values file, the data must be formatted as JSON outlined here.kyverno apply /path/to/policy1.yaml /path/to/policy2.yaml --resource /path/to/resource1.yaml --resource /path/to/resource2.yaml -f /path/to/value.yaml
Format of value.yaml
:
1policies:
2 - name: <policy1 name>
3 resources:
4 - name: <resource1 name>
5 values:
6 <variable1 in policy1>: <value>
7 <variable2 in policy1>: <value>
8 - name: <resource2 name>
9 values:
10 <variable1 in policy1>: <value>
11 <variable2 in policy1>: <value>
12 - name: <policy2 name>
13 resources:
14 - name: <resource1 name>
15 values:
16 <variable1 in policy2>: <value>
17 <variable2 in policy2>: <value>
18 - name: <resource2 name>
19 values:
20 <variable1 in policy2>: <value>
21 <variable2 in policy2>: <value>
Example:
Policy manifest (add_network_policy.yaml
):
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: add-networkpolicy
5 annotations:
6 policies.kyverno.io/category: Workload Management
7 policies.kyverno.io/description: By default, Kubernetes allows communications across
8 all pods within a cluster. Network policies and, a CNI that supports network policies,
9 must be used to restrict communications. A default NetworkPolicy should be configured
10 for each namespace to default deny all ingress traffic to the pods in the namespace.
11 Application teams can then configure additional NetworkPolicy resources to allow
12 desired traffic to application pods from select sources.
13spec:
14 rules:
15 - name: default-deny-ingress
16 match:
17 resources:
18 kinds:
19 - Namespace
20 generate:
21 kind: NetworkPolicy
22 name: default-deny-ingress
23 namespace: "{{request.object.metadata.name}}"
24 synchronize: true
25 data:
26 spec:
27 # select all pods in the namespace
28 podSelector: {}
29 policyTypes:
30 - Ingress
Resource manifest (required_default_network_policy.yaml
):
1kind: Namespace
2apiVersion: v1
3metadata:
4 name: "devtest"
Applying policy on resource using --set
or -s
flag:
kyverno apply /path/to/add_network_policy.yaml --resource /path/to/required_default_network_policy.yaml -s request.object.metadata.name=devtest
Applying policy on resource using --values_file
or -f
flag:
YAML file containing variables (value.yaml
):
1policies:
2 - name: default-deny-ingress
3 resources:
4 - name: devtest
5 values:
6 request.namespace: devtest
kyverno apply /path/to/add_network_policy.yaml --resource /path/to/required_default_network_policy.yaml -f /path/to/value.yaml
Apply policy with namespace selector:
Use --values_file
for passing a file containing namespace details.
Check here to know more about namespace selector.
kyverno apply /path/to/policy1.yaml /path/to/policy2.yaml --resource /path/to/resource1.yaml --resource /path/to/resource2.yaml -f /path/to/value.yaml
Format of value.yaml
:
1namespaceSelector:
2 - name: <namespace1 name>
3 labels:
4 <namespace label key>: <namespace label value>
5 - name: <namespace2 name>
6 labels:
7 <namespace label key>: <namespace label value>
Example:
Policy manifest (enforce-pod-name.yaml
):
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: enforce-pod-name
5spec:
6 validationFailureAction: audit
7 background: true
8 rules:
9 - name: validate-name
10 match:
11 resources:
12 kinds:
13 - Pod
14 namespaceSelector:
15 matchExpressions:
16 - key: foo.com/managed-state
17 operator: In
18 values:
19 - managed
20 validate:
21 message: "The Pod must end with -nginx"
22 pattern:
23 metadata:
24 name: "*-nginx"
Resource manifest (nginx.yaml
):
1kind: "Pod"
2apiVersion: "v1"
3metadata:
4 name: test-nginx
5 namespace: test1
6spec:
7 containers:
8 - name: "nginx"
9 image: "nginx:latest"
Namespace manifest (namespace.yaml
):
1apiVersion: v1
2kind: Namespace
3metadata:
4 name: test1
5 labels:
6 foo.com/managed-state: managed
YAML file containing variables (value.yaml
):
1namespaceSelector:
2 - name: test1
3 labels:
4 foo.com/managed-state: managed
To test the above policy use the following command:
kyverno apply /path/to/enforce-pod-name.yaml --resource /path/to/nginx.yaml -f /path/to/value.yaml
Policy Report
Policy report provide information about policy execution and violation. Use --policy_report
with the apply
command to generate policy report.
Policy report can also be generated for a live cluster. While generating a policy report for a live cluster the -r
flag is assuming a resource by specific name which is assumed to be globally unique. And it doesn’t support naming the resource type (ex., Pod/foo when the cluster contains resources of different types with the same name). To generate a policy report for a live cluster use --cluster
with --policy_report
.
1kyverno apply policy.yaml --cluster --policy_report
Above example applies a policy.yaml
to all resources in the cluster.
Below are the combination of inputs that can be used for generating the policy report from Kyverno CLI.
Policy | Resource | Cluster | Namespace | Interpretation | |
---|---|---|---|---|---|
policy.yaml | -r resource.yaml | false | Apply policy from policy.yaml to the resources specified in resource.yaml |
||
policy.yaml | -r resourceName | true | Apply policy from policy.yaml to the resource with a given name in the cluster |
||
policy.yaml | true | Apply policy from policy.yaml to all the resources in the cluster | |||
policy.yaml | -r resourceName | true | -n=namespaceName | Apply policy from policy.yaml to the resource with a given name in a specific Namespace |
|
policy.yaml | true | -n=namespaceName | Apply policy from policy.yaml to all the resources in a specific Namespace |
Example:
Consider the following policy and resources:
policy.yaml
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: require-pod-requests-limits
5 annotations:
6 policies.kyverno.io/category: Workload Management
7 policies.kyverno.io/description: >-
8 As application workloads share cluster resources, it is important to limit resources
9 requested and consumed by each pod. It is recommended to require 'resources.requests'
10 and 'resources.limits' per pod. If a namespace level request or limit is specified,
11 defaults are automatically applied to each pod based on the 'LimitRange' configuration.
12spec:
13 validationFailureAction: audit
14 rules:
15 - name: validate-resources
16 match:
17 resources:
18 kinds:
19 - Pod
20 validate:
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: "?*"
resource1.yaml
1apiVersion: v1
2kind: Pod
3metadata:
4 name: nginx1
5 labels:
6 env: test
7spec:
8 containers:
9 - name: nginx
10 image: nginx
11 imagePullPolicy: IfNotPresent
12 resources:
13 requests:
14 memory: "64Mi"
15 cpu: "250m"
16 limits:
17 memory: "128Mi"
18 cpu: "500m"
resource2.yaml
1apiVersion: v1
2kind: Pod
3metadata:
4 name: nginx2
5 labels:
6 env: test
7spec:
8 containers:
9 - name: nginx
10 image: nginx
11 imagePullPolicy: IfNotPresent
Case 1: Apply a policy manifest to multiple resource manifests
1kyverno apply policy.yaml -r resource1.yaml -r resource2.yaml --policy_report
Case 2: Apply a policy manifest to multiple resources in the cluster
Create the resources by first applying manifests resource1.yaml
and resource2.yaml
.
1kyverno apply policy.yaml -r nginx1 -r nginx2 --cluster --policy_report
Case 3: Apply a policy manifest to all resources in the cluster
1kyverno apply policy.yaml --cluster --policy_report
Given the contents of policy.yaml shown earlier, this will produce a report validating against all Pods in the cluster.
Case 4: Apply a policy manifest to multiple resources by name within a specific Namespace
1kyverno apply policy.yaml -r nginx1 -r nginx2 --cluster --policy_report -n default
Case 5: Apply a policy manifest to all resources within the default Namespace
1kyverno apply policy.yaml --cluster --policy_report -n default
Given the contents of policy.yaml
shown earlier, this will produce a report validating all Pods within the default Namespace.
On applying policy.yaml
to the mentioned resources, the following report will be generated:
1apiVersion: wgpolicyk8s.io/v1alpha1
2kind: ClusterPolicyReport
3metadata:
4 name: clusterpolicyreport
5results:
6- message: Validation rule 'validate-resources' succeeded.
7 policy: require-pod-requests-limits
8 resources:
9 - apiVersion: v1
10 kind: Pod
11 name: nginx1
12 namespace: default
13 rule: validate-resources
14 scored: true
15 status: pass
16- message: 'Validation error: CPU and memory resource requests and limits are required; Validation rule validate-resources failed at path /spec/containers/0/resources/limits/'
17 policy: require-pod-requests-limits
18 resources:
19 - apiVersion: v1
20 kind: Pod
21 name: nginx2
22 namespace: default
23 rule: validate-resources
24 scored: true
25 status: fail
26summary:
27 error: 0
28 fail: 1
29 pass: 1
30 skip: 0
31 warn: 0
Test
The test
command can test multiple policy resources from a Git repository or local folders. The command recursively looks for YAML files with policy test declarations (described below) and then executes those tests.
Example:
1kyverno test /path/to/folderContaningTestYamls
or
1kyverno test /path/to/githubRepository
Use the --f <fileName.yaml>
flag to set a file name which includes test cases.
Test declaration file format (test.yaml
)
1- name: test-1
2 policies:
3 - <path>
4 - <path>
5 resources:
6 - <path>
7 - <path>
8 results:
9 - policy: <name>
10 rule: <name>
11 resource: <name>
12 status: pass
13 - policy: <name>
14 rule: <name>
15 resource: <name>
16 status: fail
17
The test declaration consists of three parts:
- The
policies
element which lists one or more policies to be applied. - The
resources
element which lists one or more resources to which the policies are applied. - The
results
element which declares the expected results.
The test command executes a test declaration by applying the policies to the resources and comparing the results with the expected results. The test passes if the actual results match the expected results.
Multiple tests can be defined in the same file using the YAML delimiter ---
.
Example:
Policy manifest (disallow_latest_tag.yaml
):
1apiVersion: kyverno.io/v1
2kind: ClusterPolicy
3metadata:
4 name: disallow-latest-tag
5 annotations:
6 policies.kyverno.io/category: Best Practices
7 policies.kyverno.io/description: >-
8 The ':latest' tag is mutable and can lead to unexpected errors if the
9 image changes. A best practice is to use an immutable tag that maps to
10 a specific version of an application pod.
11spec:
12 validationFailureAction: audit
13 rules:
14 - name: require-image-tag
15 match:
16 resources:
17 kinds:
18 - Pod
19 validate:
20 message: "An image tag is required."
21 pattern:
22 spec:
23 containers:
24 - image: "*:*"
25 - name: validate-image-tag
26 match:
27 resources:
28 kinds:
29 - Pod
30 validate:
31 message: "Using a mutable image tag e.g. 'latest' is not allowed."
32 pattern:
33 spec:
34 containers:
35 - image: "!*:latest"
Resource manifest (resource.yaml
):
1apiVersion: v1
2kind: Pod
3metadata:
4 name: myapp-pod
5 labels:
6 app: myapp
7spec:
8 containers:
9 - name: nginx
10 image: nginx:1.12
Test manifest (test.yaml
):
1name: disallow_latest_tag
2policies:
3 - disallow_latest_tag.yaml
4resources:
5 - resource.yaml
6results:
7 - policy: disallow-latest-tag
8 rule: require-image-tag
9 resource: myapp-pod
10 status: pass
11 - policy: disallow-latest-tag
12 rule: validate-image-tag
13 resource: myapp-pod
14 status: pass
1kyverno test <PathToDirs>
The example above applies a test on the policy and the resource defined in the test YAML.
# | TEST | RESULT |
---|---|---|
1 | myapp-pod with disallow-latest-tag/require-image-tag | pass |
2 | myapp-pod with disallow-latest-tag/validate-image-tag | pass |
Validate
Validates a policy, can validate multiple policy resource description files or even an entire folder containing policy resource description files. Currently supports files with resource description in YAML. The policies can also be passed from stdin.
Example:
kyverno validate /path/to/policy1.yaml /path/to/policy2.yaml /path/to/folderFullOfPolicies
Passing policy from stdin:
kustomize build nginx/overlays/envs/prod/ | kyverno validate -
Use the -o <yaml/json>
flag to display the mutated policy.
Example:
kyverno validate /path/to/policy1.yaml /path/to/policy2.yaml /path/to/folderFullOfPolicies -o yaml
Policy can also be validated with CRDs. Use -c
flag to pass the CRD, can pass multiple CRD files or even an entire folder containing CRDs.
Example:
kyverno validate /path/to/policy1.yaml -c /path/to/crd.yaml -c /path/to/folderFullOfCRDs
Version
Prints the version of Kyverno used by the CLI.
Example:
kyverno version