DEV Community

Yusuf Isah
Yusuf Isah

Posted on • Originally published at yuscode.hashnode.dev

Chapter 4 - Kubernetes Pods

Introduction

In Kubernetes, the smallest and simplest unit of deployment is a Pod. Pods represent a single instance of a running process in your cluster. They encapsulate one or more containers, their storage resources, a unique network IP, and options that govern how the containers should run. This chapter will explore the concept of Pods, how to create and manage them, and how to ensure their health and performance in a Kubernetes cluster.

Table of Contents

Pods in Kubernetes

In Kubernetes, a Pod is the basic execution unit that comprises one or more containers. The term, Pod, is a nod to the Docker whale theme, as it refers to a group of whales swimming together. Similarly, a Pod groups containers together to work as a single, cohesive unit that can share resources and dependencies, communicate with each other, and be co-scheduled.

Key Points About Pods:

  • Single Unit of Deployment: Pods are the smallest deployable units in Kubernetes.

  • Shared Context: Containers within a Pod share the same network namespace, Inter-Process Communication (IPC) namespace, and can share storage volumes.

  • Lifecycle: Pods are created, scheduled, and managed by the Kubernetes control plane.

The Pod Manifest

A Pod manifest is a YAML file that defines the desired configuration of a Pod, utilizing Kubernetes' declarative approach. This means you specify the ideal state of your Pod in the manifest file, and then Kubernetes works to ensure that the actual state matches your declared intentions.

Creating a Pod

You can create a Pod by defining a manifest in YAML and applying it to your Kubernetes cluster.

Creating a Pod Manifest

To create a Pod manifest:

  • Define the apiVersion, kind, and metadata sections.

  • Under spec, specify the containers that the Pod should run.

Example Manifest:

apiVersion: v1
kind: Pod
metadata:
  name: greetings-pod
spec:
  containers:
  - name: greetings-container
    image: dockeryu853/greetings:1.1
    ports:
    - containerPort: 8080
Enter fullscreen mode Exit fullscreen mode

Let's name the manifest above greetings.yaml. To apply the manifest to your Kubernetes cluster, run:

kubectl apply -f greetings.yaml
Enter fullscreen mode Exit fullscreen mode

Running Pods

Once a Pod is created, you can perform various operations to manage and inspect it.

Listing Pods

Run the command below to list all Pods in your cluster:

kubectl get pods
Enter fullscreen mode Exit fullscreen mode

Image description

You can see the name of the Pod (greetings-pod) that we gave it in the YAML file. In addition to the number of ready containers (1/1), the output also shows the status, the number of times the Pod was restarted, and the age of the Pod.

If you ran this command immediately after the Pod was created, you might see:

Image description

ContainerCreating means that Kubernetes has received the YAML manifest and is in the process of creating the containers specified in the manifest. If what you see in the status field is Pending, it means that the Pod has been submitted but hasn’t been scheduled yet. If a more significant error occurs, such as an attempt to create a Pod with a container image that doesn’t exist, it will also be listed in the status field.

To see a list of the pods running in your Kubernetes cluster and observe dynamic changes in real-time, run:

kubectl get pods -w
Enter fullscreen mode Exit fullscreen mode

The command above allows you to observe the dynamic changes in your Pod landscape without needing to repeatedly run the kubectl get pods command. Press Ctrl+C to exit watch mode.

In addition, adding -o wide to any kubectl command will print out slightly more information (while still keeping the information to a single line).

kubectl get pods -o wide
Enter fullscreen mode Exit fullscreen mode

Image description

Pod Details

To get detailed information about a specific Pod, run:

kubectl describe pod <pod-name>
Enter fullscreen mode Exit fullscreen mode

Deleting a Pod

To delete a Pod, run:

kubectl delete pod <pod-name>
Enter fullscreen mode Exit fullscreen mode

NB: When you delete a Pod, any data stored in the containers associated with that Pod will be deleted as well. If you need to persist data across multiple instances of a Pod, you need to use Persistent Volumes, described at the end of this chapter.

Accessing Your Pod

Kubernetes provides several ways to interact with and troubleshoot Pods.

Getting More Information with Logs

To view the logs of a container in a Pod, run:

kubectl logs <pod-name> -c <container-name>
Enter fullscreen mode Exit fullscreen mode

Running Commands in Your Containers with exec

To execute a command in a running container:

kubectl exec -it <pod-name> -- <command>
Enter fullscreen mode Exit fullscreen mode

To exec into the greetings-pod, run the command below:

kubectl exec -it greetings-pod /bin/sh
Enter fullscreen mode Exit fullscreen mode

To exit, simply run the exit command inside the pod.

Copying Files to and From Containers

To copy files between your local system and a container:

kubectl cp <file-path> <pod-name>:/path/in/container
kubectl cp <pod-name>:/path/in/container <local-path>
Enter fullscreen mode Exit fullscreen mode

Health Checks

Kubernetes allows you to define health checks to ensure your containers are running as expected.

Liveness Probe

The liveness probe checks if a container is still running. If the check fails, Kubernetes restarts the container.

Example Liveness Probe:

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 3
  periodSeconds: 3
Enter fullscreen mode Exit fullscreen mode

The Liveness Probe configuration above will:

  • Wait 3 seconds after the container starts.

  • Send an HTTP GET request to http://localhost:8080/healthz every 3 seconds.

  • If the request fails or returns an error, Kubernetes will consider the container unhealthy and restart it.

