How Pods Really Work: Inside Containers, Namespaces, and cgroups
This article explores the inner workings of Kubernetes Pods by examining how containers share network, IPC, mount, and PID namespaces, how cgroups enforce resource limits, and how similar behavior can be reproduced with Docker, providing hands‑on examples and code snippets for deeper understanding.
When you first learn Kubernetes you are told that each Pod has a unique IP and hostname and that containers in the same Pod can communicate via localhost, making a Pod look like a tiny server.
Later you discover that each container has an isolated filesystem and cannot see the processes of its siblings, so a Pod is really a group of containers sharing a network stack.
Further investigation shows that containers can also share memory, so network namespace is not the only shared resource.
Exploring Containers
The OCI runtime spec does not limit containers to Linux containers, but in this article "container" refers to the traditional namespace and cgroup based implementation.
Setting up a playground
$ cat > Vagrantfile <<EOF
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "debian/buster64"
config.vm.hostname = "docker-host"
config.vm.define "docker-host"
config.vagrant.plugins = ['vagrant-vbguest']
config.vm.provider "virtualbox" do |vb|
vb.cpus = 2
vb.memory = "2048"
end
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y curl vim
SHELL
config.vm.provision "docker"
end
EOF
$ vagrant up
$ vagrant sshStart a container:
$ docker run --name foo --rm -d --memory='512MB' --cpus='0.5' nginxExploring container namespaces
After starting a container, the following isolation primitives are created:
# Look up the container in the process tree.
$ ps auxf
... (output omitted) ...
# Find the namespaces used by the process.
$ sudo lsns
NS TYPE NPROCS PID USER COMMAND
4026532157 mnt 3 4727 root nginx: master process nginx -g daemon off;
4026532158 uts 3 4727 root nginx: master process nginx -g daemon off;
4026532159 ipc 3 4727 root nginx: master process nginx -g daemon off;
4026532160 pid 3 4727 root nginx: master process nginx -g daemon off;
4026532162 net 3 4727 root nginx: master process nginx -g daemon off;The namespaces used are mount, uts, ipc, pid, and net. The user namespace is not used by default.
Cgroup namespaces are separate; they provide an isolated view of the cgroup hierarchy. You can inspect them with:
PID=$(docker inspect --format '{{.State.Pid}}' foo)
$ cat /proc/${PID}/cgroup
11:freezer:/docker/…
10:blkio:/docker/…
9:rdma:/
8:pids:/docker/…
7:devices:/docker/…
6:cpuset:/docker/…
5:cpu,cpuacct:/docker/…
4:memory:/docker/…
3:net_cls,net_prio:/docker/…
2:perf_event:/docker/…
1:name=systemd:/docker/…
0::/system.slice/containerd.serviceChecking resource limits:
ID=$(docker inspect --format '{{.Id}}' foo)
$ cat /sys/fs/cgroup/memory/docker/${ID}/memory.limit_in_bytes
536870912
$ ls /sys/fs/cgroup/cpu/docker/${ID}Exploring Pods
Pods run on a Kubernetes cluster using a CRI runtime such as containerd/runc. The pause container acts as the sandbox that holds shared resources.
Setting up a playground
# Install arkade and start minikube with containerd
$ curl -sLS https://get.arkade.dev | sh
$ arkade get kubectl minikube
$ minikube start --driver virtualbox --container-runtime containerdCreate a Pod with two containers:
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: app
image: docker.io/kennethreitz/httpbin
ports:
- containerPort: 80
resources:
limits:
memory: "256Mi"
- name: sidecar
image: curlimages/curl
command: ["/bin/sleep", "3650d"]
resources:
limits:
memory: "128Mi"Inspecting the Pod on the node shows the pause container and the two application containers sharing the network, UTS, and IPC namespaces:
$ sudo lsns
NS TYPE NPROCS PID USER COMMAND
4026532614 net 4 4966 root /pause
4026532715 mnt 1 4966 root /pause
4026532716 uts 4 4966 root /pause
4026532717 ipc 4 4966 root /pause
4026532718 pid 1 4966 root /pause
...Using crictl inspect confirms that the app and sidecar containers reuse the pause container's net, uts, and ipc namespaces.
The CRI API allows explicit control over namespace sharing (CONTAINER, POD, NODE) and flags such as shareProcessNamespace, hostIPC, hostNetwork, and hostPID can expose host namespaces.
Exploring Pod cgroups
Systemd visualises the cgroup hierarchy for the Pod:
$ sudo systemd-cgls
Control group /:
├─kubepods
│ ├─burstable
│ │ ├─pod…
│ │ │ ├─f0e87a933046… /pause
│ │ │ ├─dfb1cd29ab75… /usr/bin/python3 …gunicorn …
│ │ │ └─097d4fe8a7002… /bin/sleep 3650dImplementing a Pod with Docker
By creating a shared cgroup parent and a sandbox container, Docker can emulate a Pod:
# Create a cgroup for the pod
$ sudo cgcreate -g cpu,memory:/pod-foo
# Start a sandbox container
$ docker run -d --rm \
--name foo_sandbox \
--cgroup-parent /pod-foo \
--ipc 'shareable' \
alpine sleep infinity
# Run containers that reuse the sandbox's network and IPC namespaces
$ docker run -d --rm \
--name app \
--cgroup-parent /pod-foo \
--network container:foo_sandbox \
--ipc container:foo_sandbox \
kennethreitz/httpbin
$ docker run -d --rm \
--name sidecar \
--cgroup-parent /pod-foo \
--network container:foo_sandbox \
--ipc container:foo_sandbox \
curlimages/curl sleep 365dThese containers share the same IPC and network namespaces but cannot share the UTS namespace with Docker’s current options.
Conclusion
Containers and Pods are similar at the implementation level: both rely on Linux namespaces and cgroups. However, a Pod is a higher‑level construct that guarantees co‑location, synchronized lifecycle, and reduced isolation between its containers, enabling patterns such as sidecars and in‑Pod proxies.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
