Kubernetes – Securing sensitive application data (secrets)

Sometimes, our application needs to hold sensitive information. This can be credentials or tokens to log in to a database or service. Storing this sensitive information in the image itself is something to be avoided. Here, Kubernetes provides us with a solution in the construct of secrets.

Secrets give us a way to store sensitive information without including plaintext versions in our resource definition files. Secrets can be mounted to the pods that need them and then accessed within the pod as files with the secret values as content. Alternatively, you can also expose the secrets via environment variables.

Given that Kubernetes still relies on plaintext etcd storage, you may want to explore integration with more mature secrets vaults, such as Vault from Hashicorp. There is even a GitHub project for integration: https://github.com/Boostport/kubernetes-vault.

We can easily create a secret either with YAML or on the command line. Secrets do need to be base-64 encoded, but if we use the kubectl command line, this encoding is done for us. 

Let’s start with the following secret:

$ kubectl create secret generic secret-phrases --from-literal=quiet-phrase="Shh! Dont' tell"

We can then check for the secret with this command:  

$ kubectl get secrets

Now that we have successfully created the secret, let’s make a pod that can use the secret. Secrets are consumed in pods by way of attached volumes. In the following secret-pod.yaml file, you’ll notice that we use volumeMount to mount the secret to a folder in our container:

apiVersion: v1
kind: Pod
  name: secret-pod
  - name: secret-pod
    image: jonbaier/node-express-info:latest
    - containerPort: 80
      name: web
      - name: secret-volume
        mountPath: /etc/secret-phrases
  - name: secret-volume
      secretName: secret-phrases

Create this pod with kubectl create -f secret-pod.yaml. Once created, we can get a bash shell in the pod with kubectl exec and then change directories to the /etc/secret-phrases folder that we set up in the pod definition. Listing this directory reveals a single file with the name of the secret that we created earlier:

$ kubectl exec -it secret-pod bash
$ cd /etc/secret-phrases
$ ls

If we then display its contents, we should see the phrase we encoded previously, Shh! Dont' tell:

$ cat quiet-phrase

Typically, this would be used for a username and password to a database or service, or any sensitive credentials and configuration data.

Bear in mind that secrets are still in their early stages, but they are a vital component for production operations. There are several improvements being planned for future releases. At the moment, secrets are still stored in plaintext in the etcd server. However, the secrets construct does allow us to control which pods can access it, and it stores the information on the tmpfs, but does not store it at rest for each pod. You can limit users with access to etcd and perform additional wipe procedures when you decommission servers, but you’ll likely want more protection in place for a production-ready system.

Comments are closed.