I wanted to call this article “Gleaming the Kube” but someone already did that.
Kubernetes is a relatively complex system, and I typically deal with OpenStack so that is saying something. With any new and complex (and valuable) system it’s easy to use that system to build, shall we say, services with less than desirable security settings. And thus we have people building tools that help to ensure systems and definitions are as secure as is reasonably possible. Enter kubeaudit.
Kubeaudit is a helpful tool from the folks at Shopify. A Canadian company by the way!
kubeaudit is a command line tool to audit Kubernetes clusters for various different security concerns: run the container as a non-root user, use a read only root filesystem, drop scary capabilities, don’t add new ones, don’t run privileged, … You get the gist of it and more on that later. Just know: kubeaudit makes sure you deploy secure containers!
Because go compiles into a nice clean binary, it’s easy to install kubeaudit.
wget -P /tmp https://github.com/Shopify/kubeaudit/releases/download/v0.5.3/kubeaudit_0.5.3_linux_amd64.tar.gz mkdir ~/bin # if you don't have one export PATH=$PATH:~/bin # only untar kubeaudit, there is a licence and readme file in there as well which we don't need tar zxvf /tmp/kubeaudit_0.5.3_linux_amd64.tar.gz -C ~/bin kubeaudit
$ kubeaudit version INFO Kubeaudit version BuildDate="2019-03-29T15:36:37Z" Commit=b19f6509d92abc22a8cf2789a98a740af20831e6 Version=0.5.3 INFO Not running inside cluster, using local config INFO Kubernetes server version Major=1 Minor=13 Platform=linux/amd64
Note that this will check the Kubernetes version as well through reading the
Let’s deploy an nginx container.
NOTE: I alias kubectl to k
$ k run nginx --image=nginxinc/nginx-unprivileged --port=8080
It’s up and running.
$ k get all NAME READY STATUS RESTARTS AGE pod/nginx-6c6d45d55d-ckhzw 1/1 Running 0 51s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 51s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-6c6d45d55d 1 1 1 51s
Now audit it with
kubeaudit, but we’ll only check for nonroot.
$ kubeaudit nonroot -n nginx-unpriv INFO Not running inside cluster, using local config ERRO RunAsNonRoot is not set in ContainerSecurityContext, which results in root user being allowed! Container=nginx KubeType=deployment Name=nginx Namespace=nginx-unpriv ERRO RunAsNonRoot is not set in ContainerSecurityContext, which results in root user being allowed! Container=nginx KubeType=pod Name=nginx-6c6d45d55d-ckhzw Namespace=nginx-unpriv
Ok let’s fix that by patching the deployment.
Here is the patch:
$ cat nginx-unpriv-runasnonroot.yml spec: template: spec: containers: - image: nginxinc/nginx-unprivileged name: nginx securityContext: runAsNonRoot: true securityContext: runAsNonRoot: true
Apply the patch.
$ k patch deployment nginx --patch "$(cat nginx-unpriv-runasnonroot.yml)" deployment.extensions/nginx patched
A new pod should be created.
~$ k get all NAME READY STATUS RESTARTS AGE pod/nginx-686cc9b75c-jfc8t 1/1 Running 0 24s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/nginx 1/1 1 1 3m50s NAME DESIRED CURRENT READY AGE replicaset.apps/nginx-686cc9b75c 1 1 1 24s replicaset.apps/nginx-6c6d45d55d 0 0 0 3m50s
And now to run audit again:
$ kubeaudit nonroot -n nginx-unpriv INFO Not running inside cluster, using local config
That’s it. A simple example of using