Guide Linux Advanced

Linux for DevOps

How the previous 15 Linux fundamentals directly power containers, Kubernetes, CI/CD, and infrastructure automation — the concepts that actually show up on the job.

4 min read

Why Every DevOps Engineer Needs Real Linux Fundamentals

Docker, Kubernetes, Terraform, and CI/CD runners are not separate from Linux — they’re built directly on top of the kernel features covered earlier in this series. A DevOps engineer debugging a “pod stuck in CrashLoopBackOff” or a “container using 100% CPU” is really debugging a Linux process, using Linux tools, on a Linux host.

flowchart TB K8S[Kubernetes] --> DOCKER[Container Runtime] DOCKER --> NS[Linux Namespaces: isolation] DOCKER --> CG[Linux cgroups: resource limits] DOCKER --> OVL[OverlayFS: layered images] NS --> KERNEL[Linux Kernel] CG --> KERNEL OVL --> KERNEL

Containers Are Linux Processes

A “container” is just a regular Linux process with extra isolation, using two kernel features:

  • Namespaces — isolate what a process can see: its own PID tree, network interfaces, mount points, and hostname (pid, net, mnt, uts, ipc, user namespaces).
  • cgroups (control groups) — limit what a process can use: CPU shares, memory limits, I/O bandwidth.
# Prove a container is just a host process with namespaces
docker run -d --name web nginx
docker inspect --format '{{.State.Pid}}' web
ps -ef | grep $(docker inspect --format '{{.State.Pid}}' web)   # visible from the HOST too

# Inspect its cgroup memory limit directly
cat /sys/fs/cgroup/memory/docker/$(docker inspect --format '{{.Id}}' web)/memory.limit_in_bytes

Mapping Fundamentals to Real DevOps Tasks

FundamentalWhere It Shows Up in DevOps Work
Processes & signalsKubernetes sends SIGTERM then waits terminationGracePeriodSeconds before SIGKILL on pod shutdown
Filesystem & mountsKubernetes Volumes/PVCs are just bind-mounts and network filesystems under the hood
Permissions & usersContainer runAsUser/runAsNonRoot securityContext maps directly to Linux UID/GID
NetworkingKubernetes Services/iptables/IPVS rules, CNI plugins configuring routes and interfaces
systemdThe container runtime (containerd, docker) and kubelet themselves run as systemd services on the node
Logskubectl logs reads the container’s stdout/stderr, which the runtime redirects to files the kubelet tails
Kernel/cgroupsPod CPU/memory requests/limits are implemented as cgroup settings on the node

A Real Debugging Flow: “Pod OOMKilled”

kubectl describe pod myapp-xyz | grep -A5 "Last State"
# Reason: OOMKilled

# On the NODE itself (this is where Linux fundamentals matter):
dmesg -T | grep -i "killed process"     # kernel OOM killer log entry
cat /sys/fs/cgroup/memory/.../memory.limit_in_bytes   # confirm the cgroup limit that was hit
journalctl -u kubelet --since "10 min ago"

This is a kernel-level event (the OOM killer, part of the memory management subsystem covered in the Kernel article) surfaced through Kubernetes — you can’t fully explain it without the underlying Linux concept.

CI/CD Runners Are Just Linux Boxes

# A typical CI job step is executing exactly like an interactive shell would:
#!/usr/bin/env bash
set -euo pipefail
whoami                  # what user is this running as? (often a restricted service account)
env | sort               # what environment variables are actually visible?
df -h                     # is the runner's disk full? (a common flaky-CI cause)
ulimit -a                  # file descriptor / process limits on this runner

Most “flaky CI” issues trace back to Linux fundamentals: disk full (df -h), too many open files (ulimit -n), zombie build processes not reaped, or environment variables missing because a non-login shell doesn’t source .bashrc.

Production Considerations

  • Always set resources.requests/resources.limits in Kubernetes manifests — under the hood these are cgroup settings, and without them a single pod can starve others on the same node.
  • securityContext.runAsNonRoot: true is a real Linux UID check, not a Kubernetes abstraction — pair it with an image that actually has a non-root user created.
  • When a container “hangs” on shutdown, check whether your entrypoint process correctly handles SIGTERM — many app frameworks need explicit signal handling or tini/dumb-init as PID 1.

Quick Interview Answer

“Containers aren’t a separate technology from Linux — they’re regular processes isolated with namespaces and constrained with cgroups. That’s why real Linux fundamentals — signals, processes, cgroups, filesystems, users/permissions — directly explain Kubernetes behavior: OOMKilled is the kernel’s OOM killer, pod termination is SIGTERM/SIGKILL, resource requests/limits are cgroup settings, and runAsNonRoot is a plain Linux UID check.”

Common Mistakes

  • Treating Kubernetes/Docker concepts as entirely separate from Linux instead of as a layer built directly on kernel primitives — this shows up as an inability to explain why something happens, only that it happens.
  • Debugging OOMKilled pods purely from kubectl output without checking the node’s dmesg/kernel logs for the actual OOM killer event.
  • Not testing signal handling (SIGTERM) in an application’s entrypoint, leading to slow or forceful (SIGKILL) container termination in production.

Add More Questions to This Guide

Know a question that should be here? Share it and help the community!

Open Google Form