The Secret to Kubernetes Secrets

I made an innocent comment on Twitter last week that led to WAY more feedback than I was expecting. The Kubernetes community showed me there are a lot of options when creating Kubernetes Secrets. I made the statement:

Every single time I have to create a secret, I have to read the docs. I should have this figured out by now.”

Years ago, a colleague asked Albert Einstein if he knew his phone number. The rebuttal was short and rather Einsteinian, “Never memorize something that you can look up.” So when a reminder of how “Memorization is an anti-pattern.” came up during the conversation about Kubernetes Secrets, I was quite relieved.

Sign up for DevOps'ish!

DevOps'ish is a weekly newsletter covering DevOps, Cloud Native, Open Source, and the 'ish between.

The many ways you can peel the Kubernetes Secrets onion seems to grow daily. There are inline secrets, secrets as YAML files, secrets with base64 encoded values, and secrets through third-party providers (like Hashicorp Vault). When reading the Best Practices for Kubernetes Secrets, there is a cautionary tale of how things can go wrong.

Several suggestions on how folks managed Kubernetes Secrets themselves rolled in via Twitter. One tip from Jessica Deen suggested using zsh-autosuggestions. This is a very viable option and if you’re using ZSH I’d highly recommend it.

My buddy Todd Edwards suggested using VSCode snippets. That is a viable option for most anyone with an IDE. Brian Liles response about using Shell functions piqued my interest for a different reason (he might have something fancy up his sleeve too). But, this thorough response reads more like a HOWTO and less like a Tweet:

Peter Benjamin

One pertinent thing that did come up in discussion was stringData in Kubernetes Secrets. Per the documentation, a Secret has:

“Two maps: data and stringData. The data field is used to store arbitrary data, encoded using base64. The stringData field is provided for convenience, and allows you to provide secret data as unencoded strings.”

This means that the now infamous echo -n "[REDACTED]" | base64 is not needed when stringData is used. This eliminates one command when creating a Kubernetes Secret. I’ll be using stringData by default in the future. I think stringData is relatively new; please don’t feel bad for not knowing about it sooner. With this in mind, a YAML file built for use with kubectl apply would like this:

---
apiVersion: v1
kind: Secret
metadata:
  name: my-special-secret
type: Opaque
stringData:
  key: [REDACTED]

In the past, I would keep Secret files in 1Password, Vault, or some other secure storage mechanism. The idea was, I wouldn’t have to look at the Kubernetes Secret docs and do it all again. Reducing errors was the idea here. But, no one needs to make a file because they think that’s the only way. For simple Secrets, the --from-literal flag allows for a key pair after to create a full fledge Secret:

kubectl create secret generic my-special-secret \
    --from-literal=key0=barf \
    --from-literal=key1=frab

When in doubt, run kubectl describe secret my-special-secret to verify the secret is at the very least there and has two keys.

Name:         my-special-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
key0:  4 bytes
key1:  4 bytes

As far Kubernetes Secrets go, there are a few ways to create them. But, I’m going to try to stick to a one-liner or YAML files stored securely and make use of stringData for specifying keys and values. Ditching echo -n "[REDACTED]" | base64 reduces a source of potential confusion and an entire step. This lowers Kubernetes’ barrier to entry a smidge, so I am all for that.


See also