CloudKubernetes

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:

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 k8s

Mondoo 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.yaml

cnspec 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/100

To see scan results in full detail, run:

cnspec scan k8s -o full

You 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 k8s

cnspec 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 k8s

You can drill down further. For example, list all the Kubernetes service resources you can test:

help k8s.service

You 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

On this page