Managing a secret on kubernetes

3 min read | by Jordi Prats

Most of the services we will be deploying on kubernetes are going to rely on having access to secrets to retrieve or push data to another service: Let's check how to work with the secrets on kubernetes

$ kubectl create secret Create a secret using specified subcommand. Available Commands: docker-registry Create a secret for use with a Docker registry generic Create a secret from a local file, directory or literal value tls Create a TLS secret Usage: kubectl create secret [flags] [options] Use "kubectl <command> --help" for more information about a given command. Use "kubectl options" for a list of global command-line options (applies to all commands). 

On kubernetes there's an object called "secret" that we can use to store secrets. We can, of course, create a secret using a yaml file but for demo purposes I think it makes more sense to create it imperatively using kubectl. We can push data to the secret using --from-literal (password from the command line) or --from-file (password is stored on a file). In any case the format would be --from-file=[key=]source/--from-literal=[key=]source

For exemple, to create a secret with username jordi.prats and password not_so_secret the command would be:

$ kubectl create secret generic democredentials \ --from-literal=username=jordi.prats \ --from-literal=password='not_so_secret' 

Just to make it a little safer we could use a file to store the data so this way the secret won't be in the command history

$ kubectl create secret generic democredentials \ --from-file=username=path/to/username_file --from-file=password=path/to/password_file 

After creating the secret we can check it:

$ kubectl get secret democredentials NAME TYPE DATA AGE democredentials Opaque 2 69s 

With describe we won't be able to actually see the secret:

$ kubectl describe secret democredentials Name: democredentials Namespace: kube-system Labels: <none> Annotations: <none> Type: Opaque Data ==== password: 13 bytes username: 11 bytes 

On the other hand, if we retrieve the secret as a yaml we will be able to see the secret:

$ kubectl get secret democredentials -o yaml apiVersion: v1 data: password: bm90X3NvX3NlY3JldA== username: am9yZGkucHJhdHM= kind: Secret metadata: creationTimestamp: "2020-12-23T06:57:45Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:password: {} f:username: {} f:type: {} manager: kubectl-create operation: Update time: "2020-12-23T06:57:45Z" name: democredentials namespace: kube-system resourceVersion: "4576550" selfLink: /api/v1/namespaces/kube-system/secrets/democredentials uid: ba87853f-16c8-426a-b840-945bf40a6f0e type: Opaque 

On the data section of the yaml we can see that there are the fields we added to the secret (username/password) with it's value encoded using base64, we can retrieve the secrets by decoding these strings:

$ echo 'am9yZGkucHJhdHM=' | base64 -d jordi.prats $ echo 'bm90X3NvX3NlY3JldA==' | base64 -d not_so_secret 

We can also use the jsonpath to retrieve just the encoded string so we can use it on scripts more easily, for example:

$ kubectl get secret democredentials -o jsonpath="{.data.password}" bm90X3NvX3NlY3JldA== $ kubectl get secret democredentials -o jsonpath="{.data.password}" | base64 -d not_so_secret 

Posted on 23/12/2020