kuberneteskubernetes-pod

container initialization order in pod on K8s


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"

Solution

  • 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