ConfigMaps in Kubernetes (K8s)

Kubernetes Advocate
AVM Consulting Blog
6 min readFeb 16, 2021

--

ConfigMaps in K8s

ConfigMaps are Kubernetes objects that allow you to separate configuration data/files from image content to keep containerized applications portable.

ConfigMaps bind configuration files, command-line arguments, surroundings variables, port numbers, and alternative configuration artifacts to your Pods containers and system parts at run-time.

ConfigMaps are helpful for storing and sharing non-sensitive, unencrypted configuration data. Like Secrets, you’ll be able to produce config maps from files and with yaml declaration.

we are able to use config maps by relating its name and as a volume.

Create a configmap:

You can create config maps from directories, files, or literal values using kubectl create configmap.

$ cat app.properties 
environment=production
logging=INFO
logs_path=$APP_HOME/logs/
parllel_jobs=3
wait_time=30sec

and

kubectl create configmap app-config \ 
--from-file configs/app.properties
configmap "app-config" created

which is the same as

kubectl create configmap app-config \ 
--from-file configs/

and

kubectl create configmap app-config \ 
--from-literal environment=production \
--from-literal logging=INFO
.......

List configmap:

kubectl get configmap/app-config
NAME DATA AGE
app-config 1 1m

View configmap:

kubectl describe configmap/app-config
Name: app-config
Namespace: default
Labels: < none >
Annotations: < none >
Data
====
app.properties:
----
environment=production
logging=INFO
logs_path=$APP_HOME/logs/
parllel_jobs=3
wait_time=30sec
Events: < none >

Using YAML declaration:

The configmap YAML file will look like below

kind: ConfigMap
apiVersion: v1
metadata:
name: app-config
namespace: default
data:
app.properties: |
environment=production
logging=INFO
logs_path=$APP_HOME/logs/
parllel_jobs=3
wait_time=30sec

Here is the basic nginx configmap for PHP application

--- 
apiVersion: v1
data:
nginx.conf: |-
events {
}
http {
server {
listen 80 default_server;
listen [::]:80 default_server;

index index.html index.htm index.php;

root /var/www/html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
}
}
kind: ConfigMap
metadata:
name: nginx-config

Usage of ConfigMaps

ConfigMaps can be used to populate individual environment variables as shown below :

apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: my-app
image: my-app:latest
env:
- name: ENVIRONMENT
valueFrom:
configMapKeyRef:
name: app-config
key: environment
- name: LOG_MODE
valueFrom:
configMapKeyRef:
name: app-config
key: logging
- name: LOG_PATH
valueFrom:
configMapKeyRef:
name: app-config
key: logs_path
- name: THREDS_CLOUNT
valueFrom:
configMapKeyRef:
name: app-config
key: parllel_jobs

ConfigMaps can also be consumed in volumes.

The most basic way is to populate the volume with files where the key is the filename and the content of the file is the value of the key:

--- 
apiVersion: v1
kind: Pod
metadata:
name: nginx-web
spec:
containers:
-
image: "nginx:1.7.9"
name: nginx
ports:
-
containerPort: 443
name: nginx-https
-
containerPort: 80
name: nginx-http
volumeMounts:
-
mountPath: /etc/nginx/nginx.conf
name: nginx-config
subPath: nginx.conf
volumes:
-
configMap:
name: nginx-config
name: nginx-config

Kubernetes Secrets vs ConfigMaps

  1. Use Secrets for things that are actually secret like API keys, credentials, etc
  2. Use ConfigMaps for not-secret configuration data

In the future, there will likely be some differentiators for secrets like rotation or support for backing the secret API w/ HSMs, etc. In general, we like intent-based APIs, and the intent is definitely different for secret data vs. plain old configs.

One notable difference in the implementation is that kubectl apply -f:

  • ConfigMaps are “unchanged” if the data hasn’t changed.
  • Secrets are always “configured” — even if the file hasn’t changed

Both ConfigMaps and Secrets store data as a key-value pair. The major difference is Secrets stores data in base64 format meanwhile ConfigMaps stores data in plain text.

If you have some critical data like keys, passwords, service accounts credentials, DB connection string, etc then you should always go for Secrets rather than Configs.

And if you want to do some application configuration using environment variables that you don’t want to keep secret/hidden like, app theme, base platform URL, etc then you can go for ConfigMaps

On a Kubernetes Pod, what is the ConfigMap directory location?

Many applications require configuration via some combination of config files, command-line arguments, and environment variables. These configuration artifacts should be decoupled from image content to keep containerized applications portable. The ConfigMap API resource provides mechanisms to inject containers with configuration data while keeping containers agnostic of Kubernetes. ConfigMap can be used to store fine-grained information like individual properties or coarse-grained information like entire config files or JSON blobs.

I am unable to find where configmaps are saved. I know they are created however, I can only read them via the minikube dashboard.

ConfigMaps in Kubernetes can be consumed in many different ways and mounting it as a volume is one of those ways.

You can choose where you would like to mount the ConfigMap on your Pod. Example from K8s documentation:

ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
special.type: charm

Pod

apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
restartPolicy: Never

Note the volume definition and the corresponding volume mounts.

Other ways include:

  • Consumption via environment variables
  • Consumption via command-line arguments

Refer to the documentation for full examples.

Update k8s ConfigMap or Secret without deleting the existing one

You can get YAML from the kubectl create configmap command and pipe it to kubectl replace, like this:

kubectl create configmap foo --from-file foo.properties -o yaml --dry-run | kubectl replace -f -

For future reference, kubectl replace is now a very handy way to achieve this

kubectl replace -f some_spec.yaml Let you update a complete configMap (or other objects)

See doc and examples directly here

Copy/pasted from the help:

# Replace a pod using the data in pod.json.
kubectl replace -f ./pod.json
# Replace a pod based on the JSON passed into stdin.
cat pod.json | kubectl replace -f -
# Update a single-container pod's image version (tag) to v4
kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
# Force replace, delete and then re-create the resource
kubectl replace --force -f ./pod.json

For small changes in configMap, use edit
kubectl edit configmap <cfg-name>

kubectl replace fails if a configmap does not already exist:

$ kubectl create configmap foo --from-file foo.properties -o yaml --dry-run | kubectl replace -f -Error from server (NotFound): error when replacing "STDIN": configmaps "falco-config" not found

The best solution is to use kubectl apply which would create configmap if not present else update configmap if it is present:

$ kubectl create configmap foo --from-file foo.properties -o yaml --dry-run | kubectl apply -f -configmap/falco-config configured

For More, Recommendations

https://cloud.google.com/kubernetes-engine/docs/concepts/configmap

https://matthewpalmer.net/kubernetes-app-developer/articles/ultimate-configmap-guide-kubernetes.html

https://opensource.com/article/19/6/introduction-kubernetes-secrets-and-configmaps

https://phoenixnap.com/kb/kubernetes-configmap-create-and-use

👋 Join us today !!

️Follow us on LinkedIn, Twitter, Facebook, and Instagram

If this post was helpful, please click the clap 👏 button below a few times to show your support! ⬇

--

--

Kubernetes Advocate
AVM Consulting Blog

Vineet Sharma-Founder and CEO of Kubernetes Advocate Tech author, cloud-native architect, and startup advisor.https://in.linkedin.com/in/vineet-sharma-0164