In this article , we would explain how to secure your kubernetes cluster in your organization using Kyverno , ArgoCD to set up more security during your application deployment.
What is Kyverno ?
Kyverno is an open-source policy management tool for Kubernetes clusters. It allows users to declaratively define policies that can be enforced on their clusters, ensuring that resources are deployed in compliance with organizational standards.
Prerequisites.
- ArgoCD
- Kubernetes cluster
- Working app ( Hello World application ).
- Helm repository of Kyverno
Why do we need policies ?
- Compliance: Policies can be used to ensure that resources are deployed in compliance with organizational standards and best practices. For example, policies can be used to enforce security standards, such as ensuring that resources are configured with the correct level of access controls.
- Governance: Policies can be used to ensure that resources are deployed in a consistent manner across different teams and projects within an organization. This can help to promote collaboration and reduce the risk of resource conflicts.
- Automation: Kyverno’s “Generators” feature can be used to automatically create resources based on certain conditions. This can help to improve efficiency and reduce the risk of human error.
- Customization: Kyverno is highly customizable, and can be used to implement a wide range of policy enforcement use cases. Organizations can tailor policies to meet their specific needs and requirements.
- Scalability: In large and complex Kubernetes cluster, it can be hard to keep track of all the resources and configurations, policies can be used to automate and scale the enforcement of best practices across the entire cluster.
Overall, policies with Kyverno can help organizations to ensure that their resources are deployed in a compliant, consistent, and efficient manner, while also promoting collaboration and reducing the risk of resource conflicts.
Set up Kyverno using ArgoCD.
We will keep using the GitOps approach as usual and make ArgoCD the key tool to manage all helm chart installation.
Below are the steps of installing Kyverno with ArgoCD using helm chart.
First , we connected to the repository where we have the official kyverno helm chart.I added the official helm chart to my personal GitHub repository because I had to make some changes ( Version , namespace name ..etc ) but you can skip that and add the url of the official helm chart.
Here is my GitHub account
Add the repository to ArgoCD
Once added , now we can start creating the application in ArgoCD.
Kyverno application creation steps
Once you follow these steps , you will need to apply the changes and save it and then we will have Kyverno installed in our Cluster and hence , you are ready to operate and create your policies
Kyverno installed with ArgoCD.
What are Kyverno Policy types ?
- Validation policies: These policies are used to check that resources meet certain conditions before they are created or updated. If a resource does not meet the conditions specified in the policy, Kyverno will reject the resource and prevent it from being created or updated.
- Mutation policies: These policies are used to automatically modify resources that do not meet certain conditions. When a resource is created or updated, Kyverno will check the resource against the conditions specified in the policy. If the resource does not meet the conditions, Kyverno will automatically modify the resource to bring it into compliance.
- Generation policies: A generate rule can be used to create additional resources when a new resource is created or when the source is updated. This is useful to create resources, such as new RoleBindings or NetworkPolicies for a Namespace.
There are hundreds of policies from each type but we will use one from each and then provide you the link where you can explore all of it.Let’s start our demo with a Validation policy : Disallow Latest Tag
Validation policy
In real life project , it is not advised to use “latest” as image tag , the ‘:latest’ tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application Pod. This policy validates that the image specifies a tag and that it is not called `latest`.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
annotations:
policies.kyverno.io/title: Disallow Latest Tag
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
policies.kyverno.io/description: >-
The ':latest' tag is mutable and can lead to unexpected errors if the
image changes. A best practice is to use an immutable tag that maps to
a specific version of an application Pod. This policy validates that the image
specifies a tag and that it is not called `latest`.
spec:
validationFailureAction: enforce # You can change this to "audit" if you just want to monitor withour blocking developers.
background: true
rules:
- name: require-image-tag
match:
resources:
kinds:
- Pod
validate:
message: "An image tag is required."
pattern:
spec:
containers:
- image: "*:*"
- name: validate-image-tag
match:
resources:
kinds:
- Pod
validate:
message: "Using a mutable image tag e.g. 'latest' is not allowed."
pattern:
spec:
containers:
- image: "!*:latest
Once have added the Validation policy : Disallow Latest Tag to the rest of the other policies already applied , ArgoCD should notice the change and apply it to the new cluster policy.
New clusterPolicy added to the repo.
New ClusterPolicy deployed
It is show time now , if we deploy any application with “latest” Tag , deployment would fail and our error message will be displayed.
Let’s deploy a simple nginx deployment with “latest” Tag and see what would happens.
Bingoo….we could not deploy it due to our policy banning any deployment with “latest” Tag to be set up in the cluster.
Mutation policy
These policies are used to automatically modify resources that do not meet certain conditions. When a resource is created or updated, Kyverno will check the resource against the conditions specified in the policy. If the resource does not meet the conditions, Kyverno will automatically modify the resource to bring it into compliance.
In this example we are setting up and adding the label “ mykey: kyverno-demo” across all namespaces.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-labels
annotations:
policies.kyverno.io/title: Add Labels
policies.kyverno.io/category: Sample
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Label
policies.kyverno.io/description: >-
Labels are used as an important source of metadata describing objects in various ways
or triggering other functionality. Labels are also a very basic concept and should be
used throughout Kubernetes. This policy performs a simple mutation which adds a label
`foo=bar` to Pods, Services, ConfigMaps, and Secrets.
spec:
rules:
- name: add-labels
match:
resources:
kinds:
- namespace
mutate:
patchStrategicMerge:
metadata:
labels:
mykey: kyverno-demo
Add labels generation policy is added
Let’s go check if all our namespaces are labeled with mykey: kyverno-demo.
Namespaces labeled with mykey: kyverno-demo
Yessss… labels are applied to all namespaces in the cluster.
Now we will end up with Generation rule , let’s do it together.
Generation Policy
A “generate” rule in Kyverno is a type of policy that can be used to automatically create new resources based on certain conditions. These rules are defined using the “generate” field in a Kyverno ClusterPolicy CRD. This rule can be used to create additional resources when a new resource is created or when the source is updated. This is useful to create resources, such as new RoleBindings or NetworkPolicies for a Namespace.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-networkpolicy-existing
annotations:
policies.kyverno.io/title: Generate NetworkPolicy to Existing Namespaces
policies.kyverno.io/category: other
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Namespace, NetworkPolicy
kyverno.io/kyverno-version: 1.7.0
policies.kyverno.io/minversion: 1.7.0
kyverno.io/kubernetes-version: "1.23"
policies.kyverno.io/description: >-
A NetworkPolicy is often a critical piece when provisioning new Namespaces,
but there may be existing Namespaces which also need the same resource. Creating
each one individually or manipulating each Namespace in order to trigger creation
is additional overhead. This policy creates a new NetworkPolicy for existing
Namespaces which results in a default deny behavior and labels it with created-by=kyverno.
spec:
generateExistingOnPolicyUpdate: true
rules:
- name: generate-existing-networkpolicy
match:
any:
- resources:
kinds:
- Namespace
name: kubecost
generate:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
name: default-deny
namespace: kubecost # i will apply this network policy to kubecost namespace"
synchronize: true
data:
metadata:
labels:
created-by: mr-devops
spec:
podSelector: {}
policyTypes:
- Egress
This example is creating an egress network policy across all namespaces.
Generate network policy rule added.
Let’s go check if an Egress Network policy is created inside the “kubecost” namespace. We did itt !
Conclusion
Kyverno is an open-source Kubernetes policy management tool. It allows users to define, validate, and enforce policies for their Kubernetes clusters using a simple and flexible policy language. It can be used to ensure compliance, security, and operational best practices for Kubernetes resources. It can also be used to automatically inject, mutate, and validate resources as they are created or updated in the cluster. Overall, Kyverno can help users manage and maintain their Kubernetes clusters more effectively.
You can find all Policies here https://kyverno.io/policies/