Kubernetes Policy
In this post I will show you how you can enforce best practices on Kubernetes Clusters.
Updated July 2021: Updated Features/Capabilities table. Notable change: Added “Self-service reports” comparison, the ability for non-policy admins to view policy violations (decoupled from policy objects).
Updated June 2021: Updated Features/Capabilities table. Notable changes: Kyverno now supports high availability and metrics.
Updated Aug 2021: Updated Features/Capabilities table. Notable changes: Kyverno now supports Image Signature Verification with Cosign
Parts of the K8S Security Lab series
Container Runetime Security
- Part1: How to deploy CRI-O with Firecracker?
- Part2: How to deploy CRI-O with gVisor?
- Part3: How to deploy containerd with Firecracker?
- Part4: How to deploy containerd with gVisor?
- Part5: How to deploy containerd with kata containers?
Advanced Kernel Security
- Part1: Hardening Kubernetes with seccomp
- Part2: Linux user namespace management wit CRI-O in Kubernetes
- Part3: Hardening Kubernetes with seccomp
Network Security
- Part1: RKE2 Install With Calico
- Part2: RKE2 Install With Cilium
- Part3: CNI-Genie: network separation with multiple CNI
- Part3: Configurre network wit nmstate operator
- Part3: Kubernetes Network Policy
- Part4: Kubernetes with external Ingress Controller with vxlan
- Part4: Kubernetes with external Ingress Controller with bgp
- Part4: Central authentication with oauth2-proxy
- Part5: Secure your applications with Pomerium Ingress Controller
- Part6: CrowdSec Intrusion Detection System (IDS) for Kubernetes
- Part7: Kubernetes audit logs and Falco
Secure Kubernetes Install
- Part1: Best Practices to keeping Kubernetes Clusters Secure
- Part2: Kubernetes Secure Install
- Part3: Kubernetes Hardening Guide with CIS 1.6 Benchmark
- Part4: Kubernetes Certificate Rotation
User Security
- Part1: How to create kubeconfig?
- Part2: How to create Users in Kubernetes the right way?
- Part3: Kubernetes Single Sign-on with Pinniped OpenID Connect
- Part4: Kubectl authentication with Kuberos Depricated !!
- Part5: Kubernetes authentication with Keycloak and gangway Depricated !!
- Part6: kube-openid-connect 1.0 Depricated !!
Image Security
Pod Security
- Part1: Using Admission Controllers
- Part2: RKE2 Pod Security Policy
- Part3: Kubernetes Pod Security Admission
- Part4: Kubernetes: How to migrate Pod Security Policy to Pod Security Admission?
- Part5: Pod Security Standards using Kyverno
- Part6: Kubernetes Cluster Policy with Kyverno
Secret Security
- Part1: Kubernetes and Vault integration
- Part2: Kubernetes External Vault integration
- Part3: ArgoCD and kubeseal to encript secrets
- Part4: Flux2 and kubeseal to encrypt secrets
- Part5: Flux2 and Mozilla SOPS to encrypt secrets
Monitoring and Observability
- Part6: K8S Logging And Monitoring
- Part7: Install Grafana Loki with Helm3
Backup
For a production ready Kubernetes cluster it is very important to enforcing cluster-wide policies to restrict what a container is allowed to do. We do this wit PS in a previous pos. But how should we enforce our best practices to the cluster users?
OPA
Open Policy Agent (OPA), is a policy engine for Cloud Native environments hosted by CNCF. It is a general purpose policy engine. OPA policies are written in a Domain Specific Language (DSL) called Rego.
OPA Gatekeeper
Gatekeeper is specifically built for Kubernetes Admission Control use case of OPA. It uses OPA internally, but specifically for the Kubernetes admission control. Compared to using OPA with its sidecar kube-mgmt (aka Gatekeeper v1.0), Gatekeeper is integrated with the OPA Constraint Framework to enforce CRD-based policies and allow declaratively configured policies to be reliably shareable.
Install OPA Gatekeeper:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml
Now we need to create a policy template and a constraint that adds the variables to the template. If I want to create a policy to enforce all image comes from Only gcr.io, I need this Template:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredregistry
spec:
crd:
spec:
names:
kind: K8sRequiredRegistry
validation:
# Schema for the `parameters` field
openAPIV3Schema:
properties:
image:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredregistry
violation[{"msg": msg, "details": {"Registry should be": required}}] {
input.review.object.kind == "Pod"
some i
image := input.review.object.spec.containers[i].image
required := input.parameters.registry
not startswith(image,required)
msg := sprintf("Forbidden registry: %v", [image])
}
This template defines which parameters you need to define as well as the actual Rego code that will do the validation. Fo the constraint we specify that we need this constraint applied to Pods only and we pass the registry name that we need the images to be pulled from.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredRegistry
metadata:
name: images-must-come-from-gcr
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
registry: "gcr.io/"
Test the policy with an image from github:
kubectl run --generator=run-pod/v1 busybox1 --image=busybox -- sleep 3600
message: 'admission webhook "validation.gatekeeper.sh" denied the request: [denied
by images-must-come-from-gcr] Forbidden registry: busybox'
Another great feature of OPA Gatekeeper is audit functionality, it enables periodic evaluations of replicated resources against the policies enforced in the cluster to detect pre-existing misconfigurations.
Audit results are stored as violations listed in the status field of the failed constraint.
kubectl describe policystrictonly.constraints.gatekeeper.sh policy-strict-constraint
OPA and Gatekeeper
You can deploy OPA kube-mgmt as both validating webhook as well as mutating webhook configurations. Whereas, Gatekeeper currently does not support mutating admission control scenarios.
Kyverno
Kyverno is a policy engine designed for Kubernetes. With Kyverno, policies are managed as Kubernetes resources and no new language is required to write policies. This allows using familiar tools such as kubectl, git, and kustomize to manage policies. Kyverno policies can validate, mutate, and generate Kubernetes resources. The Kyverno CLI can be used to test policies and validate resources as part of a CI/CD pipeline. (Source: Kyverno )
Install kyverno:
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno --namespace kyverno kyverno/kyverno --create-namespace
Validate configurations
Here is an example of a Kyverno policy that validates that images are only pulled from gcr.io:
apiVersion : kyverno.io/v1alpha1
kind: Policy
metadata:
name: check-registries
spec:
rules:
- name: check-registries
resource:
kinds:
- Deployment
- StatefulSet
validate:
message: "Registry is not allowed"
pattern:
spec:
template:
spec:
containers:
- name: "*"
# Check allowed registries
image: "*/gcr.io/*"
Here the kind
is Policy
not ClusterPolicy
which means policies will only apply to resources within the namespace in which they are defined.
Mutate Configurations
Kyverno supports two different ways to mutate configurations. The first approach is to use a JSON Patch:
apiVersion : kyverno.io/v1alpha1
kind : Policy
metadata :
name : policy-deployment
spec :
rules:
- name: patch-add-label
resource:
kinds :
- Deployment
mutate:
patches:
- path: /metadata/labels/isMutated
op: add
value: "true"
The other way to mutate resources based on conditionals that describes the desired state:
apiVersion: kyverno.io/v1alpha1
kind: Policy
metadata:
name: set-image-pull-policy
spec:
rules:
- name: set-image-pull-policy
resource:
kinds:
- Deployment
mutate:
overlay:
spec:
template:
spec:
containers:
# if the image tag is latest, set the imagePullPolicy to Always
- (image): "*:latest"
imagePullPolicy: "Always"
Generate Configurations
Policy rule can generates new configurations:
apiVersion: kyverno.io/v1alpha1
kind: Policy
metadata:
name: "default"
spec:
rules:
- name: "deny-all-traffic"
resource:
kinds:
- Namespace
name: "*"
generate:
kind: NetworkPolicy
name: deny-all-traffic
data:
spec:
podSelector:
matchLabels: {}
matchExpressions: []
policyTypes: []
metadata:
annotations: {}
labels:
policyname: "default"
Policy Reports
Kyverno policy reports provide information about policy execution and violations. Kyverno creates policy reports for each Namespace and a single cluster-level report for cluster resources.
$ kubectl get polr -A
NAMESPACE NAME PASS FAIL WARN ERROR SKIP AGE
default polr-ns-default 338 2 0 0 0 28h
flux-system polr-ns-flux-system 135 5 0 0 0 28h
$ kubectl get clusterpolicyreport -A
NAME PASS FAIL WARN ERROR SKIP AGE
clusterpolicyreport 0 0 0 0 0 142m
$ kubectl describe polr polr-ns-default | grep "Status: \+fail" -B10
Message: validation error: Running as root is not allowed. The fields spec.securityContext.runAsNonRoot, spec.containers[*].securityContext.runAsNonRoot, and spec.initContainers[*].securityContext.runAsNonRoot must be `true`. Rule check-containers[0] failed at path /spec/securityContext/runAsNonRoot/. Rule check-containers[1] failed at path /spec/containers/0/securityContext/.
Policy: require-run-as-non-root
Resources:
API Version: v1
Kind: Pod
Name: add-capabilities-init-containers
Namespace: default
UID: 1caec743-faed-4d5a-90f7-5f4630febd58
Rule: check-containers
Scored: true
Status: fail
--
Message: validation error: Running as root is not allowed. The fields spec.securityContext.runAsNonRoot, spec.containers[*].securityContext.runAsNonRoot, and spec.initContainers[*].securityContext.runAsNonRoot must be `true`. Rule check-containers[0] failed at path /spec/securityContext/runAsNonRoot/. Rule check-containers[1] failed at path /spec/containers/0/securityContext/.
Policy: require-run-as-non-root
Resources:
API Version: v1
Kind: Pod
Name: sysctls
Namespace: default
UID: b98bdfb7-10e0-467f-a51c-ac8b75dc2e95
Rule: check-containers
Scored: true
Status: fail
Comparison
Features/Capabilities | OPA Gatekeeper | Kyverno |
---|---|---|
Validation | ✓ | ✓ |
Mutation | alpha | ✓ |
Generation | X | ✓ |
Policy as native resources | Rego in CRD | ✓ |
Metrics exposed | ✓ | ✓ |
OpenAPI validation schema (kubectl explain) | X | ✓ |
High Availability | ✓ | alpha |
API object lookup | ✓ | ✓ |
CLI with test ability | ✓ | ✓ |
Policy audit ability | ✓ | ✓ |
Self-service reports | X | ✓ |
Image Signature Verification | X | ✓ |