74

I would like to run specific command after initialization of deployment is successful.

This is my yaml file:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: auth
spec:
  replicas: 1
  template:
    metadata:
        labels:
          app: auth
    spec:
      containers:
        - name: auth
          image: {{my-service-image}}
          env:
          - name: NODE_ENV
            value: "docker-dev"
          resources:
            requests:
              cpu: 100m
              memory: 100Mi
          ports:
            - containerPort: 3000

However, I would like to run command for db migration after (not before) deployment is successfully initialized and pods are running.

I can do it manually for every pod (with kubectl exec), but this is not very scalable.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
meerkat
  • 2,673
  • 5
  • 18
  • 33

3 Answers3

140

I resolved it using lifecycles:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: auth
spec:
  replicas: 1
  template:
    metadata:
        labels:
          app: auth
    spec:
      containers:
        - name: auth
          image: {{my-service-image}}
          env:
          - name: NODE_ENV
            value: "docker-dev"
          resources:
            requests:
              cpu: 100m
              memory: 100Mi
          ports:
            - containerPort: 3000
          lifecycle:
            postStart:
              exec:
                command: ["/bin/sh", "-c", {{cmd}}]
shkaper
  • 4,689
  • 1
  • 22
  • 35
meerkat
  • 2,673
  • 5
  • 18
  • 33
  • 10
    great answer for something that works in a command line and in the same container, but I would like to do this in a separate container that runs to completion and goes away like an init-container – Rhubarb Mar 12 '18 at 18:20
  • @Rhubarb Personally I solved it creating a special management Pod, in which I run all the commands before deploying the app itself. – Denis V Apr 08 '18 at 07:57
  • 24
    be careful cause according tho the documentation, there is not garantee that the postStart is called after or before the container entry point is called. – SeB.Fr Jul 03 '18 at 13:40
  • 1
    Yes, but since entrypoint and postStart are allegedly running asynchronously, you can add a sleep command as a last resort. – yuranos Dec 05 '20 at 22:54
  • Do you add sleep to ensure poststart finishes before the entrypoint starts? – James Forbes Feb 21 '21 at 01:06
  • unfortunately, if your replicas is more than 1, your command will be executed more than once – kakarukeys Apr 02 '21 at 11:09
  • Thanks. Works well. I have NFS server pod running. Whenever the new pod starts, the mounted filesystem automatically has index.html created onto it. I could move that using the post start script. – Nikhil Apr 17 '21 at 08:30
  • thank you : command: ["/bin/sh", "-c", "npx prisma generate"] – Rafiq Jun 03 '21 at 23:29
16

You can use Helm to deploy a set of Kubernetes resources. And then, use a Helm hook, e.g. post-install or post-upgrade, to run a Job in a separate docker container. Set your Job to invoke db migration. A Job will run >=1 Pods to completion, so it fits here quite well.

Tomek
  • 494
  • 2
  • 11
Ewa
  • 553
  • 7
  • 13
4

I chose to use a readinessProbe
My application requires configuration after the process has completely started. The postStart command was running before the app was ready.

readinessProbe:
  exec:
    command: [healthcheck]
  initialDelaySeconds: 30
  periodSeconds: 2
  timeoutSeconds: 1
  successThreshold: 3
  failureThreshold: 10    
D.Fitz
  • 493
  • 5
  • 16
  • 1
    As per my understanding this will execute this command time to time not only once – Shadman Oct 11 '21 at 12:54
  • Check the link I provided. I think you are referring to a liveness probe. – D.Fitz Oct 19 '21 at 17:59
  • @D.Fitz so using this config, when app is ready will run "healthcheck"? What is exactly healthcheck, an script? Must be bash? can be something like Python/Node/PHP? – Máxima Alekz Nov 28 '22 at 17:55
  • @MáximaAlekz the command will execute inside the container. You can use any command the container is equipped to handle. – D.Fitz Nov 28 '22 at 18:44
  • @D.Fitz So an example of using bash would be `[ "/bin/sh", "-c", "echo Hella" ]`? – Máxima Alekz Nov 29 '22 at 19:18
  • You could use [startupProbe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-startup-probes) instead of `readinessProbe` to have it run only before the container is ready and until it succeeds. After that, it won't run and the `readinessProbe` will run instead. – MorganGalpin Jan 25 '23 at 03:59