Readiness Probe

The readiness probe checks if a container is ready to serve traffic.

Example Readiness Probe:

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 3
  periodSeconds: 3
Enter fullscreen mode Exit fullscreen mode

The readiness Probe configuration above will:

  • Wait 3 seconds after the container starts.

  • Send an HTTP GET request to http://localhost:8080/ready every 3 seconds.

  • If the request succeeds (returns a 200 OK response), the container is considered ready to receive traffic.

  • If the request fails or returns an error, the container is not considered ready, and Kubernetes will not send traffic to it.

Resource Management

You can specify the resources that your Pod's containers require, ensuring they run efficiently.

Resource Requests: Minimum Required Resources

Resource requests define the minimum amount of resources a container needs. These requests serve as a hint to the Kubernetes scheduler to ensure the Pod is placed on a node with sufficient resources. If the node doesn't have enough resources, the Pod won't be scheduled to that node.

Example:

  resources:
    requests:
      memory: "64Mi"
      cpu: "250m"
Enter fullscreen mode Exit fullscreen mode

The pod in the YAML manifest above is requesting:

  • At least 64 MB of memory to be allocated

  • At least 250 millicores (or 0.25 cores) of CPU processing power

Note that these are requests, not limits. The container can use more resources if available, but it's guaranteed to get at least the requested amount.

Capping Resource Usage With Limits

Resource limits specify the maximum resources a container can use. These limits prevent the container from consuming excessive resources and impacting other workloads running on the same node. If the container tries to use more resources than specified, Kubernetes will take action to enforce the limits, such as terminating the container if it exceeds the memory limit.

Example:

resources:
  limits:
    memory: "128Mi"
    cpu: "500m"
Enter fullscreen mode Exit fullscreen mode

The Pod in the YAML manifest above is restricted to:

  • Using no more than 128 MB of memory

  • Using no more than 500 millicores (or 0.5 cores) of CPU processing power

Persisting Data with Volumes

Kubernetes Volumes provide persistent storage to Pods, ensuring data is retained across restarts.

Using Volumes with Pods

apiVersion: v1
kind: Pod
metadata:
  name: greetings-pod
spec:
  containers:
  - name: greetings-container
    image: dockeryu853/greetings:1.1
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: static-files
      mountPath: /static
  volumes:
  - name: static-files
    hostPath:
      path: /home/yusbuntu/static
      type: Directory
Enter fullscreen mode Exit fullscreen mode

In the YAML manifest above, the VolumeMount is trying to achieve the following:

  • It's mounting a volume named static-files into the container at the path /static.

  • The static-files volume is defined in the volumes section and is of type hostPath, which means it's a directory on the host machine (the machine running the Kubernetes node).

  • The path field specifies the directory on the host machine (in this case, my Minikube Virtual Machine), /home/yusbuntu/static, which will be mounted into the container. Make sure to change /home/yusbuntu to your home directory or any other path you prefer.

As stated earlier, if you are using Minikube, you have to create this directory inside Minikube and not on your computer. Below are the steps to follow to create the directory inside Minikube.

minikube ssh
sudo mkdir -p /home/your_user_name/static
Enter fullscreen mode Exit fullscreen mode

Make sure to change your_user_name to your actual user name.

Putting it all Together

Kubernetes offers a comprehensive set of features, including persistent volumes for data storage, readiness and liveness probes for health monitoring, and resource restrictions for efficient resource allocation, making it an ideal platform for running stateful applications with high reliability and consistency. The manifest below puts this all together.

apiVersion: v1
kind: Pod
metadata:
  name: greetings-pod
spec:
  containers:
  - name: greetings-container
    image: dockeryu853/greetings:1.1
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: static-files
      mountPath: /static
    resources:
      limits:
        memory: "128Mi"
        cpu: "500m"
      requests:
        memory: "64Mi"
        cpu: "250m"
    readinessProbe:
      httpGet:
        path: /ready
        port: 8080
      initialDelaySeconds: 3
      periodSeconds: 3
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 3
      periodSeconds: 3
  volumes:
  - name: static-files
    hostPath:
      path: /home/yusbuntu/static
      type: Directory
Enter fullscreen mode Exit fullscreen mode

NB: Before applying the greetings.yaml manifest above, make sure to change the path (/home/yusbuntu/static) in your manifest to the path you specified in your Minikube VM.

Next, apply the manifest:

kubectl apply -f greetings.yaml
Enter fullscreen mode Exit fullscreen mode

Follow the steps below to see the contents of the container:

  • Once the container starts running, run the command below:

    kubectl get pods -o wide
    

Image description

  • As you can see from the image above, my IP is 10.244.0.214

  • Next, SSH into Minikube:

    minikube ssh
    
  • Run the command below to see the contents of the container running inside the pod:

 curl http://10.244.0.214:8080
Enter fullscreen mode Exit fullscreen mode

Conclusion

Understanding Pods is fundamental to working with Kubernetes. They encapsulate your application's containers, along with their storage, network, and configuration, into a single deployable unit. By mastering Pods and their associated operations, you can effectively manage your applications in a Kubernetes environment.

Feel free to leave comments and share this article. Follow my blog for more insights on Kubernetes!

Top comments (0)