Skip to content

Pods


A pod is the smallest and simplest unit in the Kubernetes object model that can be created or deployed.

It is an ephemeral object, designed to be created, destroyed and re-created on a regular basis.

Think of a pod as a wrapper object around containers:
Pods

A pod can be a host for multiple containers, however, as a general rule, only one container per pod should be allowed. If a pod has multiple containers, they will all share the same network namespace and storage volumes.

How to create pods?

Pods can be created either declaratively or imperatively.

E.g.:

apiVersion: v1
kind: Pod
metadata: 
  name: nginx-pod
  namespace: sandbox
  labels:
    app: nginx
spec:
  containers:
    - name: nginx-container
      image: nginx
Pulling images from private registries

By default, pods pull their container images from the DockerHub public registry.

If you want to pull from a private registry, you must first create a secret with your access credentials to the registry inside the Kubernetes cluster:

kubectl create secret docker-registry regcred \
 --docker-server=private-registry.io \
 --docker-username=registry-user \
 --docker-password=registry-password \
 --docker-email=registry-email@org.com

After that, specify the image registry on the container’s image section, alongside the imagePullSecret:

image: private-registry.io/apps/nginx
imagePullSecrets:

 - name: regcred

Specifying environment variables

You can provide environment variables to an init container using the env field:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: app
      image: busybox:1.36
      env:
        - name: ENVIRONMENT
          value: "sandbox"
      command: ["sh", "-c", "echo Running in $ENVIRONMENT"]

Alternatively, you can load variables from a ConfigMap or a Secret:

    env:
      - name: APP_MODE
        valueFrom:
          configMapKeyRef:
            name: app-config
            key: mode

Mounting volumes

You can mount volumes in containers by declaring them under spec.volumes. Each container that needs to access it must mount it individually:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  volumes:
    - name: shared-data
      emptyDir: {}

  initContainers:
    - name: init
      image: busybox:1.36
      command:
        - sh
        - -c
        - echo "Initialized by the init container" > /work/message.txt
      volumeMounts:
        - name: shared-data
          mountPath: /work

  containers:
    - name: app
      image: nginx:latest
      volumeMounts:
        - name: shared-data
          mountPath: /usr/share/nginx/html

Setting resource limits

You can set resource limits for a container using the resources field:

containers:
  - name: init
    image: busybox:1.36
    resources:
      requests:
        cpu: "100m"
        memory: "64Mi"
      limits:
        cpu: "250m"
        memory: "128Mi"

What are init containers?

Init containers are specialized containers that run before the application containers in a pod. They run to completion and must exit successfully before the next init container, or the application containers, can start.

What are sidecar containers?

A sidecar container is a secondary container that runs alongside an application container in the same pod. It extends or supports the application without being responsible for its primary workload.

Common sidecar responsibilities include:

  • Collecting, exporting or forwarding logs;
  • Synchronizing files;
  • Providing proxies or security features;
  • Handling service-to-service communication.

E.g.:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  initContainers:
  - name: sidecar-container
    image: ubuntu:latest
    restartPolicy: Always
  containers:
  - name: nginx-container
    image: nginx:latest

A sidecar is identified by setting restartPolicy: Always on an entry under initContainers. If this field is omitted, Kubernetes treats the container as a regular init container and waits for it to terminate successfully before starting the application containers.

How to execute commands in a container?

After a pod is running, you can issue regular commands to any container running inside it with kubectl exec.

If the pod contains a single container, use:

kubectl exec <pod_name> -- <command>

If the pod contains multiple containers, specify the target container with -c:

kubectl exec <pod_name> -c <container_name> -- <command>

E.g.:

kubectl exec my-pod -c app -- printenv

The -- separates the kubectl exec options from the command that should run inside the container.

Opening a shell inside a container

You can start an interactive shell inside a container with:

kubectl exec <pod_name> -c <container_name> -it -- /bin/sh

What are probes?

Probes are health checks that the kubelet uses to monitor containers running inside a pod. They determine whether a container has started successfully, is functioning correctly, and is ready to receive traffic.

Kubernetes supports three probe types:

  • Startup probe - Determines whether the container has finished starting.
  • Readiness probe - Determines whether the container is ready to receive traffic.
  • Liveness probe - Determines whether the container is still functioning correctly.
Probe execution order

On startup, Kubernetes runs probes in the following order:

  1. startupProbe runs until it succeeds, then is disabled.
  2. livenessProbe begins running to detect and recover from failures.
  3. readinessProbe begins running to control traffic routing.

What are static pods?

A static pod is a pod managed directly by the kubelet, without being created by the scheduler.

Unlike regular pods, static pods are not created by submitting a manifest through kubectl to the API server. Instead, their definitions are stored as YAML manifests in a directory watched by the kubelet, typically:

/etc/kubernetes/manifests

The kubelet monitors this directory and automatically creates, updates, or deletes static pods based on the manifests it finds there.

Static pods do not require the API server or scheduler to run. However, the kubelet usually creates a mirror pod in the API server so that the static pod can be observed through tools such as kubectl.

Mirror pod

The mirror pod is only a representation of the static pod, it is not used to manage it.