Using Init Containers to perform tasks before a pod is deployed

OKD provides init containers, which are specialized containers that run before application containers and can contain utilities or setup scripts not present in an app image.

Understanding Init Containers

You can use an Init Container resource to perform tasks before the rest of a pod is deployed.

A pod can have Init Containers in addition to application containers. Init containers allow you to reorganize setup scripts and binding code.

An Init Container can:

  • Contain and run utilities that are not desirable to include in the app Container image for security reasons.

  • Contain utilities or custom code for setup that is not present in an app image. For example, there is no requirement to make an image FROM another image just to use a tool like sed, awk, python, or dig during setup.

  • Use Linux namespaces so that they have different filesystem views from app containers, such as access to secrets that application containers are not able to access.

Each Init Container must complete successfully before the next one is started. So, Init Containers provide an easy way to block or delay the startup of app containers until some set of preconditions are met.

For example, the following are some ways you can use Init Containers:

  • Wait for a service to be created with a shell command like:

    1. for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
  • Register this pod with a remote server from the downward API with a command like:

    1. $ curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d ‘instance=$()&ip=$()’
  • Wait for some time before starting the app Container with a command like sleep 60.

  • Clone a git repository into a volume.

  • Place values into a configuration file and run a template tool to dynamically generate a configuration file for the main app Container. For example, place the POD_IP value in a configuration and generate the main app configuration file using Jinja.

See the Kubernetes documentation for more information.

Creating Init Containers

The following example outlines a simple pod which has two Init Containers. The first waits for myservice and the second waits for mydb. After both containers complete, the pod begins.

Procedure

  1. Create a YAML file for the Init Container:

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: myapp-pod
    5. labels:
    6. app: myapp
    7. spec:
    8. containers:
    9. - name: myapp-container
    10. image: registry.access.redhat.com/ubi8/ubi:latest
    11. command: ['sh', '-c', 'echo The app is running! && sleep 3600']
    12. initContainers:
    13. - name: init-myservice
    14. image: registry.access.redhat.com/ubi8/ubi:latest
    15. command: ['sh', '-c', 'until getent hosts myservice; do echo waiting for myservice; sleep 2; done;']
    16. - name: init-mydb
    17. image: registry.access.redhat.com/ubi8/ubi:latest
    18. command: ['sh', '-c', 'until getent hosts mydb; do echo waiting for mydb; sleep 2; done;']
  2. Create a YAML file for the myservice service.

    1. kind: Service
    2. apiVersion: v1
    3. metadata:
    4. name: myservice
    5. spec:
    6. ports:
    7. - protocol: TCP
    8. port: 80
    9. targetPort: 9376
  3. Create a YAML file for the mydb service.

    1. kind: Service
    2. apiVersion: v1
    3. metadata:
    4. name: mydb
    5. spec:
    6. ports:
    7. - protocol: TCP
    8. port: 80
    9. targetPort: 9377
  4. Run the following command to create the myapp-pod:

    1. $ oc create -f myapp.yaml

    Example output

    1. pod/myapp-pod created
  5. View the status of the pod:

    1. $ oc get pods

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. myapp-pod 0/1 Init:0/2 0 5s

    Note that the pod status indicates it is waiting

  6. Run the following commands to create the services:

    1. $ oc create -f mydb.yaml
    1. $ oc create -f myservice.yaml
  7. View the status of the pod:

    1. $ oc get pods

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. myapp-pod 1/1 Running 0 2m