kevP-Sirius
kevP-Sirius

Reputation: 113

Kubernetes rolling update with updating value in deployment file

I wanted to share a solution I did with kubernetes and have your opinion on best practice to do in such case. I'm still new to kubernetes.

I had a problem I wanted to be able to update my application by restarting my deployment pod that execute all the necessary action to do that already in command start.

I'm using microk8s and I wanted to just go to the good folder and execute microk8s kubectl apply -f myfilename and let kubernetes handle the rest with rolling update.

My issue was how to set dynamic value inside my .yaml file so the command would detect the change and start the process.

I've planned to do a bash script that do the job like the following:

file="my-file-deployment.yaml"
oldstr=`grep  'my' $file | xargs`
timestamp="$(date +"%Y-%m-%d-%H:%M:%S")"
newstr="value: my-version-$timestamp"
sed -i "s/$oldstr/$newstr/g" $file
echo "old version : $oldstr"
echo "Replaced String :  $newstr"

sudo microk8s kubectl apply -f $file

on my deployment.yaml file I'm giving the following env:

env:
- name: version
  value: my-version-2022-09-27-00:57:15

I'm switching with timestamp to a new value then I launch the command:

microk8s kubectl apply -f myfilename

it is working great for the moment. I still have to configure startupProbe to have a better rolling update execution because I'm having few second downtime which isn't cool.

Is there a better solution to work with rolling update using microk8s?

Upvotes: 0

Views: 1036

Answers (1)

Blender Fox
Blender Fox

Reputation: 5625

If you are trying to trigger a rolling update on your deployment (assuming it is a deployment), you can patch the deployment and let the cluster handle the rollout. Here's a trick I use and it's literally a one-liner:

kubectl -n {namespace} patch deployment {name-of-your-deployment} \
  -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}"

This will patch your deployment, adding an annotation to the template block. In this way, the cluster thinks there is a change requiring an update to the deployment's pods, and will cycle them while following the rollingUpdate clause.

The date +'%s' will resolve to a different number each time so every time you run this, it will cause the cluster to cycle the deployment's pods.

We use this trick to force a rolling update when we have done an update that requires our pods to be restarted.

You can accompany this with the rollout status command to wait for the update to complete:

kubectl rollout status deployment/{name-of-your-deployment} -n {namespace}

So a complete line would be something like this if I wanted to rolling update my nginx deployment and wait for it to complete:

kubectl -n nginx patch deployment nginx \
  -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}" \
  && kubectl rollout status deployment/nginx -n nginx

One caveat, though. Using kubectl patch does not make changes to the yamls on disk, so if you wanted a copy of the change recorded locally, such as for auditing purposes, similar to what you are doing at the moment, then you could adapt this to do it as a dry-run and redirect output to file:

kubectl -n nginx patch deployment nginx \
  -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"date\":\"`date +'%s'`\"}}}}}" \
  --dry-run=client \
  -o yaml >patched-nginx.yaml

Upvotes: 2

Related Questions