Table of contents
No headings in the article.
Introduction : Environmental variables play an important role in the configuration of applications running in a Kubernetes (k8s) cluster. These variables store information such as API keys, passwords, and other configuration data that are used by the containers in a Pod to connect to external resources and interact with each other.
In this article, we will explore the different ways to configure environmental variables in Kubernetes, including how to declare variables in the Pod definition file, using ConfigMaps and Secrets. Understanding these methods will help you choose the best approach for your specific requirements and enable you to better manage configuration settings for your applications running in a K8s cluster.
Prerequisites : Before reading this article, you should be familiar with
Containerization and Docker.
Kubernetes architecture and its components (check out this article i wrote on K8s).
command-line interface (CLI) and YAML syntax.
Also i will mostly refer to Kubernetes as k8s.
Let’s Go !
What are environmental variables ?
In Kubernetes, environmental variables refer to key-value pairs that are supplied to containers during runtime. They serve as labels or tags for information, making it easy to locate and utilize when needed.
For example, imagine you are going on a road trip and need to plan your route. You write down the name of each city you want to visit and attach a label or tag called “destination” to each one. Now, you have a list of destinations that you can easily reference and update as needed.
Similarly, in software development, environmental variables can be utilized to store crucial information like database credentials, API keys, or configuration settings, and labeled or tagged for easy retrieval. By doing this, the application can reference and utilize this information without having to embed it directly into the code.
So, in simple terms, an environmental variable is a label or tag that you attach to a piece of information to make it easily accessible and reusable within your application.
Why do we need environmental variables ?
Environmental variables play a crucial role in modern software development, as they provide a way to store and access configuration information for your applications. In the context of K8s, environmental variables are used to configure the behavior of containers and applications running within the cluster. By using environment variables, you can decouple configuration information from the application code, making it easier to manage and maintain the application. Furthermore, environmental variables provide a convenient way to configure applications for different environments, such as development, staging and production.
For example, you can use environment variables to configure database credentials, API keys, and other sensitive information in a secure and controlled manner. Overall, environmental variables are a key tool for building robust and scalable applications on K8s.
There are several ways to configure environmental variables in K8s, such as :
Declaring variables in the Pod definition file using name and value pair
Declaring variables in a Pod definition file in K8s is a way to pass data to your containerized applications at runtime. This data can include environment variables, command-line arguments, or configuration files. Declaring variables in the Pod definition file is a flexible and straightforward method for configuring your applications.
In the Pod definition file, you can use the
env
field to define environment variables that will be set within the container. For exampleapiVersion: v1 kind: Pod metadata: name: my-pod spec: containers: - name: my-container image: busybox - env: - name: DATABASE_HOST value: postgres - name: DATABASE_NAME value: product - name: DATABASE_PASSWORD value: pr0dr0b0t - name: DATABASE_USER value: product_robot - name: DATABASE_PORT value: "5432"
Declaring variables in the Pod definition file is a simple and effective way to configure your applications in K8s and the environmental variables can be declared in the Pod definition file as a list of key-value pairs and passed to the containers running in the Pod.
Using ConfigMap
ConfigMap is a K8s object that is used to store configuration data for applications as key-value pairs. It allows you to decouple configuration data from the application image and store it in a centralized location. You can manage the configuration data in ConfigMap using kubectl, or you can create and update ConfigMap objects using manifests. ConfigMap can be used in multiple ways in K8s, such as setting environment variables, providing configuration files, or passing command-line arguments to containers.
With ConfigMap, you can configure and update your application without having to rebuild the image, making it a flexible and scalable way to manage configuration in K8s.
Here is an example of using ConfigMap in K8s with YAML manifest:
apiVersion: v1 kind: ConfigMap metadata: name: app-config data: APP_COLOR: blue APP_MODE: prod
This ConfigMap creates two key-value pairs: APP_COLOR and APP_MODE
To use this ConfigMap in a Pod definition :
apiVersion: v1 kind: Pod metadata: name: simple-webapp-color labels: name: simple-webapp-color spec: containers: - name: simple-webapp-color image: simple-webapp-color ports: - containerPort: 8080 envFrom: - configMapRef: name: app-config
The environment variables APP_COLOR and APP_MODE are set using the
envFrom
field and referencing the ConfigMap using theconfigMapRef
field.With this setup, the container can access the configuration data from the mounted ConfigMap and use it to configure the application.
For more information on using ConfigMap as environmental variables in K8s, check out the official K8s Documentation.
Using Secrets
Secrets in K8s can be used to configure environmental variables for Pods. Secrets are stored as key-value pairs and can be passed to a Pod as environment variables or used to mount a volume in the Pod. When using Secrets, sensitive information is stored in an encrypted form and is only decrypted and made available to the Pod at runtime.
To configure environmental variables with Secrets in K8s, you need to first create the Secret and then reference it in the Pod definition file using the
envFrom
field in thespec.containers
section. This allows you to map the keys in the Secret to the environment variables in the Pod.Here’s an example of how to configure environmental variables using secrets in K8s:
- First encode your secrets with base64 : Base64 encoding can be used to encode secrets in k8s. To encode a secret with base64 in the terminal, you can use the following command :
echo -n "user1" | base64
r34TYp89AtrQ=
echo -n "myhost" | base64
cGf56tyGjH
echo -n "password1$" | base64
ghTu780POl
Note that “user1”, “myhost” and “password1$” are the sensitive values i want to encode. This will return the encoded secret as a string of characters in base64 format.
- Create a secret in your Kubernetes cluster by storing sensitive information in a key-value format. In a k8s YAML file, you can add the encoded secret as the value of an environmental variable, like this:
apiVersion: v1
kind: Secret
metadata:
name: app-secret
data:
DB_Host: cGf56tyGjH #encoded base64 format
DB_User: r34TYp89AtrQ= #encoded base64 format
DB_Password: ghTu780POl #encoded base64 format
Note that the values are base64-encoded, as secrets are stored as binary data in the K8s cluster.
- Use the
envFrom
field in your pod definition to set environment variables from the secret.
apiVersion: v1
kind: Pod
metadata:
name: simple-pod
labels:
name: simple-webapp-color
spec:
containers:
- name: simple-webapp-color
image: simple-webapp-color
ports:
- containerPort: 8080
envFrom:
- secretRef:
name: app-secret
This will set three environment variables which are DB_Host, DB_User and DB_Password based on the data stored in the secret.
OR via the CommandLine Interface (CLI), run the following command :
kubectl create secret generic db-secret --from-literal=DB_Host=sql01 --from-literal=DB_User=root --from-literal=DB_Password=password123
- Finally, verify that the environment variables are set by accessing the pod and checking the environment:
kubectl exec simple-pod env | grep DB_User
The above command will give you the below result:
DB_Host=user1
With these above steps, you can securely configure environmental variables in your Kubernetes cluster using secrets.
Note : Secrets are not encrypted but are encoded data in base64 format and anyone with the base64 encoded secret can easily decode it. As such the secrets can be considered not very safe. However, some best practices around using secrets make it safer. As in best practices like:
Not adding secret object definition files to source code repositories.
Enabling Encryption at Rest for Secrets so they are stored encrypted in ETCD. (check out the official K8s Documentation for more info about enabling encryption at Rest in ETCD )
Also the way K8s handles secrets, such as :
A secret is only sent to a node if a pod on that node requires it.
Kubelet stores the secret into a tmpfs so that the secret is not written to disk storage.
Once the Pod that depends on the secret is deleted, kubelet will delete its local copy of the secret data as well.
For more information on using Secret as environmental variables in K8s, check out the official K8s Documentation.
In conclusion, configuring environmental variables in K8s is an important aspect of deploying and running applications in a cluster. Whether you prefer to use ConfigMaps, Secrets, or the command-line interface, it is important to choose the right method for your specific needs and to make sure your configurations are secure and managed correctly.
By understanding the different ways to configure environmental variables in K8s, you can ensure that your applications are deployed and running smoothly, and that the data they need to function is readily available. With the ability to configure environmental variables, you can create flexible and scalable applications that can be adapted to meet changing requirements, while maintaining control over the configuration data they need to function.