85

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.

0

3 Answers 3

160

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}}]
Sign up to request clarification or add additional context in comments.

10 Comments

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 Personally I solved it creating a special management Pod, in which I run all the commands before deploying the app itself.
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.
Yes, but since entrypoint and postStart are allegedly running asynchronously, you can add a sleep command as a last resort.
IMPORTANT NOTE: this will not wait until the pod is ready, but rather will execute immediately after the pod starts.
|
19

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.

Comments

4

My solution uses a readinessProbe
The application needs additional input that's only available after the process has fully initialized and the postStart method was executing before the app is ready.

readinessProbe:
  exec:
    command: [healthcheck]
  initialDelaySeconds: 30
  periodSeconds: 2
  timeoutSeconds: 1
  successThreshold: 3
  failureThreshold: 10    

WARNING: This method could cause undefined behavior. Take care with how you use it.

8 Comments

As per my understanding this will execute this command time to time not only once
Check the link I provided. I think you are referring to a liveness probe.
@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áximaAlekz the command will execute inside the container. You can use any command the container is equipped to handle.
The role of readiness and lifeness prob is not to execute commands that have side effects. They are here just to do what their names say. Check the health of the pod.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.