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.
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:
I do:— peter.benjamin.svc.cluster.local (@petermbenjamin) May 24, 2019
- kubectl create secret --help (ah, I need `generic`)
- kubectl create secret generic --help (ah, i need to give it a name and some add'l flags)
- kubectl create secret generic test --from-literal=username=foo --from-literal=password=bar --dry-run -o yaml > secret.yaml
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.