Init  Containers: Day 11 of 40daysofkubernetes

Init Containers: Day 11 of 40daysofkubernetes

ยท

6 min read

Introduction

Welcome to Day 11 of the 40DaysOfKubernetes challenge! Today, we're diving into the concept of multi-container pods in Kubernetes. As you progress in your Kubernetes journey, you'll often encounter scenarios where a single container is insufficient for your application needs. This is where multi-container pods come into play, providing a powerful way to run closely related application components together within the same pod. Let's get Started

Multi-Container Pods in Kubernetes

A pod is the smallest deployable unit in Kubernetes and can contain one or more containers that share the same network namespace and storage. Multi-container pods are often used to enable tightly coupled application components to share resources and communicate easily.

Benefits of Multi-Container Pods:

  1. Resource Sharing: Containers within a pod share the same network IP, port space, and storage volumes, making it easier for them to communicate and share data.

  2. Tightly Coupled Components: Ideal for scenarios where multiple containers need to work closely together, for instance, a main application container and a helper container.

  3. Separation of Concerns: Allows the separation of different functionalities into distinct containers, each handling a specific task.

Init Container

Init containers are specialized containers that run before the main application containers in a pod. They are primarily used to perform initialization tasks that must be completed before the main containers start.

Characteristics of Init Containers:

  • Run Sequentially: Init containers run one at a time in sequence. Each init container must complete successfully before the next one starts.

  • Transient: Once all init containers complete successfully, they are terminated, and the main application containers start.

  • Different Configuration: Init containers can have different images and configurations from the main containers, allowing them to perform setup tasks that the main containers do not require.

Use Cases for Init Containers:

  1. Setup Tasks: Performing setup tasks like database schema migrations or pre-fetching data.

  2. Dependency Checking: Ensuring that all dependencies are available before the main application starts.

  3. Configuration Management: Setting up configuration files or secrets required by the main containers.

Example

Create a file mypod.yaml and paste the content below into it:

apiVersion: v1
kind: Pod
metadata:
  name: myapp
  labels:
    name: myapp-pod
spec:
  containers:
    - name: myapp-container
      image: busybox:1.28
      command: ['sh', '-c', 'echo The app is running! && sleep 3600']
      env:
        - name: FIRSTNAME
          value: "shivam"
  initContainers:
    - name: init-mycontainer
      image: busybox:1.28
      command: ['sh', '-c']
      args: ['until nslookup myservice.default.svc.cluster.local; do echo waiting to service up; sleep 2 ; done']

Explanation of this File

apiVersion: v1

Specifies the API version used to create this object. Here, v1 is the stable API version for core Kubernetes objects like pods.

kind: Pod

Specifies the type of Kubernetes object being created. In this case, it's a Pod.

metadata

Metadata provides information about the pod.

  • name: myapp Sets the name of the pod to myapp.

  • labels Adds labels to the pod for identification and grouping purposes.

    • name: myapp-pod Adds a label with key name and value myapp-pod.

spec

Spec defines the desired state of the pod, including the containers it runs.

containers

Defines the list of containers that run in the pod.

  • - name: myapp-container Names the container myapp-container.

  • image: busybox:1.28 Specifies the container image to use. In this case, it's busybox version 1.28.

  • command: ['sh', '-c', 'echo The app is running! && sleep 3600'] Sets the command to run in the container. Here, it runs a shell command that prints "The app is running!" and then sleeps for 3600 seconds (1 hour).

  • env Defines environment variables for the container.

    • - name: FIRSTNAME Sets an environment variable FIRSTNAME with the value "shivam".

initContainers

Defines the list of init containers for the pod. Init containers run to completion before any app containers start.

  • - name: init-mycontainer Names the init container init-mycontainer.

  • image: busybox:1.28 Specifies the container image to use. In this case, it's busybox version 1.28.

  • command: ['sh', '-c'] Specifies the command to run in the init container. The command uses the shell (sh) and the -c option allows the execution of a shell command string.

  • arg: ['until nslookup myservice.default.svc.cluster.local; do echo waiting to service up; sleep 2 ; done'] Provides the arguments for the command. Here, the command repeatedly checks (nslookup) if the service myservice.default.svc.cluster.local is up. If not, it prints "waiting to service up" and sleeps for 2 seconds before trying again. The until loop continues until the nslookup command succeeds.

This YAML file defines a Kubernetes pod with one init container and one application container. The init container ensures that a specific service (myservice.default.svc.cluster.local) is available before the main application container starts running. The application container runs a simple shell command that prints a message and then sleeps for an hour.

Now apply this file with the command:

kubectl apply -f mypod.yaml

In the image, you can see that our pod is created, In our pod there are two containers one is myapp( application container) and other one is init-container, but our application container is not running because it is waiting for the init container to run, and the init container is waiting for the condition to be satisfied as specified in our YAML file.

You can see the logs using the command:

kubectl logs pod/<pod-name>

And to see the logs of the init-container, use:

kubectl logs pod/<pod-name> <init-container-name>

It shows that it is waiting for the service to be up and keeps checking every 2 seconds, as specified in the YAML file.

Now we will create a deployment and expose it to a myservice service.

From the image, we can see that our myapp pod is running because the init container was waiting for myservice, and myservice was created.

Now check the logs of the init-container again using:

kubectl logs pod/myapp init-mycontainer

Now it is getting the response, as seen in the above image.

We already set an environment variable in our myapp pod, and to see that we can use the command:

kubectl exec -it myapp -- printenv

We can have multiple init-containers in the pod, and to run the main application, they should all run first.

Sidecar Containers

Sidecar containers are auxiliary containers that run alongside the main container(s) within the same pod. They help extend and enhance the functionality of the main application container without modifying it.

Characteristics of Sidecar Containers:

  • Run Concurrently: Sidecar containers run concurrently with the main containers and share the pod's lifecycle.

  • Complementary Functions: They provide supplementary functions such as logging, monitoring, or proxying.

Use Cases for Sidecar Containers:

  1. Logging: Collecting and shipping logs from the main application container to a central logging system.

  2. Monitoring: Running monitoring agents that collect metrics and health information.

  3. Proxying: Acting as a reverse proxy to manage traffic to and from the main application container.

  4. Data Synchronization: Synchronizing data between the main application and external services or systems.

We will be doing more hands-on with sidecar containers in the coming days.

Thank you for reading my blog. If you have any queries, please ask in the comments. I will surely answer your questions.

Resources I used

ย