Using Passwords and Config in Kubernetes Pods — Part I (Environment Variables)
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.
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.
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!