CKA Full Course 2024: Day 11/40 Multi Container Pod Kubernetes - Sidecar vs Init Container

Lloyd Rivers - Oct 29 - - Dev Community

A Note from Me

In this project, I wanted to apply Kubernetes concepts like init containers and sidecar containers, but I didn’t want to just follow along with a tutorial.

My goal was to build something memorable.

After some brainstorming, I present to you the Get Me App!


What Get Me App Does

The Get Me App is designed to dynamically fetch and display content from various GitHub repositories. The application runs within a Kubernetes pod and comprises two primary components:

  1. Nginx Container: This serves as the main application, hosting the dynamically fetched content. It's lightweight and efficient, making it ideal for serving static web pages.

  2. Sidecar Container: This runs alongside the primary nginx container. It is responsible for refreshing the content every 5 seconds by fetching the latest HTML from a randomly selected GitHub page. This ensures that the content served by Nginx is always up to date.

  3. Init Container: This initializes the environment before the main containers start. It checks for the availability of the Get Me App Service by resolving its DNS entry. This step ensures that the application is ready to interact with the service once it starts running. Read more here (I had to)

The nginx container then serves the updated HTML webpage, making it accessible through a browser via a NodePort service.


Prerequisites

Before we start, ensure you have a configuration file to create the Kubernetes cluster. Refer to the Kind Quick Start guide for detailed instructions on setting up your Kind cluster.

Cluster Configuration (config.yml)

Create a file named config.yml with the following content to define your Kind cluster:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: cka-cluster  
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30001  # Change this to match the NodePort
    hostPort: 30001
    listenAddress: "0.0.0.0" 
    protocol: tcp
- role: worker  
- role: worker 
Enter fullscreen mode Exit fullscreen mode

Run the following command to create the cluster:

kind create cluster --name kind-cka-cluster --config config.yml
Enter fullscreen mode Exit fullscreen mode

Use the following command to set the context to the new cluster:

kubectl config use-context kind-kind-cka-cluster
Enter fullscreen mode Exit fullscreen mode

Step 1: Create the Project Directory and File

First, set up the directory and file structure for the project.

mkdir get-me-app
cd get-me-app
nano get-me-app.yml
Enter fullscreen mode Exit fullscreen mode

Step 2: Define the Kubernetes Pod Specification

In the get-me-app.yml file, we’ll define a Kubernetes pod that includes the nginx container, a sidecar container for content refreshing, and an init container for initial data fetch.

apiVersion: v1
kind: Pod
metadata:
  name: get-me-app
  labels:
    app: get-me-app
spec:
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup get-me-app-service.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for get-me-app-service; sleep 2; done"]

  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html

  - name: content-refresher
    image: busybox
    command: ["sh", "-c", "while true; do url=$(shuf -n 1 -e https://github.com/piyushsachdeva/CKA-2024 https://github.com/kubernetes https://github.com/jenkinsci https://github.com/techiescamp/kubernetes-learning-path https://github.com/NotHarshhaa/kubernetes-learning-path); wget -O /work-dir/index.html \"$url\"; sleep 5; done"]
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"

  volumes:
  - name: workdir
    emptyDir: {}
Enter fullscreen mode Exit fullscreen mode

What Each Part of This Pod Specification Does

  1. nginx container: This is the primary container, serving content on port 80. The volumeMount makes the /usr/share/nginx/html directory available in the pod’s workdir volume.

  2. Sidecar container (content-refresher): This container runs a while true loop, downloading the latest version of the webpage every 5 seconds. This ensures that the content in the workdir volume stays updated.

  3. Init container (init-myservice): This waits for the get-me-app-service to become available by continuously performing a DNS lookup. It runs only once during initialization and does not restart after completion.

  4. Volumes: The workdir volume (an emptyDir type) is shared among the containers, allowing the init container, sidecar, and nginx to access and serve the same content.


Step 3: Test Locally with NodePort (Optional)

To make the app accessible through a browser on your local machine, configure a NodePort service to expose the pod’s port 80.

Add this service definition in get-me-app-service.yml:

apiVersion: v1
kind: Service
metadata:
  name: get-me-app-service
spec:
  type: NodePort
  selector:
    app: get-me-app
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30001  
Enter fullscreen mode Exit fullscreen mode

Deploy the setup with:

kubectl apply -f get-me-app.yml

kubectl apply -f get-me-app-service.yml
Enter fullscreen mode Exit fullscreen mode

Access it by visiting http://localhost:30001 in your browser, and you should the github page. Refresh the page after 5 seconds and you should see a different github page.


Key Takeaways

This project helped me understand how init containers can initialize shared resources and how sidecar containers keep those resources updated for the main application. It's an engaging way to experiment with and learn about real-time data handling in Kubernetes.


Here’s the formatted content for the section you provided:


Tags and Mentions

End Notes: Please remember that this project is not part of the video tutorials. I wanted to build something on my own using the concepts from the tutorial as general guidance.

. . . . . . . . . . . . .