/containers-internals
Linux containers internals skill for namespaces, cgroups, and OCI. Use when understanding clone/unshare namespaces, cgroups v2 limits, overlayfs, runc, seccomp profiles, capabilities, or escape mitigations. Activates on queries about namespaces, cgroups, overlayfs, runc,
$ npx -y skills add mohitmishra786/low-level-dev-skills --skill containers-internals --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/containers-internals
Context preview
The summary Claude sees to decide when to auto-load this skill.
Linux containers internals skill for namespaces, cgroups, and OCI. Use when understanding clone/unshare namespaces, cgroups v2 limits, overlayfs, runc, seccomp profiles, capabilities, or escape mitigations. Activates on queries about namespaces, cgroups, overlayfs, runc,
SKILL.md
containers-internals.SKILL.mdname: containers-internals
description: Linux containers internals skill for namespaces, cgroups, and OCI. Use when understanding clone/unshare namespaces, cgroups v2 limits, overlayfs, runc, seccomp profiles, capabilities, or escape mitigations. Activates on queries about namespaces, cgroups, overlayfs, runc, seccomp-bpf, OCI spec, or container escape.
Containers Internals
Purpose
Guide agents through Linux container internals: namespaces (`clone`, `unshare`, `nsenter`), cgroups v2 resource limits, overlayfs storage, runc and the OCI runtime spec, seccomp-bpf filtering, Linux capabilities for privilege dropping, and container escape mitigations.
When to Use
- Understanding how Docker/Podman isolate processes under the hood
- Debugging container resource limits (OOM, CPU throttling)
- Writing custom seccomp profiles for sandboxed workloads
- Building minimal containers without Docker
- Investigating container escape vulnerabilities
- Tuning cgroups v2 for Kubernetes pods
Workflow
1. Namespaces
# List namespaces for a process
ls -la /proc/self/ns/
readlink /proc/self/ns/pid
readlink /proc/1234/ns/net
# Enter container namespaces
nsenter -t <pid> -m -u -i -n -p bash
# Unshare namespaces (manual container)
unshare --fork --mount-proc --pid --net --uts --ipc bash
| Namespace | Isolates | |-----------|----------| | `CLONE_NEWNS` (mount) | Mount points, filesystem roots | | `CLONE_NEWPID` | Process IDs | | `CLONE_NEWNET` | Network stack | | `CLONE_NEWUTS` | Hostname | | `CLONE_NEWIPC` | SysV IPC, POSIX message queues | | `CLONE_NEWUSER` | UID/GID mappings | | `CLONE_NEWCGROUP` | cgroup root view |
// clone() with namespaces
#define _GNU_SOURCE
#include <sched.h>
int container_init(void *arg) {
sethostname("container", 9);
mount("proc", "/proc", "proc", 0, NULL);
execv("/bin/sh", (char *[]){"/bin/sh", NULL});
return 1;
}
int stack[1024 * 1024];
clone(container_init, stack + sizeof(stack)/sizeof(int),
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD, NULL);2. cgroups v2
# Unified hierarchy (cgroup v2)
mount -t cgroup2 none /sys/fs/cgroup
# Create cgroup and set limits
mkdir /sys/fs/cgroup/mycontainer
echo $$ > /sys/fs/cgroup/mycontainer/cgroup.procs
# Memory limit 256MB
echo 256M > /sys/fs/cgroup/mycontainer/memory.max
# CPU weight (relative to siblings, default 100)
echo 50 > /sys/fs/cgroup/mycontainer/cpu.weight
# IO weight
echo default 100 > /sys/fs/cgroup/mycontainer/io.weight
# Check current cgroup
cat /proc/self/cgroup
# OOM events
cat /sys/fs/cgroup/mycontainer/memory.events
3. overlayfs
overlayfs layers
├── lowerdir (read-only image layers)
├── upperdir (container writes)
├── workdir (internal bookkeeping)
└── merged (mount point seen by container)
mount -t overlay overlay \
-o lowerdir=lower1:lower2,upperdir=upper,workdir=work \
merged
# Docker stores layers in /var/lib/docker/overlay2/
Copy-on-write: reads from lower, writes go to upper.
4. runc and OCI spec
# Generate default OCI config
mkdir -p mycontainer/rootfs
runc spec
# Edit config.json — namespaces, mounts, process args
# Run container
sudo runc run mycontainer
# List
runc list
`config.json` key sections:
{
"ociVersion": "1.0.2",
"process": {
"args": ["/bin/sh"],
"capabilities": { "bounding": ["CAP_NET_BIND_SERVICE"] }
},
"linux": {
"namespaces": [
{"type": "pid"}, {"type": "network"}, {"type": "mount"}
],
"seccomp": { ... },
"resources": {
"memory": { "limit": 268435456 }
}
},
"root": { "path": "rootfs", "readonly": false }
}5. seccomp-bpf
// libseccomp example — block mount
#include <seccomp.h>
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mount), 0);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(pivot_root), 0);
seccomp_load(ctx);
# Docker default seccomp profile (JSON)
# https://github.com/moby/moby/blob/master/profiles/seccomp/default.json
# Audit blocked syscalls
# kernel: seccomp log via auditd
ausearch -m SECCOMP
| Action | Effect | |--------|--------| | `SCMP_ACT_KILL` | Kill process | | `SCMP_ACT_ERRNO(n)` | Return error | | `SCMP_ACT_TRACE` | Notify tracer | | `SCMP_ACT_ALLOW` | Permit syscall |
6. Linux capabilities
# Drop all caps except needed
capsh --drop=all --add=net_bind_service -- -c '/app/server'
# File capabilities
setcap cap_net_bind_service+ep /usr/bin/myserver
getcap /usr/bin/myserver
In containers: default Docker drops `CAP_SYS_ADMIN`, `CAP_NET_RAW`, etc. Run as non-root with minimal bounding set.
7. User namespace rootless
# Rootless podman/docker maps root in container to unprivileged UID on host
cat /proc/self/uid_map
# 0 1000 1
# container UID 0 → host UID 1000
Rootless limits: cannot mount most filesystems, no `CAP_SYS_ADMIN`.
8. Escape mitigations
Defense layers
├── User namespace (rootless)
├── seccomp (block dangerous syscalls)
├── AppArmor/SELinux (MAC)
├── Capabilities drop (--cap-drop=ALL)
├── Read-only rootfs
├── no-new-privileges
└── Seccomp + Landlock for filesystem
docker run --read-only --cap-drop=ALL --security-opt=no-new-privileges \
--security-opt seccomp=default.json myimage
Known escape vectors: mounted docker.sock, privileged mode, kernel CVEs, `/proc` leaks.
Common Problems
| Symptom | Cause | Fix | |---------|-------|-----| | Container OOMKilled | memory.max exceeded | Raise limit or fix leak | | CPU throttled | cpu.max quota low | Adjust `cpu.max` or weight | | Permission denied in container | Capability dropped | Add specific cap or fix app | | seccomp kill on start | Missing syscall in profile | `strace` to find; allow syscall | | overlay mount fail | workdir not empty | Clean workdir; check permissions | | Rootless mount fail | User namespace limi
Read more
name: containers-internals description: Linux containers internals skill for namespaces, cgroups, and OCI. Use when understanding clone/unshare namespaces, cgroups v2 limits, overlayfs, runc, seccomp profiles, capabilities, or escape mitigations. Activates on queries about namespaces, cgroups, overlayfs, runc, seccomp-bpf, OCI spec, or container escape.
Containers Internals
Purpose
Guide agents through Linux container internals: namespaces (`clone`, `unshare`, `nsenter`), cgroups v2 resource limits, overlayfs storage, runc and the OCI runtime spec, seccomp-bpf filtering, Linux capabilities for privilege dropping, and container escape mitigations.
When to Use
- Understanding how Docker/Podman isolate processes under the hood
- Debugging container resource limits (OOM, CPU throttling)
- Writing custom seccomp profiles for sandboxed workloads
- Building minimal containers without Docker
- Investigating container escape vulnerabilities
- Tuning cgroups v2 for Kubernetes pods
Workflow
1. Namespaces
# List namespaces for a process ls -la /proc/self/ns/ readlink /proc/self/ns/pid readlink /proc/1234/ns/net # Enter container namespaces nsenter -t <pid> -m -u -i -n -p bash # Unshare namespaces (manual container) unshare --fork --mount-proc --pid --net --uts --ipc bash
| Namespace | Isolates | |-----------|----------| | `CLONE_NEWNS` (mount) | Mount points, filesystem roots | | `CLONE_NEWPID` | Process IDs | | `CLONE_NEWNET` | Network stack | | `CLONE_NEWUTS` | Hostname | | `CLONE_NEWIPC` | SysV IPC, POSIX message queues | | `CLONE_NEWUSER` | UID/GID mappings | | `CLONE_NEWCGROUP` | cgroup root view |
// clone() with namespaces
#define _GNU_SOURCE
#include <sched.h>
int container_init(void *arg) {
sethostname("container", 9);
mount("proc", "/proc", "proc", 0, NULL);
execv("/bin/sh", (char *[]){"/bin/sh", NULL});
return 1;
}
int stack[1024 * 1024];
clone(container_init, stack + sizeof(stack)/sizeof(int),
CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD, NULL);2. cgroups v2
# Unified hierarchy (cgroup v2) mount -t cgroup2 none /sys/fs/cgroup # Create cgroup and set limits mkdir /sys/fs/cgroup/mycontainer echo $$ > /sys/fs/cgroup/mycontainer/cgroup.procs # Memory limit 256MB echo 256M > /sys/fs/cgroup/mycontainer/memory.max # CPU weight (relative to siblings, default 100) echo 50 > /sys/fs/cgroup/mycontainer/cpu.weight # IO weight echo default 100 > /sys/fs/cgroup/mycontainer/io.weight
# Check current cgroup cat /proc/self/cgroup # OOM events cat /sys/fs/cgroup/mycontainer/memory.events
3. overlayfs
overlayfs layers ├── lowerdir (read-only image layers) ├── upperdir (container writes) ├── workdir (internal bookkeeping) └── merged (mount point seen by container)
mount -t overlay overlay \ -o lowerdir=lower1:lower2,upperdir=upper,workdir=work \ merged # Docker stores layers in /var/lib/docker/overlay2/
Copy-on-write: reads from lower, writes go to upper.
4. runc and OCI spec
# Generate default OCI config mkdir -p mycontainer/rootfs runc spec # Edit config.json — namespaces, mounts, process args # Run container sudo runc run mycontainer # List runc list
`config.json` key sections:
{
"ociVersion": "1.0.2",
"process": {
"args": ["/bin/sh"],
"capabilities": { "bounding": ["CAP_NET_BIND_SERVICE"] }
},
"linux": {
"namespaces": [
{"type": "pid"}, {"type": "network"}, {"type": "mount"}
],
"seccomp": { ... },
"resources": {
"memory": { "limit": 268435456 }
}
},
"root": { "path": "rootfs", "readonly": false }
}5. seccomp-bpf
// libseccomp example — block mount #include <seccomp.h> scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW); seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mount), 0); seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(pivot_root), 0); seccomp_load(ctx);
# Docker default seccomp profile (JSON) # https://github.com/moby/moby/blob/master/profiles/seccomp/default.json # Audit blocked syscalls # kernel: seccomp log via auditd ausearch -m SECCOMP
| Action | Effect | |--------|--------| | `SCMP_ACT_KILL` | Kill process | | `SCMP_ACT_ERRNO(n)` | Return error | | `SCMP_ACT_TRACE` | Notify tracer | | `SCMP_ACT_ALLOW` | Permit syscall |
6. Linux capabilities
# Drop all caps except needed capsh --drop=all --add=net_bind_service -- -c '/app/server' # File capabilities setcap cap_net_bind_service+ep /usr/bin/myserver getcap /usr/bin/myserver
In containers: default Docker drops `CAP_SYS_ADMIN`, `CAP_NET_RAW`, etc. Run as non-root with minimal bounding set.
7. User namespace rootless
# Rootless podman/docker maps root in container to unprivileged UID on host cat /proc/self/uid_map # 0 1000 1 # container UID 0 → host UID 1000
Rootless limits: cannot mount most filesystems, no `CAP_SYS_ADMIN`.
8. Escape mitigations
Defense layers ├── User namespace (rootless) ├── seccomp (block dangerous syscalls) ├── AppArmor/SELinux (MAC) ├── Capabilities drop (--cap-drop=ALL) ├── Read-only rootfs ├── no-new-privileges └── Seccomp + Landlock for filesystem
docker run --read-only --cap-drop=ALL --security-opt=no-new-privileges \ --security-opt seccomp=default.json myimage
Known escape vectors: mounted docker.sock, privileged mode, kernel CVEs, `/proc` leaks.
Common Problems
| Symptom | Cause | Fix | |---------|-------|-----| | Container OOMKilled | memory.max exceeded | Raise limit or fix leak | | CPU throttled | cpu.max quota low | Adjust `cpu.max` or weight | | Permission denied in container | Capability dropped | Add specific cap or fix app | | seccomp kill on start | Missing syscall in profile | `strace` to find; allow syscall | | overlay mount fail | workdir not empty | Clean workdir; check permissions | | Rootless mount fail | User namespace limi
A curated suite of AI agent skills for systems and low-level programming — C/C++, Rust, Zig, GPU, bare-metal firmware, Linux kernel/driver development, computer architecture, compiler internals, HPC, and more.
Repo: mohitmishra786/low-level-dev-skills
Other skills on low-level-dev-skills.
- /custom-allocators
Custom allocator skill for memory allocation strategies. Use when implementing pool/slab/arena allocators, tuning jemalloc/mimalloc, writing Rust GlobalAlloc, or benchmarking allocator performance. Activates on queries about jemalloc, mimalloc, tcmalloc, arena allocator,
Open skill - /numa-programming
NUMA programming skill for multi-socket memory locality. Use when detecting NUMA topology, binding processes with numactl, using libnuma API, building NUMA-aware data structures, or measuring remote access penalties. Activates on queries about numactl, libnuma, NUMA topology,
Open skill - /af-xdp
AF_XDP skill for high-performance XDP sockets. Use when creating AF_XDP sockets, configuring UMEM and XSK rings, XDP_REDIRECT programs, copy vs zero-copy mode, or comparing with DPDK. Activates on queries about AF_XDP, xsk_umem, XDP_REDIRECT, libbpf xsk, or zero-copy XDP.
Open skill - /dpdk
DPDK skill for userspace packet I/O. Use when initializing EAL, configuring PMD drivers, using mbuf pools and rte_ring, setting up huge pages, RSS, or testpmd validation. Activates on queries about DPDK, EAL, rte_eth_rx_burst, hugepages, PMD, or testpmd.
Open skill - /io-uring
io_uring skill for Linux async I/O. Use when building high-performance servers with liburing, multi-shot operations, provided buffers, fixed files, zero-copy send, or tokio-uring. Activates on queries about io_uring, SQE/CQE, liburing, IORING_OP_PROVIDE_BUFFERS, or io_uring vs
Open skill - /adc-dac-baremetal
Bare-metal ADC and DAC skill. Use when configuring analog sampling, DMA-driven ADC, calibration, or DAC output on MCUs. Activates on queries about ADC bare-metal, sampling time, DMA ADC, or DAC channel setup.
Open skill

