KubeLinter – linter for the Kubernetes



KubeLinter is a static analysis tool that detects misconfigurations in Kubernetes deployments. That CLI tool can automatically analyzes YAML files against Kubernetes configuration and security best practices.


Installation is quite easy.

GOBIN=$(pwd) GO111MODULE=on go install golang.stackrox.io/kube-linter/cmd/kube-linter@latest
sudo mv kube-linter /usr/local/bin/

Of course you there are other options available like: brew, from source or docker however if you have environment configured for go-lang development, that option is the best.


$ kube-linter -h
  kube-linter [command]

Available Commands:
  checks      View more information on lint checks
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  lint        Lint Kubernetes YAML files and Helm charts
  templates   View more information on check templates
  version     Print version and exit

  -h, --help         help for kube-linter
      --with-color   Force color output (default true)

Use "kube-linter [command] --help" for more information about a command.

As you an see there are few options (which is good) to follow. Let start from lint

Usage KubeLinter: lint

As a example I prepared standard jenkins.yaml file:

apiVersion: extensions/v1beta1
kind: Deployment
  name: jenkins-deployment
  replicas: 1
      app: jenkins
        app: jenkins
        - name: jenkins
          image: jenkins/jenkins:lts
            - containerPort: 8080
            - name: jenkins-home
              mountPath: /var/jenkins_home
        - name: jenkins-home
          emptyDir: {}

And KubeLinter in action:

$ kube-linter lint jenkins.yaml 
KubeLinter development

jenkins-deployment.yaml: (object: <no namespace>/jenkins-deployment extensions/v1beta1, Kind=Deployment) disallowed API object found: extensions/v1beta1, Kind=Deployment (check: no-extensions-v1beta, remediation: Migrate using the apps/v1 API versions for the objects. Refer to https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/ for details.)

Error: found 1 lint errors

Quite detailed information pointing where exactly is a problem, which check has been used and even remediation proposition.

Another YAML is much simpler:

apiVersion: v1
  password: cGFzc3dvcmQ0cG9zdGZpeAo=
  username: dXNlcm5hbWU0bmV3cG9zdGZpeAo=
kind: Secret
  creationTimestamp: "2022-01-18T05:17:25Z"
  name: credentials
  namespace: test-ns
  resourceVersion: "5526322"
  selfLink: /api/v1/namespaces/test-ns/secrets/credentials
  uid: 87a0f786-9c6d-4a96-b2d6-7553de7b3d40
type: Opaque

And the result:

$ kube-linter lint credential.yaml 
KubeLinter development

No lint errors found!

However, if I break configuration by adding 22 at the end of the password (it won't be valid hash) the result is odd.

$ kube-linter lint credential.yaml 
Warning: no valid objects found.

And the return code is 0

Last example:

apiVersion: v1
kind: Pod
  name: pod.vol
    - name: 'pod-data1'
          path: '/k8s/volumes'
    - image: nginx
      name: ngx
        - mountPath: "/data1"
          name: "pod-data1"
            cpu: "500m"
            memory: "128Mi"
            cpu: "1000m"
            memory: "254Mi"
        - containerPort: 80
          name: http
          protocol: TCP

And quite interesting output:

$ kube-linter lint pod_vol.yml 
KubeLinter development

pod_vol.yml: (object: <no namespace>/pod.vol /v1, Kind=Pod) The container "ngx" is using an invalid container image, "nginx". Please use images that are not blocked by the `BlockList` criteria : [".*:(latest)$" "^[^:]*$" "(.*/[^:]+)$"] (check: latest-tag, remediation: Use a container image with a specific tag other than latest.)

pod_vol.yml: (object: <no namespace>/pod.vol /v1, Kind=Pod) container "ngx" does not have a read-only root file system (check: no-read-only-root-fs, remediation: Set readOnlyRootFilesystem to true in the container securityContext.)

pod_vol.yml: (object: <no namespace>/pod.vol /v1, Kind=Pod) container "ngx" is not set to runAsNonRoot (check: run-as-non-root, remediation: Set runAsUser to a non-zero number and runAsNonRoot to true in your pod or container securityContext. Refer to https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ for details.)

Error: found 3 lint errors

At first glance, using of KubeLinter is extremely easy and productive. Output is human readable and alarming if misconfiguration is detected.

Usage KubeLinter: checks

Checks are the items which contains actually the rules which liner is following during the scanning of the YAML. To list all checks run following command:

$ kube-linter checks list

Name: access-to-create-pods
Description: Indicates when a subject (Group/User/ServiceAccount) has create access to Pods. CIS Benchmark 5.1.4: The ability to create pods in a cluster opens up possibilities for privilege escalation and should be restricted, where possible.
Remediation: Where possible, remove create access to pod objects in the cluster.
Template: access-to-resources
Parameters: map[resources:[^pods$ ^deployments$ ^statefulsets$ ^replicasets$ ^cronjob$ ^jobs$ ^daemonsets$] verbs:[^create$]]
Enabled by default: false

You can select which checks you want to use during the scanning. That can be set in configuration file and/or via parameters/flags.

Additionally, there is a nice feature. You can extend the list of checks by adding your own ones. Of course it requires go-lang software development experience but still it's possible. Hot to do that? Find here

You can skip the check for the Kubernetes resources by adding annotation in the manifest like:

ignore-check.kube-linter.io/privileged: "This deployment needs to run as privileged because it needs kernel access

Usage KubeLinter: templates

Basically this is group of checks and adding a custom check is feasible based on template.


In general, configuration contains setting which checks should be executed and which doesn't. It can be specified by parameter --config or can be put to the file  .kube-linter.yaml  or .kube-linter.yml in current working directory. Obviously the second options is better for CI/CD pipelines whereas --config parameter is better for ad hoc testings.


  doNotAutoAddDefaults: true
  - "privileged-container"
  - "run-as-non-root"

More here: https://docs.kubelinter.io/#/configuring-kubelinte


Despite being a fairly fresh project it can be adopted by DevOps or Developer in the pipelines. Especially, because is configurable and quite easy can be extended. Flexibility always matters.

More info:

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *