ConfigMaps in Kubernetes (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=30secEvents: < 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
- Use Secrets for things that are actually secret like API keys, credentials, etc
- 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 !!
If this post was helpful, please click the clap 👏 button below a few times to show your support! ⬇