Search code examples
kubernetesdeploymentjobskubectl

Kubernetes job and deployment


can I run a job and a deploy in a single config file/action Where the deploy will wait for the job to finish and check if it's successful so it can continue with the deployment?


Solution

  • 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/v1
    kind: Deployment
    metadata:
      labels:
        run: my-app
      name: my-app
    spec:
      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 pods
    NAME                      READY   STATUS     RESTARTS   AGE
    my-app-6b4fb4958f-44ds7   0/1     Init:0/1   0          4s
    my-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: v1
    kind: Service
    metadata:
      name: mydb
    spec:
      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 -w
    NAME                      READY   STATUS     RESTARTS   AGE
    my-app-6b4fb4958f-44ds7   0/1     Init:0/1   0          91s
    my-app-6b4fb4958f-s7wmr   0/1     Init:0/1   0          91s
    my-app-6b4fb4958f-s7wmr   0/1     PodInitializing   0          93s
    my-app-6b4fb4958f-44ds7   0/1     PodInitializing   0          94s
    my-app-6b4fb4958f-s7wmr   1/1     Running           0          94s
    my-app-6b4fb4958f-44ds7   1/1     Running           0          95s
    ^C
    $ kubectl get all
    NAME                          READY   STATUS    RESTARTS   AGE
    pod/my-app-6b4fb4958f-44ds7   1/1     Running   0          99s
    pod/my-app-6b4fb4958f-s7wmr   1/1     Running   0          99s
    
    NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
    service/mydb         ClusterIP   10.100.106.67   <none>        80/TCP    14s
    
    NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/my-app   2/2     2            2           99s
    
    NAME                                DESIRED   CURRENT   READY   AGE
    replicaset.apps/my-app-6b4fb4958f   2         2         2       99s
    

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