Chuyển đến nội dung chính

LESSON 37: KYVERNO POLICY ENGINE

Deploy Kyverno policy engine, validation/mutation/generation policies, best practices enforcement, image verification, and policy-as-code workflow with GitOps.

🔒 DevSecOps — Lesson 37 LESSON 37: KYVERNO POLICY ENGINE

Deploy Microservices On-Premises with Kubernetes HA

Part 9: Security Hardening

xdev.asia

🎯 LESSON OBJECTIVE__HTMLTAG_66___
  • ✅ Kyverno architecture and admission webhooks
  • ✅ Validation policies (block dangerous configs)
  • ✅ Mutation policies (inject defaults)
  • ✅ Generation policies (auto-create resources)
  • ✅ Image verification (cosign signatures)
  • ✅ Policy-as-code GitOps workflow__HTMLTAG_79___

PART 1: KYVERNO ARCHITECTURE


Kyverno Flow:

kubectl apply
      │
      ▼
┌──────────┐    ┌──────────────────┐
│API Server│───►│ Kyverno Webhook  │
│          │    │  (Admission)     │
│          │    │                  │
│          │◄───│ Allow / Deny /   │
│          │    │ Mutate resource  │
└──────────┘    └──────────────────┘
                        │
                ┌───────┴────────┐
                │   Policies     │
                │ - Validate     │
                │ - Mutate       │
                │ - Generate     │
                │ - VerifyImages │
                └────────────────┘
# Install Kyverno:
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

helm install kyverno kyverno/kyverno \
  --namespace kyverno \
  --create-namespace \
  -f kyverno-values.yaml
# kyverno-values.yaml:
admissionController:
  replicas: 3
  resources:
    requests:
      cpu: 100m
      memory: 256Mi
    limits:
      cpu: 500m
      memory: 512Mi

backgroundController:
  replicas: 2

cleanupController:
  replicas: 2

reportsController:
  replicas: 2

PART 2: VALIDATION POLICY

# Require resource limits:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-resource-limits
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: validate-limits
      match:
        any:
          - resources:
              kinds: ["Pod"]
      exclude:
        any:
          - resources:
              namespaces: ["kube-system", "kyverno"]
      validate:
        message: "CPU and memory limits are required"
        pattern:
          spec:
            containers:
              - resources:
                  limits:
                    memory: "?*"
                    cpu: "?*"

---
# Disallow privileged containers:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-privileged
spec:
  validationFailureAction: Enforce
  rules:
    - name: deny-privileged
      match:
        any:
          - resources:
              kinds: ["Pod"]
      validate:
        message: "Privileged containers are not allowed"
        pattern:
          spec:
            containers:
              - securityContext:
                  privileged: "!true"

---
# Require labels:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: Enforce
  rules:
    - name: check-labels
      match:
        any:
          - resources:
              kinds: ["Deployment", "StatefulSet"]
      validate:
        message: "Labels app and team are required"
        pattern:
          metadata:
            labels:
              app: "?*"
              team: "?*"

---
# Disallow latest tag:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: Enforce
  rules:
    - name: validate-image-tag
      match:
        any:
          - resources:
              kinds: ["Pod"]
      validate:
        message: "Image tag 'latest' is not allowed"
        pattern:
          spec:
            containers:
              - image: "!*:latest"

PART 3: MUTATION POLICY

# Auto-inject default securityContext:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-security-context
spec:
  rules:
    - name: add-security-context
      match:
        any:
          - resources:
              kinds: ["Pod"]
      exclude:
        any:
          - resources:
              namespaces: ["kube-system"]
      mutate:
        patchStrategicMerge:
          spec:
            securityContext:
              runAsNonRoot: true
              seccompProfile:
                type: RuntimeDefault
            containers:
              - (name): "*"
                securityContext:
                  allowPrivilegeEscalation: false
                  capabilities:
                    drop: ["ALL"]

---
# Auto-add imagePullSecrets:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-image-pull-secret
spec:
  rules:
    - name: add-pull-secret
      match:
        any:
          - resources:
              kinds: ["Pod"]
      mutate:
        patchStrategicMerge:
          spec:
            imagePullSecrets:
              - name: harbor-registry-creds

PART 4: GENERATION POLICY

# Auto-create NetworkPolicy for new namespaces:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-default-networkpolicy
spec:
  rules:
    - name: deny-all-ingress
      match:
        any:
          - resources:
              kinds: ["Namespace"]
      exclude:
        any:
          - resources:
              names: ["kube-system", "kyverno", "monitoring"]
      generate:
        synchronize: true
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        name: default-deny-all
        namespace: "{{request.object.metadata.name}}"
        data:
          spec:
            podSelector: {}
            policyTypes:
              - Ingress
              - Egress
            ingress: []
            egress:
              - to: []
                ports:
                  - port: 53
                    protocol: UDP
                  - port: 53
                    protocol: TCP

---
# Auto-create ResourceQuota per namespace:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-resource-quota
spec:
  rules:
    - name: create-quota
      match:
        any:
          - resources:
              kinds: ["Namespace"]
              selector:
                matchLabels:
                  type: application
      generate:
        synchronize: true
        apiVersion: v1
        kind: ResourceQuota
        name: default-quota
        namespace: "{{request.object.metadata.name}}"
        data:
          spec:
            hard:
              requests.cpu: "4"
              requests.memory: 8Gi
              limits.cpu: "8"
              limits.memory: 16Gi
              pods: "50"

PART 5: IMAGE VERIFICATION

# Require signed images (cosign):
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-cosign
      match:
        any:
          - resources:
              kinds: ["Pod"]
      verifyImages:
        - imageReferences:
            - "harbor.local/*"
          attestors:
            - entries:
                - keys:
                    publicKeys: |-
                      -----BEGIN PUBLIC KEY-----
                      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
                      -----END PUBLIC KEY-----
# Sign images with cosign:
cosign generate-key-pair

# Sign:
cosign sign --key cosign.key harbor.local/order-service:v1.0

# Verify:
cosign verify --key cosign.pub harbor.local/order-service:v1.0

PART 6: POLICY REPORTS

# View policy reports:
kubectl get policyreport -A
kubectl get clusterpolicyreport

# Detailed report:
kubectl get policyreport -n default polr-ns-default -o yaml

# Policy violations dashboard:
# Kyverno exports metrics → Prometheus → Grafana
# kyverno_policy_results_total{rule_result="fail"}

💡 KEY TAKEAWAYS

  1. Kyverno: Kubernetes-native policy engine (YAML, no Rego)
  2. Validate: Block non-compliant resources
  3. Mutate: Auto-inject security defaults
  4. Generate: Auto-create NetworkPolicy, ResourceQuota
  5. Image verification: Require cosign signatures
  6. Policy reports: Audit compliance across cluster

🎯 EXERCISE

Exercise 1: Core Policies__HTMLTAG_132___
  • Deploy Kyverno, create validation policies__HTMLTAG_135___
  • Test: deploy pod without limits → should be blocked
  • Create mutation policy for securityContext

Exercise 2: Policy Reports

  • Scan existing cluster with Audit mode policies__HTMLTAG_145___
  • Review policy reports for violations
  • Switch to Enforce mode after fixing violations

📚 NEXT POST

In Lesson 38: Falco Runtime Security, we will implement runtime threat detection.