Kyverno Setup on EKS

Kyverno Setup on EKS

1. Confirm cluster context

kubectl config current-context
kubectl get nodes

2. Add the Kyverno Helm repo

helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

3. Install Kyverno

kubectl create namespace kyverno

helm install kyverno kyverno/kyverno \
  -n kyverno \
  --set replicaCount=3 \
  --wait

4. Verify

kubectl get pods -n kyverno
kubectl get deploy -n kyverno

5. Policy examples

Each example is a standalone ClusterPolicy. Replace my-app-namespace with the target namespace. Policies can be combined into one file by merging rules under a single spec.rules list.

Allowed registries

Only allow images from the account ECR or public.ecr.aws.

allowed-registries.yaml:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: allowed-registries
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: allowed-registries
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - my-app-namespace
      validate:
        message: "Images must come from an approved registry (ECR account or public.ecr.aws)."
        pattern:
          spec:
            containers:
              - image: "<YOUR_ACCOUNT_ID>.dkr.ecr.*.amazonaws.com/* | public.ecr.aws/*"

Disallow :latest tag

Block implicit or explicit :latest image tags.

disallow-latest-tag.yaml:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: disallow-latest-tag
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - my-app-namespace
      validate:
        message: "Images must not use the ':latest' tag or omit a tag."
        pattern:
          spec:
            containers:
              - image: "!*:latest"
                =(imagePullPolicy): "!Always"

Require resource limits

Require CPU and memory limits on all containers.

require-resource-limits.yaml:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resource-limits
spec:
  validationFailureAction: Enforce
  rules:
    - name: require-limits
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - my-app-namespace
      validate:
        message: "CPU and memory limits are required."
        pattern:
          spec:
            containers:
              - resources:
                  limits:
                    memory: "?*"
                    cpu: "?*"

Disallow privileged containers

Prevent pods from running privileged containers.

disallow-privileged.yaml:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: Enforce
  rules:
    - name: disallow-privileged
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - my-app-namespace
      validate:
        message: "Privileged containers are not allowed."
        pattern:
          spec:
            containers:
              - securityContext:
                  privileged: false

Require labels

Require standard labels on every pod.

require-labels.yaml:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: Enforce
  rules:
    - name: require-labels
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - my-app-namespace
      validate:
        message: "Labels 'app' and 'env' are required."
        pattern:
          metadata:
            labels:
              app: "?*"
              env: "?*"

Apply one or more policies:

kubectl apply -f allowed-registries.yaml
kubectl apply -f disallow-latest-tag.yaml
kubectl apply -f require-resource-limits.yaml
kubectl apply -f disallow-privileged.yaml
kubectl apply -f require-labels.yaml

6. Remove a ClusterPolicy

# List what's currently applied
kubectl get clusterpolicy

# Delete a specific ClusterPolicy
kubectl delete clusterpolicy allowed-registries
kubectl delete clusterpolicy disallow-latest-tag

# Delete all ClusterPolicies (removes every policy cluster-wide)
kubectl delete clusterpolicy --all

7. Debug

kubectl logs -n kyverno \
  -l app.kubernetes.io/component=admission-controller \
  --tail=50

kubectl get pods -n kyverno
kubectl get pods -n kyverno -o wide

kubectl logs -n kyverno -l app.kubernetes.io/component=admission-controller -f --tail=20