container initialization order in pod on K8s

10/3/2021

I want to run two containers on a single pod.

container1 is a test that tries to connect to a SQL Server Database that runs on container2.

How can I make sure that the sql container (container2) will run and be ready before container1 starts?

initContainer won't work here, as it will run before both containers.

This is my compose.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: sql-test-pod
  labels:
    name: sql-test
spec:
  restartPolicy: Never
  containers:
    - name: my-sqldb
      image: docker-registry.com/database
      imagePullPolicy: Always
      resources:
        limits:
          memory: "4096Mi"
          cpu: "750m"
        requests:
          memory: "4096Mi"
          cpu: "750m"
    - name: tests
      tty: true
      stdin: true
      image: docker-registry.com/test
      imagePullPolicy: Always
      resources:
        limits:
          memory: "4096Mi"
          cpu: "750m"
        requests:
          memory: "4096Mi"
          cpu: "750m"
      env:
      - name: sqlhostname
        value: "SqlHostnamePlaceholder"
  nodeSelector:
    kubernetes.io/os: windows
  tolerations:
  - key: "windows"
    operator: "Equal"
    value: "2019"
    effect: "NoSchedule"
-- Gal I.
kubernetes
kubernetes-pod

3 Answers

10/4/2021

Another option is to add command and args to the container.

You can add sleep command if it's known approximate time for another container to start or add some logic within the command (while loop checking the connection, once it's connected, exit the loop and run main process - example).

Note! Image's entrypoint will be replaced by this command:

The command and arguments that you define in the configuration file override the default command and arguments provided by the container image

For instance, for nginx and command container spec will look like (since entrypoint is replaced, it's necessary to provide a command to start the nginx server):

  containers:
    - name: test
      image: nginx
      command: ["/bin/bash", "-c"]
      args: ["sleep 30 ; echo sleep ended ;  nginx -g \"daemon off;\""]

More details here Define a Command and Arguments for a Container.

-- moonkotte
Source: StackOverflow

10/4/2021

You cannot do that with current implements of kubernetes: all container in one pod will startup in same time(except the init container).

One solution is to enhance the code in test container to detect the state of db container, hold on until is ready.

-- vincent pli
Source: StackOverflow

10/7/2021

In order to make sure that container1 will start only after container2's SQL Server is up the only way I found is to use postStart container's lifecycle event. postStart triggered after after the container is create, it is true that there is no guarantee, that the postStart handler is called before the Container's entrypoint is called, but it turns out that the Kubelet code that starts the container blocks the start of the next container until the post-start handler terminates.

And this is how my new compose file will look like:

apiVersion: v1
kind: Pod
metadata:
  name: sql-test-pod
  labels:
    name: sql-test
spec:
  restartPolicy: Never
  containers:
    - name: my-sqldb
      image: docker-registry.com/database
      imagePullPolicy: Always
      lifecycle:
        postStart:
          exec:
            command: ['powershell.exe', '-command', "$connectionString = 'Server=sql-test-pod;User Id=user;Password=password'; $sqlConnection = New-Object System.Data.SqlClient.SqlConnection $connectionString; $i=0; while($i -lt 6) {Try { $i++;$sqlConnection.Open();$sqlConnection.Close(); return}Catch {Write-Error $_; start-sleep 30}}"]
      resources:
        limits:
          memory: "4096Mi"
          cpu: "750m"
        requests:
          memory: "4096Mi"
          cpu: "750m"
    - name: tests
      tty: true
      stdin: true
      image: docker-registry.com/test
      imagePullPolicy: Always
      resources:
        limits:
          memory: "4096Mi"
          cpu: "750m"
        requests:
          memory: "4096Mi"
          cpu: "750m"
      env:
      - name: sqlhostname
        value: "sql-test-pod"
  nodeSelector:
    kubernetes.io/os: windows
  tolerations:
  - key: "windows"
    operator: "Equal"
    value: "2019"
    effect: "NoSchedule"

Similar case you can find here

-- Gal I.
Source: StackOverflow