Secure your Kubernetes cluster with Kyverno and ArgoCD

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 ?

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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 ?

  1. 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.
  2. 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.
  3. Generation policies: 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/