Secure a Kubernetes Cluster
Scan a Kubernetes cluster against security and compliance best practices with cnspec.
Scan your Kubernetes cluster to find security risks before they become incidents. cnspec evaluates cluster configurations, deployments, pods, services, and RBAC settings. All you need is kubectl access to the cluster you want to assess.
Prerequisites
To scan Kubernetes with cnspec, you must have:
- cnspec installed on your workstation.
- kubectl installed on your workstation. Confirm access with
kubectl describe nodes.
Verify with a quick Kubernetes check
Confirm that cnspec can reach your Kubernetes cluster:
cnspec run k8s -c 'k8s.deployment.name != "foo"'This asserts that none of your deployments are named foo. cnspec returns a report listing your deployments. For each, it indicates whether the deployment meets the requirement (not named foo):
[passed] k8s.deployment.name != "foo"
[ok] value: "coredns"
[ok] value: "luna-frontend"
[ok] value: "postgres"Scan with policy-based assessments
Mondoo maintains out-of-the-box Kubernetes Security and Kubernetes Best Practices policies that check for misconfigurations across your entire Kubernetes infrastructure: pod security, RBAC, network policies, resource limits, and more.
To scan with the default policies, run:
cnspec scan k8sMondoo Platform users: Enable the policies in your space. In the Mondoo Console, go to Findings > Policies, search for "Kubernetes", and add the policies. All future scans of your clusters automatically evaluate against them. To learn more, read Manage Policies.
Open source users: Pass a policy bundle URL directly to cnspec to pin a specific version:
cnspec scan k8s \
--policy-bundle https://raw.githubusercontent.com/mondoohq/cnspec/refs/heads/main/content/mondoo-kubernetes-security.mql.yamlcnspec returns a report summarizing the scan results:
Show or hide example scan results
→ discover related assets for 1 asset(s)
→ use cluster name from kube config cluster-name=minikube
→ discovery option auto detected: cluster, jobs, cronjobs, pods, statefulsets, deployments, replicasets, daemonsets
→ resolved assets resolved-assets=20
→ connecting to asset K8s Cluster minikube (api)
→ connecting to asset kube-system/coredns (k8s-object)
→ connecting to asset luna/luna-frontend (k8s-object)
→ connecting to asset luna/postgres (k8s-object)
Asset: kube-system/coredns
==========================
Checks:
✓ Pass: Container should not mount the CRI-O socket
✓ Pass: Pod should not run with hostIPC
✓ Pass: Pod should not run with hostPID
✓ Pass: Deployments should not bind to a host port
✓ Pass: Deployments should not run with NET_RAW capability
✕ Fail: A 80 Container should have a CPU limit
✓ Pass: Container should request memory
✓ Pass: Deployments should not run in the default namespace
✓ Pass: Container should configure a livenessProbe
. Unknown: Pods should not run Kubernetes dashboard
✕ Fail: A 80 Container should have a memory limit
✕ Fail: C 40 Container image pull should be consistent
✕ Fail: F 0 Container should not run as root
✓ Pass: Pod should not run with the default service account
✓ Pass: Container should not allow privilege escalation
Summary
=======
Score: B 72/100To see scan results in full detail, run:
cnspec scan k8s -o fullYou can also create your own policies to meet your specific needs. To learn more about policies, read Policies.
Explore and test checks interactively
The cnspec shell is handy for quick checks and tests, or for developing your MQL skills. Its auto-complete and help features guide you in writing checks.
To launch a shell connected to your Kubernetes environment:
cnspec shell k8scnspec automatically discovers the Kubernetes assets available to query:
→ resolved assets resolved-assets=20
Available assets
8. luna/luna-frontend-7fb96c846b-2k5j7 (k8s-pod)
> 9. luna/luna-frontend-7fb96c846b-8b94j (k8s-pod)
10. luna/luna-frontend-7fb96c846b-jglt9 (k8s-pod)
11. kube-system/kube-controller-manager-minikube (k8s-pod)
12. kube-system/kube-proxy-cdzrr (k8s-pod)
13. kube-system/kube-scheduler-minikube (k8s-pod)
14. kube-system/storage-provisioner (k8s-pod)
•••Use the arrow keys to highlight a row, then press Enter to choose the asset you want to explore.
Discover capabilities with the help command
Inside the shell, use the help command to learn what Kubernetes resources you can test:
help k8sYou can drill down further. For example, list all the Kubernetes service resources you can test:
help k8s.serviceYou can also browse available Kubernetes resources in the Mondoo Kubernetes Resource Pack Reference.
Query namespaces
cnspec> k8s.namespaces { uid name }
k8s.namespaces: [
0: {
uid: "a6809146-53e4-4086-b289-0d368ba298d4"
name: "default"
}
1: {
uid: "73ce97b9-b3d7-42ad-bf4f-a9fef35d6f67"
name: "kube-system"
}
]Filter services by namespace
cnspec> k8s.services.where(namespace == "luna") { name spec['type'] spec['clusterIP'] }Example security checks
Ensure Pods aren't using HostAliases
This check asserts that DNS entries aren't managed locally using /etc/hosts within Pods:
cnspec> k8s.pod { podSpec['hostAliases'] == null }If the check passes, cnspec returns ok. If it fails, cnspec lists the offending Pods.
Ensure no workloads run in the default namespace
cnspec> k8s.pods { namespace != "default" }To include identifying fields in the output, list them inside the braces:
cnspec> k8s.pods { namespace != "default" id name created namespace }Exit the cnspec shell
To exit the cnspec shell, either press Ctrl + D or type exit.
Learn more
- Mondoo Kubernetes Resource Pack Reference — every Kubernetes resource and field cnspec can query
- Write Effective MQL — guide to authoring checks and queries
- Secure Kubernetes Manifests — scan Kubernetes YAML manifests in CI/CD