Quick Read: How to Set a Default Container in a Kubernetes Manifest

Another day, another minor inconvenience at work that I should have fixed ages ago. This week I finally took a minute to fix a Kubernetes annoyance that I was dealing with for ages: how to specify a default container when using a multi-container deployment manifest.

The Problem

When using kubectl, a pod's default container for commands like kubectl logs or kubectl exec, if not specified, is simply whichever container is defined first in its manifest file.

Yes, I am aware that the kubectl command accepts a -c container-name argument, but I always forget to use it the first time, and, more importantly, it means additional keystrokes every time I use kubectl.

via GIPHY

The manifest file that I work with most often (and that I'll use as an example in this post) defines two containers: a static-assets container which is an NGINX proxy, and a bouncer container which is a Python web server. I've never needed to exec into or fetch logs from the static-assets container, and yet that's always where I end up first because it's defined first in my manifest file.

The Fix

Sure, I could simply rearrange the containers so that bouncer appears first in the manifest, but that's not a great long-term solution as someone else could end up rearranging the manifest or adding a new container while unaware that container order matters.

The proper solution is to use an annotation.

More specifically, there is a kubectl.kubernetes.io/default-container annotation that can be configured. From the documentation:

The value of the annotation is the container name that is default for this Pod. For example, kubectl logs or kubectl exec without -c or --container flag will use this default container.

In this case, the following annotation is needed:

kubectl.kubernetes.io/default-container: "bouncer"

To better understand where this annotation should be added, here is a simplified version of the file with the new annotation:

apiVersion: apps/v1
kind: Deployment
metadata: ...
spec: ...
    selector: ...
    strategy: ...
    template:
    	metadata:
            annotations:
            	kubectl.kubernetes.io/default-container: "bouncer"
        spec:
            containers: ...
            - name: static-assets
            	...
            - name: bouncer
            	...
            volumes: ...

Now when I exec into my pod, I end up in the bouncer container even though it's listed second in the manifest. Success!

Wrapping Up

It was surprising how difficult it was to find the documentation on this annotation, which is why I ended up writing this post. Thanks to this manifest update I'm able to work with my Kubernetes pod more quickly and with fewer keystrokes!

via GIPHY

As always, thanks for reading.