Using Passwords and Config in Kubernetes Pods — Part I (Environment Variables)

Sidhartha Mani
Koki
Published in
4 min readDec 28, 2017

This is Part 1 of a 2 part blog series on using passwords and Config in Kubernetes Pods. Part 2 is available here

Kubernetes provides a declarative mechanism for specifying Config and Secret information. The declarative interface for storing Config Data is ConfigMap. Similarly, Secret is the declarative interface for storing Secret Data. Both of these interfaces can hold arbitrary, unstructured information.

Passwords should be stored as a secret

Secret should be used to store sensitive information such as passwords, access keys, API Tokens etc.

ConfigMap should be used to store configuration information such as endpoints, application properties, command line flags etc.

Kubernetes provides all the essential buttons and knobs to configure your application

Config and Secrets

There are two mechanisms to create Secret and ConfigMap resources. The first is the kubectl create command. The second mechanism is discussed in the next section.

kubectl create can read the contents of a file(s) and store the value in a ConfigMap or Secret resource. Here’s an example showing its operation

# ConfigMap
$ kubectl create configmap config_data --from-file=config_data.txt
# Secret
$ kubectl create secret secret_data --from-file=secret_data.txt

This command can also create ConfigMap and Secret from literals, as shown below

# ConfigMap
$ kubectl create configmap config_data --from-literal=key=val
# Secret
$ kubectl create secret secret_data --from-literal=key=val

An experienced DevOps or IT engineer would’ve already noticed some issues with this approach.

  • Repeatability — The same command can potentially lead to different behaviors based on the contents of the file
  • Debugging — A person debugging issues has an extra checkpoint to ensure that the resource created has the right data — i.e. the right file was used to create the resource

These issues are just the surface of the potential issues caused by the Imperative style of storing configuration and sensitive information.

Declarative Config and Secrets

The second mechanism is the Declarative style of creating Secret and ConfigMap resources. In this style of expression, we declare the desired state of the system rather than a series of steps to follow.

Note: I’ve used the cleaner and simpler Koki Short syntax to declare these resources.

config_map:
data:
db_name=colors_db
table_name=purple
name: config_data
version: v1

Similarly, Secret can be declared by creating a secret resource

secret:
data:
username: my-username
password: my-password
name: secret_data
version: v1

The concern of Repeatability can be safely put to rest with this style since the resource is declared. The data in the resource are not a result of a series of steps or the transient state of a file.

Using the Declarative style, it is easier to reason about accuracy of data and correctness of running workloads in the system.

Using Config and Secrets in a Pod

Once the Secret and/or ConfigMap have been created, they can be consumed by a Pod in the same namespace.

Pods can consume the Secret or the ConfigMap as Environment Variables or as a Volume mounted inside one of its containers. In order to consume as an Environment Variable, here’s the syntax

pod:
labels:
app: nginx
name: nginx
namespace: default
version: v1
containers:
- name: nginx
image: nginx
env:
- key: NGINX_
from: config:config_data

The above syntax declares that the container should have environment variables with the prefix NGINX_, whose values are the data in the ConfigMap named config_data.

That is, the container can expect to use NGINX_DB_NAME and NGINX_TABLE_NAME for its operations. The above keys and their corresponding values are derived from the ConfigMap declared previously.

If only a certain field of the config map is desired, then it can be selected as shown below

pod:
labels:
app: nginx
name: nginx
namespace: default
version: v1
containers:
- name: nginx
image: nginx
env:
- key: NGINX_DB_NAME
from: config:config_data:db_name

The above syntax declares that the container should have an environment variable called NGINX_DB_NAME, whose value is obtained from the key db_name of the ConfigMap named config_data.

A similar operation is possible for obtaining values from Secret resources as well. More information on the syntax is available here — https://docs.koki.io/short/resources/pod/#environment-overview

Short Syntax

The syntax used here is called the Short Syntax, and it is designed to be a more readable form of YAML than the machine oriented Kubernetes API spec that exists today. It provides the following advantages for its users

  • Tunes out the noise from the manifests and makes them easier to read and write
  • Lets you get a lot more done, a lot more quickly
  • Completely translates from Kubernetes to Short and back Kubernetes without losing any information
  • Completely free
  • Comes with a Chrome Plugin
  • Completely Open Source

Go try out Koki Short. Share your feedback here, and stay tuned for more Kubernetes deep dives!

--

--