To myself...
Most apps require settings that are unique to themselves. Some of these settings can be credentials, others are not so sensitive but still need to be managed when these apps get deployed. These settings are what we usually called configs or configurations in software domain.
A little history
Going back to the old ways of doing things, when an app is deployed, it will usually contain a file alongside it that will hold the sensitive and non-sensitive configuration. After the introduction of Docker, it's a very similar way of deployment except that the image that is packaged also contains the configuration within it.
So what's so wrong with this approach? Well for one, when some config needs to be changed, the image needs to be recompiled and redeployed again. Another reason is that the confidential information such as API keys or passwords is exposed as plaintext. Anyone that can get into the system can alter these things!
What about using volumes in Docker? That's a good catch but volumes for config files still require to or mounted first before the container is started.
So is there really a way to solve these problems better? Yes of course! Using Kubernetes ConfigMap and Secret are the keys to manage these issues.
What is a ConfigMap?
ConfigMap is a top-level Kubernetes resource to store configuration data, called environment variables, inside a container in a decoupled way. At its core, ConfigMap is a map of key/value pairs.
What do you mean by decoupled? It means that the running container doesn't need to know the existence of the ConfigMap because upon the creation of ConfigMap, its contents are passed to the container as either environment variables or as files in a volume.
Creating a ConfigMap
There are 3 ways to create a ConfigMap in Kubernetes.
- with a literal
- with a manifest file
- with a config file
- with an env file
Let's start an example of informing our app how to locate the API for users. In here we define apiUrl as the key and the value is https://my-site.com/api/users
Option 1
There's no file. We directly tell Kubernetes our setting/s from the command line.
Command to run
kubectl create configmap [cm-name] --from-literal=apiUrl=https://my-site.com/api/users
Option 2
There needs to be a manifest file and the format is
apiVersion: v1 kind: ConfigMap metadata: name: app-settings labels: app: app-settings data: apiUrl: "https://my-site.com/api/users"
Command to run
kubectl create -f configmap.yml
Notice that the command doesn't need to explicitly invoke the configmap
. This is because the manifest file declares the kind of file as ConfigMap
.
Option 3
A typical config file, let's call it api.config
apiUrl=https://my-site.com/api/users
Command to run
kubectl create configmap [cm-name] --from-file=[path-to-file]
Under the hood, Kubernetes will generate a ConfigMap
apiVersion: v1 kind: ConfigMap data: api.config: |- apiUrl=https://my-site.com/api/users
The file name api.config
is the key.
Option 4
With env file, for instance, api.env
apiUrl=https://my-site.com/api/users
Command to run
kubectl create configmap [cm-name] --from-env-file=[path-to-file]
Under the hood, Kubernetes will generate a ConfigMap
apiVersion: v1 kind: ConfigMap data: apiUrl=https://my-site.com/api/users
The file name api.env
is not included as the key.
Consuming a ConfigMap
So now that we know how to create a ConfigMap, what's next? Well, the following step is to create it of course and let it be consumed by pods or containers.
Accessing a ConfigMap via Environment Variables
Let's say we opted for option 4 using env file. We can let the pod access the ConfigMap by appending an env
key like below.
apiVersion: apps/v1 ... spec: template: ... spec: containers: ... env: - name: APIURL valueFrom: configMapKeyRef: name: app-settings key: apiUrl
The pod now has an environment variable name called APIURL
with its value reference from the ConfigMap data apiUrl
.
In reality, the env file will contain more entries. In this case, if there's a need to use up all the environment variables without declaring them one after another, we can use envFrom
key instead of env
key.
envFrom: - configMapRef: name: app-settings
Now all the entries in the env file is available to the pod
Accessing a ConfigMap via Volume
With this approach, it is possible to change the settings without redeploying the container. Although there would be 30-60 second delay, for most cases, this is sufficient.
apiVersion: v1 ... spec: template: ... spec: volumes: - name: app-config-vol configMap name: app-settings containers: volumeMounts: - name: app-config-vol mountPath: /etc/config
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.