Appendix A: Command-Line Tools

A reference for the tools the book reaches for repeatedly. Standard Unix utilities (cat, ls, grep, sed, awk, tar, sha256sum) are omitted; the book uses them for plumbing, not as subjects.

Container Engines And CLIs

docker

A user-facing wrapper over dockerd, which talks to containerd over a Unix socket. Almost everything in this book that uses docker could equally use nerdctl or podman; the syntax is shared by convention, not by spec.

podman

A daemonless, rootless-first container engine. CLI is docker-compatible, so alias docker=podman works for most flows. Without a daemon, every invocation forks runc directly; the container's parent is the calling shell. Rootless storage lives under ~/.local/share/containers/storage/.

nerdctl

containerd's docker-compatible CLI. Same arguments your fingers already know (run -it, exec, logs, pull), but talks directly to containerd without a daemon.

ctr

containerd's native debug CLI. Closer to the gRPC API than nerdctl, less ergonomic, but the right tool when you want to see exactly what containerd is doing.

crictl

The Kubernetes CRI debug CLI. Speaks the same gRPC interface the kubelet uses, so it sees what the kubelet sees.

kubectl

Kubernetes cluster CLI. Talks to kube-apiserver over HTTPS, never directly to a node's runtime — anything touching containerd from a node uses crictl or nerdctl.

buildah

Image-building CLI from the Containers project. Builds OCI images without a daemon and without root, and lets you script the layer-by-layer construction of an image as a sequence of buildah commands instead of a Dockerfile.

skopeo

Image transport tool. Copies, inspects, and verifies images between registries, OCI layouts on disk, Docker daemons, and archive files.

OCI Runtimes

runc

The reference OCI runtime. Reads an OCI bundle (a directory containing config.json and a rootfs/), creates the namespaces and cgroups, applies the security profiles, and execs the user process. Almost every container on Linux runs under runc or a drop-in replacement.

crun

A C reimplementation of runc. Faster startup, lower memory per running container, drop-in compatible. The default runtime in podman.

youki

A Rust reimplementation of the OCI runtime. Less battle-tested than runc or crun but tracks the spec.

Linux Primitive Tools

unshare(1)

User-space wrapper for unshare(2). Creates new namespaces and execs a command inside them.

nsenter(1)

Calls setns(2) on a target namespace and execs a command. The mechanism behind kubectl exec, crictl exec, and docker exec.

lsns(1)

Lists namespaces by walking /proc/*/ns/. The fastest way to figure out which container is using which namespace.

Capabilities, Seccomp, MAC

capsh(1)

libcap's capability-set inspector and launcher. Decodes capability bitmaps and runs commands with chosen sets.

setpriv(1)

Drop privileges before exec. The right tool for testing capability and no_new_privs configurations without writing C.

getcap(8) / setcap(8)

Read and write file capabilities (the security.capability xattr). The mechanism that lets ping work for non-root users by carrying cap_net_raw=ep on the binary.

aa-status(8)

AppArmor status. Confirms the LSM is loaded and lists which profiles are in enforce versus complain mode.

getenforce(8) / setenforce(8) / sestatus(8)

SELinux equivalents. getenforce returns Enforcing, Permissive, or Disabled; sestatus is the verbose form. setenforce 0 is a debugging crutch — useful for ruling SELinux in or out as the cause of a failure, almost never the fix.

ausearch(8)

Searches the kernel audit log. The single most useful tool for diagnosing SELinux denials.

bpftool(8)

Inspects and manipulates eBPF programs and maps. cgroup v2's device control is implemented as an attached BPF program, so bpftool is the only way to see what device policy a container has.

Cgroups And systemd

systemctl(1)

systemd's control CLI.

systemd-run(1)

Launches a transient unit and tracks it under a chosen slice. The convenient way to put a process into a specific cgroup without writing files by hand.

systemd-cgls(1)

Pretty-prints the cgroup tree as systemd has shaped it: slices, scopes, and services in their hierarchy.

Filesystem And Mount

findmnt(8)

Lists mounts as a tree. The right tool for "what propagation type is / set to?" and "what is mounted under /sys/fs/cgroup?"

mount(8) / umount(8)

Front-ends to mount(2) and umount2(2). Relevant invocations:

fuse-overlayfs

Userspace OverlayFS that does not require CAP_SYS_ADMIN for trusted.* xattrs. The fallback rootless container engines use on kernels older than 5.11.

jq

CLI JSON processor. Used throughout the book to walk OCI image manifests, runtime config.json files, and docker inspect output.

Networking

ip(8)

The iproute2 swiss-army knife, replacing every legacy networking utility. Used in nearly every chapter that touches the network namespace.

bridge(8)

iproute2's bridge subcommand. Lists and configures Linux bridges, including FDB entries and VLANs.

ss(8)

Socket statistics. The netstat replacement.

iptables(8) / nft(8)

Netfilter rule management. iptables is legacy; nft is the modern (nftables) interface. Container networking still mostly uses iptables-style rules through compatibility layers.

tcpdump(1)

Packet capture.

conntrack(8)

Inspects the kernel's connection-tracking table, the data structure netfilter NAT relies on. Reach for it when a connection works once and then breaks — a stale conntrack entry is the usual culprit.

Init And Supervision

tini, dumb-init

Tiny init programs designed to run as PID 1 inside a container. They install signal handlers (so SIGTERM from docker stop actually terminates the process tree), forward signals to their child, and reap zombie processes. Without one of these or an equivalent, container shutdown and zombie reaping rely on the application doing the right thing as PID 1.

Where These Are Used

Tool Chapters
docker, podman most chapters
nerdctl 1, 10, 12
ctr 1, 6, 10, 12, 13, 17, 20
crictl 4, 13
kubectl 1, 13
runc throughout
crun, youki 1, 3, 5, 8, 9
skopeo 6
unshare, nsenter, lsns 4, 17, 18
capsh, setpriv, getcap, setcap 7
aa-status, ausearch 7
bpftool 5, 7
systemctl, systemd-run, systemd-cgls 5
findmnt 4, 17, 18
mount, fuse-overlayfs, jq 6
ip, bridge, iptables, nft, tcpdump, conntrack, ss 14, 15, 16, 19
tini, dumb-init 4