0
votes

I havw a question, as part of the kubectl deployment process we currently run, we sometimes need to run migrations on the database as part of that process.

We do what we call a rollout restart after we have re-built a tagged Docker image.

However, we usually have anywhere between 2 and 4 pods, with randomly assigned names, e.g.:

web-7f54669b5f-c6z8m             1/1     Running   0          55s
web-7f54669b5f-fp2kw             1/1     Running   0          67s

To run, say, a database migration command, we could do:

kubectl exec --stdin --tty web-7f54669b5f-fp2kw -- python manage.py migrate --plan

That's fine. But we were wondering if there a way to just target any of the "web" pods ...?

I'm assuming it's not possible, but not 100% sure why...

1
I would recommend using a kubernetes job. Most kubectl commands can work based on label filters, but exec is not one of them - jordanm
Assuming this is a migration that manipulates a shared resource, run the migration as a workload (pod) of its own that is controlled by another resource (like a job, as jordanm suggested) - Emile Pels
@jordanm Ahhh, ok, I did not know about k8s jobs. Thank you. So anytime I want to run a migration to the DB, I simply apply the kubernetes job, or does that merely create the "job" pod - then I can run it with another command from then on in? - Micheal J. Roberts
Use job as a standalone entity. Its like a regular pod but when finished, it's not being restarted (unlike a regular pod). Make all commands into a job, dont use exec. Once job finishes running commands it will change it's status to completed. - Matt
Thanks @Matt, makes sense for sure. - Micheal J. Roberts

1 Answers

2
votes

So, what you can do is add unique labels to all pods and fetch each one of them using labels.

Example:

kubectl exec --stdin --tty $(kubectl get po -l "<label_name>=<label_value>" \
-o jsonpath='{.items[0].metadata.name}') -- python manage.py migrate --plan