Kubernetes job and deployment Kubernetes job and deployment kubernetes kubernetes

Kubernetes job and deployment


Based on the information you provided I believe you can achieve your goal using a Kubernetes feature called InitContainer:

Init containers are exactly like regular containers, except:

  • Init containers always run to completion.
  • Each init container must complete successfully before the next one starts.

If a Pod’s init container fails, Kubernetes repeatedly restarts the Pod until the init container succeeds. However, if the Pod has a restartPolicy of Never, Kubernetes does not restart the Pod.

  • I'll create a initContainer with a busybox to run a command linux to wait for the service mydb to be running before proceeding with the deployment.

Steps to Reproduce:- Create a Deployment with an initContainer which will run the job that needs to be completed before doing the deployment:

apiVersion: apps/v1kind: Deploymentmetadata:  labels:    run: my-app  name: my-appspec:  replicas: 2  selector:    matchLabels:      run: my-app  template:    metadata:      labels:        run: my-app    spec:      restartPolicy: Always      containers:      - name: myapp-container        image: busybox:1.28        command: ['sh', '-c', 'echo The app is running! && sleep 3600']      initContainers:      - name: init-mydb        image: busybox:1.28        command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

Many kinds of commands can be used in this field, you just have to select a docker image that contains the binary you need (including your sequelize job)

  • Now let's apply it see the status of the deployment:
$ kubectl apply -f my-app.yaml deployment.apps/my-app created$ kubectl get podsNAME                      READY   STATUS     RESTARTS   AGEmy-app-6b4fb4958f-44ds7   0/1     Init:0/1   0          4smy-app-6b4fb4958f-s7wmr   0/1     Init:0/1   0          4s

The pods are hold on Init:0/1 status waiting for the completion of the init container.- Now let's create the service which the initcontainer is waiting to be running before completing his task:

apiVersion: v1kind: Servicemetadata:  name: mydbspec:  ports:  - protocol: TCP    port: 80    targetPort: 9377
  • We will apply it and monitor the changes in the pods:
$ kubectl apply -f mydb-svc.yaml service/mydb created$ kubectl get pods -wNAME                      READY   STATUS     RESTARTS   AGEmy-app-6b4fb4958f-44ds7   0/1     Init:0/1   0          91smy-app-6b4fb4958f-s7wmr   0/1     Init:0/1   0          91smy-app-6b4fb4958f-s7wmr   0/1     PodInitializing   0          93smy-app-6b4fb4958f-44ds7   0/1     PodInitializing   0          94smy-app-6b4fb4958f-s7wmr   1/1     Running           0          94smy-app-6b4fb4958f-44ds7   1/1     Running           0          95s^C$ kubectl get allNAME                          READY   STATUS    RESTARTS   AGEpod/my-app-6b4fb4958f-44ds7   1/1     Running   0          99spod/my-app-6b4fb4958f-s7wmr   1/1     Running   0          99sNAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGEservice/mydb         ClusterIP   10.100.106.67   <none>        80/TCP    14sNAME                     READY   UP-TO-DATE   AVAILABLE   AGEdeployment.apps/my-app   2/2     2            2           99sNAME                                DESIRED   CURRENT   READY   AGEreplicaset.apps/my-app-6b4fb4958f   2         2         2       99s

If you need help to apply this to your environment let me know.


Although initContainers are a viable option for this solution, there is another if you use helm to manage and deploy to your cluster.

Helm has chart hooks that allow you to run a Job before other installations in the helm chart occur. You mentioned that this is for a database migration before a service deployment. Some example helm config to get this done could be...

apiVersion: batch/v1kind: Jobmetadata:  name: api-migration-job  namespace: default  labels:    app: api-migration-job  annotations:    "helm.sh/hook": pre-install,pre-upgrade    "helm.sh/hook-weight": "-1"    "helm.sh/hook-delete-policy": before-hook-creationspec:  template:    spec:      containers:        - name: platform-migration        ...

This will run the job to completion before moving on to the installation / upgrade phases in the helm chart. You can see there is a 'hook-weight' variable that allows you to order these hooks if you desire.

This in my opinion is a more elegant solution than init containers, and allows for better control.