Kubernetes Pods and Containers
Kubernetes Pods and Containers are fundamental building blocks for deploying and managing applications in a scalable and resilient containerized environment.
Kubernetes Pods and Containers describes the smallest deployable and manageable unit in Kubernetes, the Pod, and its relationship to the containers it wraps. A Pod is a thin, shared execution context around one or more containers that are deployed, scheduled, and scaled together as a single unit, guaranteeing that its constituent containers always run on the same node and can cooperate through shared network and storage resources.
The Pod Abstraction
Why Kubernetes Does Not Schedule Bare Containers
Kubernetes schedules Pods rather than individual containers because many real workloads consist of tightly coupled processes that must run together, such as a main application container and a logging sidecar. Wrapping these in a single schedulable unit guarantees co-location, avoids the complexity of coordinating placement across separately scheduled containers, and gives the group a single lifecycle and IP address.
Shared Execution Context
All containers within a Pod share:
- Network namespace: Every container in a Pod shares a single IP address and port space, and can reach each other over
localhost. - IPC namespace: Containers can communicate using standard inter-process communication mechanisms as if they were processes on the same machine.
- Storage volumes: Volumes defined at the Pod level can be mounted into any of its containers, enabling data sharing between them.
Containers within a Pod do not share a process ID namespace or filesystem by default, preserving isolation between them even while sharing network and storage.
Container Types Within a Pod
Application Containers
The primary containers of a Pod run the main application logic. A Pod may contain a single application container, the most common case, or several that need to operate closely together.
Init Containers
Init containers run to completion, in order, before any application container in the Pod starts. They are commonly used to perform setup tasks, such as waiting for a dependency to become available or populating a shared volume, that must finish before the main application begins.
spec:
initContainers:
- name: wait-for-db
image: busybox:1.36
command: ["sh", "-c", "until nc -z db-service 5432; do sleep 2; done"]
containers:
- name: app
image: codartium/app:1.0.0
Sidecar Containers
Sidecar containers run alongside the main application container for the entire lifetime of the Pod, commonly providing cross-cutting functionality such as log shipping, metrics collection, or service mesh proxying, without embedding that logic into the application image itself.
Pod Specification
apiVersion: v1
kind: Pod
metadata:
name: codartium-analyzer
labels:
app: codartium-analyzer
spec:
containers:
- name: analyzer
image: codartium/analyzer:3.2.0
ports:
- containerPort: 9090
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "300m"
memory: "256Mi"
volumeMounts:
- name: cache
mountPath: /var/cache/analyzer
volumes:
- name: cache
emptyDir: {}
restartPolicy: Always
Pod Lifecycle
Phases
A Pod progresses through a sequence of phases reported in its status.phase field: Pending, while the Pod is accepted but its containers are not yet running; Running, once at least one container is running; Succeeded or Failed, once all containers have terminated; and Unknown, if the Pod's state cannot be determined, typically due to a communication failure with its node.
Restart Policy
The restartPolicy field, Always, OnFailure, or Never, governs whether the kubelet restarts containers within the Pod after they exit, and is a key factor distinguishing long-running service Pods from batch or run-to-completion Pods.
Pod Disposability
Pods are treated as ephemeral and disposable. They are not migrated between nodes; if a node fails or a Pod is deleted, a new Pod with a new identity and, typically, a new IP address is created in its place by the relevant controller. Applications running in Pods must therefore be designed to tolerate replacement rather than relying on any individual Pod's persistence.
Container Images and Pull Policy
Each container in a Pod specifies an image reference, typically including a registry, repository, and tag or digest. The imagePullPolicy field determines whether the kubelet always pulls the latest image, pulls only if the image is not already present locally, or never pulls, which affects both startup latency and the guarantee that a given tag always resolves to the same content.
kubectl run codartium-debug --image=busybox:1.36 --restart=Never -- sleep 3600
kubectl exec -it codartium-debug -- sh
kubectl logs codartium-analyzer -c analyzer
Multi-Container Coordination
Because containers in a Pod share network and storage but remain independently defined, patterns such as the sidecar, ambassador, and adapter emerge naturally: a sidecar extends or monitors the main container, an ambassador proxies outbound connections on its behalf, and an adapter normalizes its output for external consumption, all without modifying the main container's image.