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.deployments.none(name == "foo")'

This asserts that none of your deployments are named foo. cnspec runs the query against every asset it discovers in the cluster, such as the cluster itself, its namespaces, and its workloads, and returns a result for each:

[ok] value: true

[ok] value: true

[ok] value: true

Scan with policy-based assessments

Mondoo maintains out-of-the-box Mondoo Kubernetes Cluster and Workload Security and Mondoo 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 App, 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 in Mondoo Platform.

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)

Asset: (Kubernetes Deployment) kube-system/coredns
--------------------------------------------------

Passing:
✓ Container should configure a livenessProbe
✓ Container should not allow privilege escalation
✓ Container should not mount the CRI-O socket
✓ Container should request memory
✓ Deployments should not bind to a host port
✓ Deployments should not run in the default namespace
✓ Deployments should not run with NET_RAW capability
✓ Pod should not run with hostIPC
✓ Pod should not run with hostPID
✓ Pod should not run with the default service account

Failing:
✕ LOW (20):       Container should have a CPU limit
✕ LOW (20):       Container should have a memory limit
✕ MEDIUM (60):    Deployment container image pull should be consistent
✕ CRITICAL (100): Container should not run as root

Scanned 20 assets

Kubernetes Cluster
  MEDIUM (45):  minikube

Kubernetes Deployment
  MEDIUM (60):  kube-system/coredns
  LOW (20):     luna/luna-frontend
  HIGH (75):    luna/postgres

To see scan results in full detail, run:

cnspec scan k8s -o full

cnspec scores each asset and summarizes the results. To learn how to read a report in depth, see Understand Scan Results.

You can also create your own policies to meet your specific needs. To learn more about policies, read Policies.

Connection options

The k8s provider accepts these connection and scope options:

OptionDescription
--contextTarget a specific Kubernetes context from your kubeconfig
--namespacesOnly include Kubernetes objects in the matching namespaces
--namespaces-excludeFilter out Kubernetes objects in the matching namespaces
--namespace-label-selectorOnly include namespaces matching the label selector, along with the objects in them
--object-label-selectorOnly include Kubernetes objects matching the label selector
--imagesOnly include container images matching these image references during discovery
--images-excludeFilter out container images matching these image references during discovery
--container-proxyHTTP proxy to use for container image pulls
--kubeloginAuthenticate against a remote Azure AD enabled Kubernetes cluster using an Azure identity

The --images and --images-exclude options take a comma-separated list of image references and support glob patterns.

Choose which assets to discover

By default, cnspec discovers the cluster, its namespaces, and the workloads in them as separate assets. Use the --discover flag to choose which Kubernetes object types become their own assets. Supported values are auto, all, clusters, namespaces, pods, deployments, replicasets, statefulsets, daemonsets, jobs, cronjobs, services, ingresses, container-images, and admissionreviews. For example, to scan only the cluster and its deployments:

cnspec scan k8s --discover clusters,deployments

Container images are not part of auto. To also scan the images your workloads run, add container-images:

cnspec scan k8s --discover auto,container-images

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:

    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:

cnspec> help k8s

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

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

Continuously scan with Mondoo Platform

Go beyond one-off scans. Use Mondoo Platform and the Mondoo Kubernetes integration to continuously monitor your clusters. Get a real-time security dashboard, track your posture over time, and catch new misconfigurations as workloads change.

Learn more

On this page