A mistake that many new developers make is the failure to remove key data in their applications to configuration files. It’s a hallmark of organizing code and is essential to perform correctly so that your team remains organized as your codebase scales. Therefore, most systems that orchestrate or provide an environment for applications to run, typically supply their own method of providing configurations or build upon existing robust solutions. Kubernetes is not an exception.
Enter ConfigMaps and Secrets, the “Kubernetes Way” of providing configurations to your contarized applications orchestrated by Kubernetes. Like all concepts that we’ve discussed in this series so far, they’re designed to work seamlessly with the “Pod Centric” approach of Kubernetes. They’re also designed to be accomodating to various types of data representation. For example, those familiar with representing configuration files as XML will find using ConfigMaps and Secrets just as easy for those whose cup of tea is JSON.
Yet, Kubernetes also provides the more traditional approach of configuring your applications in the form of environment variables. This is a method that is employed across a variety of cloud based deployments and was a key feature in the first iteration of our Nirmata orchestration solution. In this manner, Kubernetes provides leeway to developers who might not want to jump headfirst into the Kubernetes approach to configuration. It’s particularly useful for large organizations, who already make use of environment variables, and want to map their existing solutions onto Kubernetes for the purpose of prototyping.
In this blog post we’ll walk you through how you can configure your applications with ConfigMaps, Secrets, and Environment Variables.
ConfigMaps are Kubernetes objects that can draw configuration information from other sources such as directories or files. ConfigMaps are added to virtual directories called Volumes, which are mounted filesystems that share the lifetime of a Pod which encloses it. This enables containers to access information in ConfigMaps as if it were on a filesystem.
A powerful feature of ConfigMaps, is he ability to aggregate a variety of information from different file types into a config map. Furthermore, if we would like to update any of these files while our Pods are running, we can do so and have the changes be made available in realtime.
Suppose we have a directory data/ with the following files.
--- data/ --- info.json --- info2.xml
kubectl create configmap test-config --from-file=data
A ConfigMap could make info.json and info2.xml both accessible to pods which need to access this information. Let’s do this and run the following command to generate a configmap from this directory.
This will produce a ConfigMap that enables an application running in a container within a pod that uses this configmap to access configuration information as it would in a traditional filesystem.
To make a configmap accessible within a pod, we can modify the configuration of the pod itself. In his article “Kubernetes ConfigMaps and Secrets Part 2”, Sandeep Dinesh provides an example of a deployment that makes use of configmaps. Notice that that, we place ConfigMaps and Secretes under volumes:, since they are made available to Pods by Kubernetes through volumes.
# Licensed under the Apache License, Version 2.0 (the "License") apiVersion: extensions/v1beta1 kind: Deployment metadata: name: envtest spec: replicas: 1 template: metadata: labels: name: envtest spec: containers: - name: envtest image: gcr.io/smart-spark-93622/envtest:file5 ports: - containerPort: 3000 volumeMounts: - name: my-config mountPath: /usr/src/app/config - name: my-secret mountPath: /usr/src/app/secret volumes: - name: my-config configMap: name: my-config - name: my-secret secret: secretName: my-secret
Applications running within one our Pods orchestrated by this deployment, will be able to access configuration files as if they were part of a local file system. This makes it extremely easy to bring applications onto Kubernetes, without modifying their methods of accessing configuration information.
Secrets, in Kubernetes are a lot like ConfigMaps, except they encode information for safekeeping of sensitive information. This is essential for data such as API Keys, certificates, and many others.
The command for creating a secret is exactly like that of a config map. For example, taken the same data/ directory that we mentioned earlier.
--- data/ --- info.json --- info2.xml
We can create a secret that takes both of these files,
kubectl create secret generic test-secret --from-file=data/
Additionally, we can create a seperate secret, called credentials-secret, that stores an API key from a string literal.
kubectl create secret generic credentials-secret --from-literal=username=my_user --from-literal=password=K4Ab949
Therefore, secrets grant us the same flexibility and rapid deployment of configuration changes that ConfigMaps do, while granting us additional security for confidential information.
Note that secrets are only secure as long as the nodes that use them are secure. However, an infected node will only be able to view secrets that are made available to its pods.
One of the most basic methods of providing configuration information is through the use of environment variables. Docker comes with native support for this, and we can provide environment variables in the Dockerfiles of our docker containers.
The benefits of environment Variables include that they are a very popular method among developers of providing configuration information to their applications. Therefore, environment methods in Kubernetes provide an easy method of bringing existing applications that rely upon environment variables onto the platform.
In Kubernetes, setting environment variables is easy and occurs in the config.yaml under the spec field. For example, observe the following config.yaml file, from the Kubernetes documentation.
apiVersion: v1 kind: Pod metadata: name: envar-demo labels: purpose: demonstrate-envars spec: containers: - name: envar-demo-container image: gcr.io/google-samples/node-hello:1.0 env: - name: DEMO_GREETING value: "Hello from the environment" - name: DEMO_FAREWELL value: "Such a sweet sorrow"
Our containerized applications can now reference these environment variable directly in our code.
In this blog post, we provided three ways in which you can provide configurations to your containerized applications running on Kubernetes.
ConfigMaps provided an easy method of bundling multiple configuration files and mounting them as volumes. Secrets, added onto this capability, by encoding this information for enhanced security for sensitive data. Finally, we explored how Kubernetes let’s us forgo its own methods of providing configurations, in favor of traditional environment variables.
Again, it’s apparent that Kubernetes keeps developers in mind by taking popular methods of configuring applications, and extending them to a distributed container orchestration environment. At Nirmata, we strongly believe in empowering developers and therefore double down on the ease of providing configurations that Kubernetes offers to developers.