Mastering Kubernetes: How to validate Kubernetes YAML Files Part 3

Mastering Kubernetes: How to validate Kubernetes YAML Files Part 3

kube-score

Introduction

Before we can even use our tool Kubectl to send our workload YAML files, we need to make sure we follow the best settings, practices in these files.

We need a tool to help us check and validate our YAML files.

Today we will focus on kube-score which is a tool that performs static code analysis of your Kubernetes object definitions. Exactly what we need!

How to use Kube-Score?

As always we have several options to install the tool

  • command-line tool
  • Docker

We will use first the Docker option as it is very simple :)

We can find the docker image in the link

[GitHub - zegl/kube-score: Kubernetes object analysis with recommendations for improved reliability…
kube-score is a tool that performs static code analysis of your Kubernetes object definitions. The output is a list of…github.com](https://github.com/zegl/kube-score "github.com/zegl/kube-score")

[Docker Hub
Edit descriptionhub.docker.com](https://hub.docker.com/r/zegl/kube-score/ "hub.docker.com/r/zegl/kube-score")

All we need is to pull the docker image with:

docker pull zegl/kube-score

Let’s do it!

λ docker pull zegl/kube-score
Using default tag: latest
latest: Pulling from zegl/kube-score
1b9df04e6215: Pull complete
3e6314b120ac: Pull complete
Digest: sha256:df26b2d3978be960b41e8c09906a38f3e5ad7ef3c63b8770c693dc3405005299
Status: Downloaded newer image for zegl/kube-score:latest
docker.io/zegl/kube-score:latest

We can check our local repo:

λ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
zegl/kube-score latest 6afa21f585fe 8 months ago 18.8MB

We can see it is pretty small.

Now we have Minikube cluster running, we have our YAML file validator installed with docker, how do we create our first workload YAML deployment file and validate it?

Let’s see!

Workload YAML deployment File Creation and Validation

To create easily a sample workload YAML deployment file for Kubernetes we can use the Kubectl tool with the command create.

kubectl create deployment mydeployment --image=myimage --dry-run=client -o yaml > mydeployment.yaml

We just pipelined the deployment YAML file to a file called mydeployment.yaml with fake docker image “myimage” just for an example.

We will not run this deployment, we will just validate it with kube-score!

Let’s see the content of the YAML file: mydeployment.yaml

λ cat mydeployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: mydeployment
name: mydeployment
spec:
replicas: 1
selector:
matchLabels:
app: mydeployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: mydeployment
spec:
containers:
- image: myimage
name: myimage
resources: {}
status: {}

We can see the dummy docker image: myimage and the rest is standard.

Let’s use docker and kube-score to validate our YAML file:

λ docker run -v %cd%:/project zegl/kube-score:latest score mydeployment.yaml
apps/v1/Deployment mydeployment �
[CRITICAL] Container Resources
· myimage -> CPU limit is not set
Resource limits are recommended to avoid resource DDOS. Set
resources.limits.cpu
· myimage -> Memory limit is not set
Resource limits are recommended to avoid resource DDOS. Set
resources.limits.memory
· myimage -> CPU request is not set
Resource requests are recommended to make sure that the application
can start and run without crashing. Set resources.requests.cpu
· myimage -> Memory request is not set
Resource requests are recommended to make sure that the application
can start and run without crashing. Set resources.requests.memory
[CRITICAL] Container Image Tag
· myimage -> Image with latest tag
Using a fixed tag is recommended to avoid accidental upgrades
[CRITICAL] Container Security Context ReadOnlyRootFilesystem
· myimage -> Container has no configured security context
Set securityContext to run the container in a more secure context.
[CRITICAL] Container Ephemeral Storage Request and Limit
· myimage -> Ephemeral Storage limit is not set
Resource limits are recommended to avoid resource DDOS. Set
resources.limits.ephemeral-storage
[CRITICAL] Pod NetworkPolicy
· The pod does not have a matching NetworkPolicy
Create a NetworkPolicy that targets this pod to control who/what
can communicate with this pod. Note, this feature needs to be
supported by the CNI implementation used in the Kubernetes cluster
to have an effect.
[CRITICAL] Container Security Context User Group ID
· myimage -> Container has no configured security context
Set securityContext to run the container in a more secure context.

Let’s explain the command:

docker run -v %cd%:/project zegl/kube-score:latest score mydeployment.yaml

We found the docker command in the direct link : https://github.com/zegl/kube-score#example-with-docker

[GitHub - zegl/kube-score: Kubernetes object analysis with recommendations for improved reliability…
kube-score is a tool that performs static code analysis of your Kubernetes object definitions. The output is a list of…github.com](https://github.com/zegl/kube-score#example-with-docker "github.com/zegl/kube-score#example-with-doc..")

It is said to run for example:

docker run -v $(pwd):/project zegl/kube-score:latest score my-app/*.yaml

Well $(pwd) does work on Linux/Mac or Powershell, if you use Windows ms-dos we must use %cd% instead.

We can see we need a volume to bind to the workspace /project inside the container so we keep this directory so kube-score can find our YAML file.

We can check this point with the docker image layers where we can see the WORKDIR is indeed: /project.

I think the documentation should highlight better this point. I tried in vain to use -v %cd%:/usr/tmp and it said:

Failed to score files: open mydeployment.yaml: no such file or directory

Remember to have a look in the docker hub and check the docker image layers before, it is very useful!

Then we just pass the argument score to tell kube-score to give a score to our YAML file.

We can see our YAML file is not valid with many critical points to solve.

  • We should first put request/limit to CPU, Memory.
  • Then we need to put a tag to our docker image and avoid the “latest” default tag.
  • a Container security Context must be set

We should read the documentation of Kube-Score to have further information.

Below we can find the list of checks

[kube-score/README_CHECKS.md at master · zegl/kube-score
Kubernetes object analysis with recommendations for improved reliability and security - kube-score/README_CHECKS.md at…github.com](https://github.com/zegl/kube-score/blob/master/README_CHECKS.md "github.com/zegl/kube-score/blob/master/READ..")

Or we can run :

λ docker run zegl/kube-score:latest list
ingress-targets-service,Ingress,Makes sure that the Ingress targets a Service,default
cronjob-has-deadline,CronJob,Makes sure that all CronJobs has a configured deadline,default
container-resources,Pod,Makes sure that all pods have resource limits and requests set. The --ignore-container-cpu-limit flag can be used to disable the requirement of having a CPU limit,default
container-resource-requests-equal-limits,Pod,Makes sure that all pods have the same requests as limits on resources set.,optional
container-cpu-requests-equal-limits,Pod,Makes sure that all pods have the same CPU requests as limits set.,optional
container-memory-requests-equal-limits,Pod,Makes sure that all pods have the same memory requests as limits set.,optional
container-image-tag,Pod,Makes sure that a explicit non-latest tag is used,default
container-image-pull-policy,Pod,Makes sure that the pullPolicy is set to Always. This makes sure that imagePullSecrets are always validated.,default
container-ephemeral-storage-request-and-limit,Pod,Makes sure all pods have ephemeral-storage requests and limits set,default
container-ephemeral-storage-request-equals-limit,Pod,Make sure all pods have matching ephemeral-storage requests and limits,optional
container-ports-check,Pod,Container Ports Checks,optional
statefulset-has-poddisruptionbudget,StatefulSet,Makes sure that all StatefulSets are targeted by a PDB,default
deployment-has-poddisruptionbudget,Deployment,Makes sure that all Deployments are targeted by a PDB,default
poddisruptionbudget-has-policy,PodDisruptionBudget,Makes sure that PodDisruptionBudgets specify minAvailable or maxUnavailable,default
pod-networkpolicy,Pod,Makes sure that all Pods are targeted by a NetworkPolicy,default
networkpolicy-targets-pod,NetworkPolicy,Makes sure that all NetworkPolicies targets at least one Pod,default
pod-probes,Pod,Makes sure that all Pods have safe probe configurations,default
container-security-context-user-group-id,Pod,Makes sure that all pods have a security context with valid UID and GID set ,default
container-security-context-privileged,Pod,Makes sure that all pods have a unprivileged security context set,default
container-security-context-readonlyrootfilesystem,Pod,Makes sure that all pods have a security context with read only filesystem set,default
container-seccomp-profile,Pod,Makes sure that all pods have at a seccomp policy configured.,optional
service-targets-pod,Service,Makes sure that all Services targets a Pod,default
service-type,Service,Makes sure that the Service type is not NodePort,default
stable-version,all,Checks if the object is using a deprecated apiVersion,default
deployment-has-host-podantiaffinity,Deployment,Makes sure that a podAntiAffinity has been set that prevents multiple pods from being scheduled on the same node. kubernetes.io/docs/concepts/configuration/a..
statefulset-has-host-podantiaffinity,StatefulSet,Makes sure that a podAntiAffinity has been set that prevents multiple pods from being scheduled on the same node. kubernetes.io/docs/concepts/configuration/a.. deployment-targeted-by-hpa-does-not-have-replicas-configured,Deployment,Makes sure that Deployments using a HorizontalPodAutoscaler doesn't have a statically configured replica count set,default
statefulset-has-servicename,StatefulSet,Makes sure that StatefulSets have an existing headless serviceName.,default
deployment-pod-selector-labels-match-template-metadata-labels,Deployment,Ensure the StatefulSet selector labels match the template metadata labels.,default
statefulset-pod-selector-labels-match-template-metadata-labels,StatefulSet,Ensure the StatefulSet selector labels match the template metadata labels.,default
label-values,all,Validates label values,default
horizontalpodautoscaler-has-target,HorizontalPodAutoscaler,Makes sure that the HPA targets a valid object,default

Conclusion

We can use this kube-score with docker within a CI/CD tool before our workload is deployed on our cluster for example. As long we have critical points to solve, the YAML should not be applied to our cluster!