Wednesday, 10 February 2021

Argh, Kubernetes and YAML hell

I was trying to create a Kubernetes (K8s) Secret, containing existing Docker credentials, as per this: -

Create a Secret based on existing Docker credentials

and kept hitting syntax errors with the YAML.

For reference, in this scenario, we've already logged into a container registry, such as IBM Container Registry or Docker Hub, and want to grab the credentials that Docker itself "caches" in ~/.docker/config.json

Wait, what ? You didn't know that Docker helpfully does that ? Another good reason to NOT leave yourself logged into a container registry when you step away from your box ....

Anyhow, as per the above linked documentation, the trick is to encapsulate the content of that file, encoded using Base64, into a YAML file that looks something like this: -

---
apiVersion: v1
kind: Secret
data:
  .dockerconfigjson:
    <HERE'S THE BASE64 ENCODED STUFF>
metadata:
  name: my_secret
type: kubernetes.io/dockerconfigjson

The trick is to get the Base64 encoded stuff just right ....

I was doing this: -

cat ~/.docker/config.json | base64 

which resulted in: -

ewoJImF1dGhzIjoge30sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2Vy
LUNsaWVudC8xOS4wMy42IChsaW51eCkiCgl9Cn0=

I kept seeing exceptions such as: -

error: error parsing secret.yaml: error converting YAML to JSON: yaml: line 7: could not find expected ':'

and: -

Error from server (BadRequest): error when creating "secret.yaml": Secret in version "v1" cannot be handled as a Secret: v1.Secret.ObjectMeta: v1.ObjectMeta.TypeMeta: Kind: Data: decode base64: illegal base64 data at input byte 76, error found in #10 byte of ...|BLAHBLAH=="},"kind":"|..., bigger context ...|BLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAHBLAH=="},"kind":"Secret","metadata":{"annotations":{"kube|...

when I tried to apply the YAML: -

kubectl apply -f secret.yaml

And then I re-read the documentation, for the 11th time, and saw: -

base64 encode the docker file and paste that string, unbroken as the value for field data[".dockerconfigjson"]

Can you see what I was doing wrong ?

Yep, I wasn't "telling" the Base64 encoded to produce an unbroken ( and, more importantly, unwrapped ) string.

This time I did it right: -

cat ~/.docker/config.json | base64 --wrap=0

resulting in this: -

ewoJImF1dGhzIjoge30sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy42IChsaW51eCkiCgl9Cn0=root@379cd9170839:~# 

Having discarded the user@hostname stuff, I was left with this: -

ewoJImF1dGhzIjoge30sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy42IChsaW51eCkiCgl9Cn0=

I updated my YAML: -

---
apiVersion: v1
kind: Secret
data:
  .dockerconfigjson: ewoJImF1dGhzIjoge30sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy42IChsaW51eCkiCgl9Cn0=
metadata:
  name: my_secret
type: kubernetes.io/dockerconfigjson

and applied it: -

kubectl apply -f secret.yaml 

secret/armadamultiarch created

and we're off to the races!

No comments:

Note to self - use kubectl to query images in a pod or deployment

In both cases, we use JSON ... For a deployment, we can do this: - kubectl get deployment foobar --namespace snafu --output jsonpath="{...