Kubernetes is a Database
Tags: kubernetes, devops
Published: 2023-11-11 19:04:14

## The Problem
A colleague of mine who is leading an Agile DevOps team using the OpenShift platform, was in a discussion with one of the developers. 
They were looking for a solution to determine which container images and their versions were part of a release of the application they were developing. They decided to modify the Tekton build pipelines so it would tag the custom build container images with the release in which they were used.

I asked the team lead about the solution they had come up with and also told him that I considered it a bad solution for the following reasons:
* the adaptation of the Tekton pipelines would take time
* the process of setting the tags on the images would involve human interaction
* how would you tag images that were used in different releases in different environments
* how would you know if an image was actually deployed and used in a release

Their solution turned out not to be sufficient.

## A better solution

There is a much easier way to list the actually deployed container images in a release. This is because Kubernetes is a databases, and much more of course.

Kubernetes uses an interesting approach to deploy the resources that make up applications. When you instruct Kubernetes to create e.g. a Deployment with **kubectl apply**, then in essence you post the yaml files to the kube-api-server which after some checks saves your definition in a database, **etcd**. Then a process of reconciliation starts to realize your desired state. The result of this process is also saved in the **etcd** database, as a status field on each resource.

The key thing is that this database can be queried via the api, using the **kubectl** tool. When you also know that all containers run in Pods, then getting an overview of the container images and their version can be done with a single kubectl get pods command with some additional parameters and a Go text template.

Kubectl allows you to specify the output with the --output parameter. Options include yaml and json, but also a go-template, as output. Kubectl will pass the result of your query as an array of Pod objects to the [Go text template](https://pkg.go.dev/text/template) processor, that uses your template to produce a list of, in our case, the images that are used in our application.

## Example

First you need to know the structure of the response that your template needs to process. Start with the full list of pods your namespace in yaml format: kubectl get pods -o yaml. This gives you this output.

```
$ kubectl get pods -A -o yanl
apiVersion: v1
items:
- apiVersion: v1
  kind: Pod
  metadata:
    name: pod-1
  spec:
    containers:
    - name: container-1
      image: image-name:tag
# Lines ommitted for brevity...
```

Create a simple Go template in a file _pod-containers.tpl_. 

```
{{- /* Loop through all Pods */ -}}
{{- range .items -}}
{{- /* Now . is a Pod */ -}}
pod name: {{ .metadata.name }}
{{ range .spec.containers -}}
{{- /* Now . is a container */ -}}
container name: {{ .name }}
container image: {{ .image }}
{{ end -}}

{{ range .spec.initContainers -}}
{{- /* Now . is an initContainer */ -}}
init container name: {{ .name }}
init container image: {{ .image }}
{{ end }}
{{ end -}}
```

Use it with kubectl.

```
$ get pods \
    --all-namespaces \
    --output go-template-file \
    --template ./pod-containers.tpl
```

The output gives you the pods, the containers and the container image.

```
pod name: coredns-5d78c9869d-tnzhc
container name: coredns
container image: registry.k8s.io/coredns/coredns:v1.10.1

pod name: coredns-5d78c9869d-xlkxc
container name: coredns
container image: registry.k8s.io/coredns/coredns:v1.10.1

pod name: etcd-kind-control-plane
container name: etcd
container image: registry.k8s.io/etcd:3.5.7-0

# Lines delete for brevity...
```

## Conclusion

Kubernetes exposes its information via a service API and because the kubectl tool supports Go templates, you can get all information about your installed components and resources in the format that you need. For the given problem we started with a simple template and we got a nice overview of all the images and their versions running in our environment. We ended up developing different templates that produced HTML reports and Excel compatible CSV files.

Of course Kubernetes is not a Database, it is much more, but it uses a database to keep track of its resources and their status. Realizing this helps you to rethink on how to access the information about your application components running on this great platform. Just ask Kubernetes.