There may be cases wherein we just need to update a Kubernetes configmap or any other Kubernetes object based on our requirements.
And let's say it's just one or two configmaps(here we will be talking about configmaps just for simplicity but its applicable for other Kubernetes objects as well) then that's fine, right? We can simply do the following:
kubectl edit -n NAMESPACE_NAME configmap CONFIGMAP_NAME
- Update it based on our requirements.
- Save it.
But think about a scenario, wherein we need to update +100 configmaps with the same values how to do it?
We cannot update or edit each and every object since that would be a bit tedious and will be error-prone as well. Plus there might be chances we might skip some of them.
So, the best way to do it is by using patch
command in an automated way.
Refer: https://kubernetes.io/docs/reference/kubectl/generated/kubectl_patch/ for more details about it.
Let's see this in action:
- I have a very minimal configmap which contains some DATABASE details.
apiVersion: v1
data:
DATABASE_HOST: "api01.ybdb.io"
DATABASE_NAME: "api01"
DATABASE_PORT: "5433"
kind: ConfigMap
metadata:
name: api01-configmap
namespace: default
- Now, let's assume there is an update instead of port number 5433. Our database now listens on port 5444.
- We can easily accomplish this using
kubectl edit
but let's seepatch
in action:
$ kubectl patch configmap api01-configmap -n default -p '{"data":{"DATABASE_PORT":"5444"}}'
configmap/api01-configmap patched
$ kubectl get cm -n default -o yaml api01-configmap
apiVersion: v1
data:
DATABASE_HOST: api01.ybdb.io
DATABASE_NAME: api01
DATABASE_PORT: "5444"
kind: ConfigMap
metadata:
creationTimestamp: "2024-05-22T10:06:39Z"
name: api01-configmap
namespace: default
resourceVersion: "67651"
uid: 2d49a0ea-6910-420c-b2bf-00e42e6c08d7
- The command is pretty straight forward
kubectl patch configmap api01-configmap -n default -p '{"data":{"DATABASE_PORT":"5444"}}'
- -n is to specify the namespace name where the configmap resides.
- -p is to specify what patch/update we want in the Kubernetes object.
- Here, under
data:
we are updating a key calledDATABASE_PORT:
to5444
. - Note: If in case
DATABASE_PORT:
key doesn't exist, it will create that key for us.
Assume you want to see the output as well in the same command then add -o or --output flag with the type [json,name,yaml,etc].
$ kubectl patch configmap api01-configmap -n default -p '{"data":{"DATABASE_PORT":"5444"}}' -o yaml
apiVersion: v1
data:
DATABASE_HOST: api01.ybdb.io
DATABASE_NAME: api01
DATABASE_PORT: "5444"
kind: ConfigMap
metadata:
creationTimestamp: "2024-05-22T10:47:41Z"
name: api01-configmap
namespace: default
resourceVersion: "69416"
uid: a303bd0e-7f61-49c0-b671-06649ecdf999
But there is another catch, you can also not run the patch command +100 times, I mean definitely you can but again that might be error-prone too.
So, in that case we can write a simple reusable bash script that can do the job for us and can help us to update +100 configmaps in one go.
It can be in any language but I have chosen bash
, since it's pretty common.
Quick rundown of the script:
- Here I have three variables, NAMESPACE (where the object resides), CONFIGMAP_FILE (input file which contains a list of all the configmaps that need to be updated), DATA (a set of key:value pair which needs to be replaced/added).
- Here I am creating log files as well (update_cm.log - contains generic readable information, patch.log - contains output of patch command).
- As of now, I just have added action as add but we can have other actions as well like replace or remove (based on our requirements).
#!/bin/bash
NAMESPACE="default"
CONFIGMAP_FILE="configmaps"
DATA='{"data":{"DATABASE_PORT":"5444"}}'
rm patch.log update_cm.log
if [ ! -f "$CONFIGMAP_FILE" ]; then
echo "File $CONFIGMAP_FILE not found."
exit 1
fi
echo `date` >> update_cm.log
echo "----------------------------" >> update_cm.log
action=$1
if [ "$action" == "add" ]; then
echo "Action: $action"
echo "Action: $action" >> update_cm.log
while IFS= read -r cm; do
echo "Updating ConfigMap: $cm"
echo "Updating ConfigMap: $cm" >> update_cm.log
kubectl patch configmap "$cm" -n "$NAMESPACE" -p $DATA >> patch.log 2>&1
done < "$CONFIGMAP_FILE"
else
echo "Invalid action, please specify add".
exit 1
fi
echo "----------------------------" >> update_cm.log
Feel free to use it, tweak it, based on your requirements. This script is for configmaps but similar logic we can write for other objects as well if required.
Happy learning :)
References:
- Google.
- Kubernetes docs (https://kubernetes.io/docs/home/).
kubectl explain
Disclaimer:
- We should not manually update/patch the Kubernetes objects, this should be done when absolutely necessary or needed on the fly.
- Ideally these all values should come from the version control system wherein the values files are maintained.