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:
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:
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:
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:
If the pod contains multiple containers, specify the target container with -c:
E.g.:
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:
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:
startupProberuns until it succeeds, then is disabled.livenessProbebegins running to detect and recover from failures.readinessProbebegins 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:
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.