Video Thumbnail for Lesson
4.2: Pod

Pod

In Kubernetes, a Pod is the smallest and simplest unit in the Kubernetes object model that you can create or deploy. A Pod represents a running process on your cluster and encapsulates an application container (or, in some cases, multiple containers), storage resources, a unique network IP, and options that govern how the container(s) should run.

🚨 Note: In the real world you will almost never create pods directly. Instead you will work with the higher level resources like Deployments and Jobs and let Kubernetes manage the underlying pods. We are creating these pods manually for educational purposes only.

Hands-On: Working with Pods

Let's explore how to create and manage Pods using practical commands.

1. Create a Namespace for the Examples

First, we'll create a namespace for these examples and set it as the default.

# task 01-create-namespace
# - Create a namespace for these examples and set as default.
kubectl apply -f Namespace.yaml
kubens 04--pod

2. Create a Pod the Wrong Way

Next, we'll demonstrate how to create a Pod the wrong way (via a kubectl run command). This method is not recommended for creating Pods in production environments.

# task 02-wrong-way-create
# - Create a pod the wrong way.
kubectl run --image=nginx:1.26.0 -n ${NAMESPACE} created-the-wrong-way

3. Apply the Minimal Pod Configuration

Now, we'll apply a minimal Pod configuration using a YAML file. This definition only contains a container name and image tag so it will use the Kubernetes defaults for all other fields.

# Pod.nginx-minimal.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-minimal
spec:
  containers:
    - name: nginx
      image: nginx:1.26.0
# task 03-minimal-apply
# - Apply the minimal pod configuration.
kubectl apply -n ${NAMESPACE} -f Pod.nginx-minimal.yaml

4. Apply a Better Pod Configuration

Now, we'll apply a Pod configuration containing additional settings for security and resource management.

As you can see from the below specification, we have added:

  1. Container Port: Specifies that the container listens on port 8080 for TCP traffic, necessary for the readiness probe and port forwarding.

  2. Readiness Probe: Checks the application's health by performing an HTTP GET request to / on port 8080. Ensures traffic is routed only when the application is ready.

  3. Resource Requests and Limits: Defines minimum (requests: 50Mi memory, 250m CPU) and maximum (limits: 50Mi memory) resource usage to ensure proper function and prevent overconsumption.

  4. Security Context for Pod and Container: Enhances security by setting policies at both Pod and container levels. Disables privilege escalation (allowPrivilegeEscalation: false) and prevents running in privileged mode (privileged: false).

  5. Non-Root User: Runs the Pod as a non-root user with user ID 1001 and group ID 1001 (runAsUser and runAsGroup). Ensures the container cannot run as root (runAsNonRoot: true), enhancing security.

# Pod.nginx-better.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-better
  namespace: 04--pod
spec:
  containers:
    - name: nginx
      image: cgr.dev/chainguard/nginx:latest
      ports:
        - containerPort: 8080
          protocol: TCP
      readinessProbe:
        httpGet:
          path: /
          port: 8080
      resources:
        limits:
          memory: "50Mi"
        requests:
          memory: "50Mi"
          cpu: "250m"
      securityContext:
        allowPrivilegeEscalation: false
        privileged: false
  securityContext:
    seccompProfile:
      type: RuntimeDefault
    runAsUser: 1001
    runAsGroup: 1001
    runAsNonRoot: true
# task 05-better-apply
# - Apply the better pod configuration.
kubectl apply -n ${NAMESPACE} -f Pod.nginx-better.yaml

5. Delete the Namespace to Clean Up

Finally, clean up by deleting the namespace, which will also delete all resources within it.

# task 07-delete-namespace
# - Delete the namespace to clean up.
kubectl delete -f Namespace.yaml