All Blog Posts

How to K8s: Kubernetes Secrets Made Simple

Kubernetes secrets, etcd diagram
Looking for more of our How to K8s series? Join us on September 23rd at 12 PM EDT/9 AM PDT for our How to K8s: Shipping macOS Logs in Kubernetes.  

In the upcoming webinar, MacStadium's iOS DevOps Coach, John Cabaniss, will walk us through, step-by-step how to get and ship basic macOS build metrics, then log and ship platform-level metrics in Kubernetes using the Orka system, all with fluentD. Reserve your spot now!

Whether in production or a testing environment, sensitive information – such as SSH keys or database credentials – needs to be kept private and secure. In Kubernetes, this need is satisfied by an object called a Secret.

What is a Secret, exactly?

Secrets are Kubernetes objects that store small amounts of private information. They are created in much the same way as Pods. Although Secrets live out a very different life than that of a Pod, they are similar in the sense that they are also fundamental Kubernetes objects that can be created and torn down much like a Pod can be.

Kubernetes Secrets diagram, etcd

Secrets live out their lives in etcd, the central datastore for the entire Kubernetes system. This is the same central location where declarative definitions for Kubernetes Deployments live.

This centralized storage approach allows users to create one Secret that can then be consumed by any number of Pods, whether those Pods are identical copies of one another (as would be the case with a Deployment or ReplicaSet) or not. It is worth noting that you can create any number of Secrets you like, but none can exceed 1MB in size.

How do you make a Secret?

Secrets can either be defined via the kubectl CLI or manually via a YAML file.

If going the manual route, you’ll first need to encode the values that will be passed to the Secret:

$ echo -n <value_to_be_encoded> | base64

For example, we can encode the word “password” like so:

$ echo -n password | base64
cGFzc3dvcmQ=

Then create a YAML file that defines a Secret. For example:

# example_secret.yml

apiVersion: v1
kind: Secret
metadata:
 name: mysecret
type: Opaque
data:
 username: YWRtaW4=
 password: MWYyZDFlMmU2N2Rm

Notice that both our username and password values have been encoded.

And, finally, apply the Secret’s definition:

kubectl apply -f example_secret.yml

How are Secrets used?

The information Secrets house can be accessed by the code that needs it in two ways. It can either be mounted onto a Pod in the form of a Volume or set as an environment variable within the Pod.

When mounted as a Volume, the key-value pairs are expressed as files in a directory. So, if your secret information was something like:

db_creds : "some really long complex string"

Once mounted onto the Pod as a Volume at “/etc/db-creds” for example, a file named “db_creds” would be in the db-creds directory, and within that file you would find:

# db_creds
some really long complex string

To mount the Secret onto the Pod as a Volume, we need to define a Volume with a secretName that corresponds to our above Secret definition. We also need to define the volumeMount where the Volume will live in the Pod.

apiVersion: v1
kind: Pod
metadata:
 name: pod-with-secret
 labels:
   name: pod-with-secret
spec:
 volumes:
 - name: db-creds
   secret:
     secretName: mysecret
 containers:
 - name: chef-server
   image: jdvincent/chef-server
   volumeMounts:
   - name: db-creds
     readOnly: true
     mountPath: "/etc/db-creds"

The mountPath in the Pod template is the path to the directory that will house your decoded information as one or more files named for a given key and containing the associated value. If we exec into the running Pod we would see the following:

# cd /etc/db-creds
# ls
username password
# cat password
MacStadium

Something to note: The key-value pairs can also be introduced into the Pods as environment variables with only a slight change to the definition statement.

TL;DR

Kubernetes Secrets are a fundamental API object that stores small amounts of encrypted data, such as would be used for DB passkeys or SSH keys. This information is stored in etcd, the central datastore for Kubernetes. As such, a single Secret can be consumed by any number of Pods and, by extension, containers running therein.

You May Also Like

Was this article helpful?

Vote Submitted
Oops! Something went wrong while submitting the form.
Vote Submitted
Oops! Something went wrong while submitting the form.
Return to Blog Home