Kubernetes - deployment initialization - how to ensure it happens only once?

11/22/2018

I using Kubernetes 1.12. I have a service (e.g. pod) which may have multiple instances (e.g. replicas > 1)

My goal is to perform a maintenance task (e.g. create\upgrade database, generate certificate, etc) before any of service instances are up.

I was considering to use Init Container, but at least as I understand, Init Container will be executed anytime additional replica (pod) is created and worse - that might happen in parallel. In that case, multiple Init Containers might work in parallel and thus corrupt my database and everything else.

I need a clear solution to perform a bootstrap maintenance task only once per deployment. How you would suggest to do that?

-- Illidan
kubernetes

2 Answers

11/22/2018

One of the ways you could use to retain startup sequence controll would be to use StatefulSet. With sequential startup, next pod will not start untill previous is done, removing parallel init risk.

Personally I would prefer this init to have its own locking mechanism and stick to regular Deploymants.

Remember that you need to take into account not only first startup on Deployment creation, but also cases for rolling releases, scaling, outages etc.

-- Radek 'Goblin' Pieczonka
Source: StackOverflow

8/30/2019

I encountered the same problem running db migrations before each deployment. Here's a solution based on a Job resource:

kubectl apply -f migration-job.yml 
kubectl wait --for=condition=complete --timeout=60s job/migration
kubectl delete job/migration
kubectl apply -f deployment.yml

migration-job.yml defines a Job configured with restartPolicy: Never and a reasonably low activeDeadlineSeconds. Using kubectl wait ensures that any errors or timeout in migration-job.yml causes the script to fail and thus prevent applying deployment.yml.

-- Aleksi
Source: StackOverflow