# **Kyverno Practical - Hands-on Tutorial**
This guide demonstrates the practical use of Kyverno in enforcing Kubernetes policies on a deployment. We will walk through a series of policy files and explain their purpose, patterns, and effects on Kubernetes resources.
### **1. Deployment YAML**
The deployment.yaml defines a standard Kubernetes deployment resource. This deployment represents an Nginx server with the following configuration:
```
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
team: backend
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: container1
image: nginx
```
*Play around this deployment !!!*
* **Replicas:** This deployment only has one replica of the Nginx server.
* **Labels:** The deployment includes labels such as app: nginx and team: backend, which are key for matching with the policies below.
### 2. **Enforcing Deployment Team Label (label-policy.yaml)**
This policy ensures that every deployment has a label defining which team is responsible for it.
```
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-deployment-team-label
spec:
validationFailureAction: Enforce
rules:
- name: require-deployment-team-label
match:
any:
- resources:
kinds:
- Deployment
validate:
message: "You must have a backend team for this deployment!!"
pattern:
metadata:
labels:
team: "backend"
```
**Purpose:**
* **Pattern Enforced:** All deployments must include a label team: backend.
* **Effect:** If a deployment is missing the team label or has an incorrect value, it will be blocked from being applied to the cluster.
**Why?**
* This enforces ownership and accountability of resources. By enforcing the team label, teams can better manage and identify their resources.
### **3. Prevent Using "latest" Image Tag (no-latest-tag-policy.yaml)**
This policy enforces two image-related rules: requiring a specific image tag and disallowing the use of the latest tag.
```
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: no-latest-tag-policy
spec:
validationFailureAction: Enforce
rules:
- name: Require Image Tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Must use an image tag in deployment!"
pattern:
spec:
containers:
- image: "*:*"
- name: Don't allow latest tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Can't use latest tag!"
pattern:
spec:
containers:
- image: "!*:latest"
```
**Purpose:**
* **Pattern Enforced:** Pods must have an explicit image tag (e.g., *nginx:1.21*) and cannot use *:latest*.
* **Effect:** Deployments using the latest tag, which is not a best practice, are blocked, enforcing image versioning for predictable deployments.
**Why?**
* **No** *:latest* **Tag:** Using *latest* can lead to unexpected behaviors when new versions are pushed. Explicit tags ensure stable deployments.
* **Image Tag Requirement:** Ensures every image in the deployment is versioned, improving traceability and rollback options.
### **4. Restrict Public Registries (private-registry.yaml)**
This policy restricts the use of public container registries, enforcing the use of images from a trusted registry.
```
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: deny-public-registries
spec:
validationFailureAction: Enforce
rules:
- name: deny-public-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Unknown image registry"
pattern:
spec:
containers:
- image: "kubernetes.io/*"
```
**Purpose:**
* **Pattern Enforced:** Pods are only allowed to pull images from specific, trusted registries (e.g., Kubernetes' own registry).
* **Effect:** This blocks pods from pulling images from public registries, which may be less secure or prone to malicious images.
**Why?**
* **Security:** Using a trusted private registry reduces the risk of using compromised or vulnerable images from public sources.
### **5. Minimum Replicas Requirement (replica-policy.yaml)**
This policy ensures that every deployment has at least three replicas, enhancing high availability and fault tolerance.
```
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: minimum-replicas
spec:
validationFailureAction: Enforce
rules:
- name: minimum-replicas
match:
any:
- resources:
kinds:
- Deployment
validate:
message: "Must have minimum of 3 replicas in deployment!"
pattern:
spec:
replicas: ">=3"
```
**Purpose:**
* **Pattern Enforced:** Every deployment must have at least 3 replicas.
* **Effect:** If a deployment tries to run with fewer than 3 replicas, it will be blocked.
**Why?**
* **High Availability:** Multiple replicas ensure that the application remains available even if some pods fail.
* **Load Balancing:** With multiple replicas, traffic can be evenly distributed, improving performance.
### **Summary**
Kyverno is a powerful tool for policy enforcement in Kubernetes. By applying these policies:
1. **Label Enforcement:** Ensures proper resource management and ownership.
1. **Image Tagging:** Prevents unpredictable behaviors by enforcing image versioning.
1. **Private Registries:** Enhances security by limiting where images can be pulled from.
1. **Replica Count:** Ensures high availability and resilience.
These policies will enforce best practices, ensuring that deployments in your cluster are secure, stable, and managed effectively.
# Usage Guide
This guide walks you through the practical steps to apply Kyverno policies to your Kubernetes cluster. Follow these instructions to enforce best practices in your deployments using Kyverno.
### **Prerequisites:**
1. **Kubernetes Cluster:** Ensure you have a running Kubernetes cluster (Minikube, K3s, or a cloud provider).
1. **Kyverno Installed:** You need to install Kyverno to enforce the policies. You can install Kyverno using the following command:
```
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno -n kyverno --create-namespace
```
for more info visit: https://kyverno.io/docs/installation/methods/
Verify that Kyverno is installed:
```
kubectl get pods -n kyverno
```
## **Step 1: Applying the deployment.yaml**
First, create a deployment for testing the policies:
```
kubectl apply -f deployment.yaml
```
This deployment describes an Nginx server, which we will validate against various policies. It has 1 replica and labels like `app: nginx` and `team: backend`.
## **Step 2: Applying the Policies**
**2.1 Label Enforcement Policy (label-policy.yaml)**
This policy ensures that all deployments must have a label indicating the responsible team. To apply it:
```
kubectl apply -f label-policy.yaml
```
If a deployment does not have the label `team: backend`, it will be blocked. Try creating a deployment without the team label and observe Kyverno enforcing the rule.
**2.2 No Latest Tag Policy (no-latest-tag-policy.yaml)**
This policy prevents the use of the `latest` image tag and requires all containers to specify a version tag.
```
kubectl apply -f no-latest-tag-policy.yaml
```
* If you try deploying a container image using `nginx:latest`, the deployment will be rejected.
* Only images that follow the `image:tag` format (e.g., nginx:1.19) will be allowed.
Test it by attempting to deploy a pod with the `latest `tag.
**2.3 Private Registry Enforcement (private-registry.yaml)**
This policy ensures that only images from trusted registries (e.g., kubernetes.io/*) are used, rejecting any other public registries.
```
kubectl apply -f private-registry.yaml
```
If a deployment tries to pull from an untrusted public registry, Kyverno will block it. This protects your cluster from untrusted sources.
**2.4 Minimum Replicas Policy (replica-policy.yaml)**
This policy enforces that every deployment must have at least 3 replicas. To apply the policy:
```
kubectl apply -f replica-policy.yaml
```
1. If a deployment tries to run with fewer than 3 replicas, it will be rejected.
1. You can test it by creating a deployment with only 1 or 2 replicas and observing how Kyverno denies the deployment.
## Step 3: Testing Policies
### Verifying Policy Enforcement
To test the policy effects, you can modify your deployment.yaml or create new deployments that violate the policies and check Kyverno's response.
1. **Label Check:** Modify the labels in deployment.yaml and remove or change the team label. Apply the modified deployment:
```
kubectl apply -f deployment.yam
```
Kyverno will block the deployment and output an error.
2. **Image Tag Check:** Change the container image to nginx:latest and try applying:
```
kubectl apply -f deployment.yaml
```
Kyverno will block the deployment and notify that the latest tag is not allowed.
3. **Private Registry Check:** Change the container image to one from a public registry (e.g., docker.io/nginx) and apply:
```
kubectl apply -f deployment.yaml
```
Kyverno will block the image pull if it's not from the trusted registry (e.g., kubernetes.io).
4. **Replica Check:** Modify the replicas field to less than 3 and try applying the deployment:
```
kubectl apply -f deployment.yaml
```
Kyverno will enforce the minimum replicas policy and block the deployment.
## Step 4: Policy Cleanup
Once you're done testing, you can remove the policies and deployments from the cluster using:
```
kubectl delete -f label-policy.yaml
kubectl delete -f no-latest-tag-policy.yaml
kubectl delete -f private-registry.yaml
kubectl delete -f replica-policy.yaml
kubectl delete -f deployment.yaml
```
# **Conclusion**
Kyverno helps enforce policies and maintain security, compliance, and best practices in Kubernetes clusters. By applying these policies, you ensure deployments have proper labeling, avoid insecure image tags, use trusted registries, and maintain adequate replicas for high availability.
If you're interested in practicing Kyverno policies in a live Kubernetes environment, check out this Kyverno Lab provided by KodeKloud:
[KodeKloud - Kubernetes Kyverno Lab](https://kodekloud.com/public-playgrounds/kubernetes-kyverno-lab)