Cgroups_namespaces
Chapter 83: cgroups and Namespaces
Section titled “Chapter 83: cgroups and Namespaces”Linux Resource Isolation and Virtualization
Section titled “Linux Resource Isolation and Virtualization”83.1 Understanding cgroups
Section titled “83.1 Understanding cgroups”What are cgroups?
Section titled “What are cgroups?”Control groups (cgroups) are a Linux kernel feature that allows processes to be organized into hierarchical groups and have resource limits, accounting, and isolation applied to them. Cgroups are the foundation for containerization technologies like Docker and system services managed by systemd.
┌────────────────────────────────────────────────────────────────────────┐│ CGROUPS ARCHITECTURE │├────────────────────────────────────────────────────────────────────────┤│ ││ ┌──────────────────────────────────────────────────────────────────┐ ││ │ LINUX KERNEL │ ││ │ │ ││ │ ┌──────────────────────────────────────────────────────────┐ │ ││ │ │ cgroup v2 (unified hierarchy) │ │ ││ │ │ │ │ ││ │ │ /sys/fs/cgroup/ │ │ ││ │ │ ├── cgroup.controllers │ │ ││ │ │ ├── cgroup.subtree_control │ │ ││ │ │ ├── cgroup.procs │ │ ││ │ │ │ │ │ ││ │ │ ├── system.slice/ │ │ ││ │ │ │ ├──.slice/ │ │ ││ │ │ │ └── user.slice/ │ │ ││ │ │ │ │ │ ││ │ │ ├── docker/ │ │ ││ │ │ │ └── abc123.../ │ │ ││ │ │ │ │ │ ││ │ │ └── mygroup/ │ │ ││ │ │ ├── cgroup.procs │ │ ││ │ │ ├── cpu.max │ │ ││ │ │ ├── memory.max │ │ ││ │ │ └── io.max │ │ ││ │ └──────────────────────────────────────────────────────────┘ │ ││ └──────────────────────────────────────────────────────────────────┘ ││ ││ User Space ││ ┌──────────────────────────────────────────────────────────────────┐ ││ │ systemd, Docker, containerd, runc, cgcreate, cgset │ ││ └──────────────────────────────────────────────────────────────────┘ ││ │└────────────────────────────────────────────────────────────────────────┘Cgroup v1 vs v2
Section titled “Cgroup v1 vs v2”| Feature | cgroup v1 | cgroup v2 |
|---|---|---|
| Hierarchy | Multiple separate hierarchies | Single unified hierarchy |
| Controllers | Separate controllers | Unified controllers |
| Process Management | Per-controller cgroup.procs | Single cgroup.procs |
| Thread Model | Thread-group level | Process-level |
| Performance | More overhead | Better performance |
| Compatibility | Legacy support | Modern, recommended |
Available Controllers
Section titled “Available Controllers”┌────────────────────────────────────────────────────────────────────────┐│ CGROUP CONTROLLERS │├────────────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────┬──────────────────────────────────────────────────┐ ││ │ Controller │ Purpose │ ││ ├─────────────┼──────────────────────────────────────────────────┤ ││ │ cpu │ CPU time scheduling │ ││ │ cpuacct │ CPU usage accounting │ ││ │ memory │ Memory allocation and usage │ ││ │ io │ Block I/O control │ ││ │ blkio │ Block I/O (v1 legacy) │ ││ │ pids │ Process count limits │ ││ │ devices │ Device access control │ ││ │ net_cls │ Network traffic classification (v1) │ ││ │ net_prio │ Network priority (v1) │ ││ │ perf_event │ Performance monitoring │ ││ │ freezer │ Suspend/resume processes │ ││ │ hugetlb │ Huge pages limits │ ││ │ rdma │ RDMA/IB resources │ ││ └─────────────┴──────────────────────────────────────────────────┘ ││ │└────────────────────────────────────────────────────────────────────────┘83.2 Using cgroups
Section titled “83.2 Using cgroups”Checking cgroup Version
Section titled “Checking cgroup Version”# Check mounted cgroup filesystemsmount | grep cgroup
# Show cgroup versioncat /proc/cgroups
# Check if running v2ls -la /sys/fs/cgroup/# If unified cgroup, shows single directory without controllers
# Check current cgroupcat /proc/self/cgroup
# Check systemd cgroupsystemd-cglsCreating and Managing cgroups (v2)
Section titled “Creating and Managing cgroups (v2)”# Create a new cgroupsudo mkdir -p /sys/fs/cgroup/mylimit
# Add current shell to cgroupecho $$ | sudo tee /sys/fs/cgroup/mylimit/cgroup.procs
# Or add specific processecho <PID> | sudo tee /sys/fs/cgroup/mylimit/cgroup.procs
# List processes in cgroupcat /sys/fs/cgroup/mylimit/cgroup.procs
# Verify cgroup controllerscat /sys/fs/cgroup/mylimit/cgroup.controllers
# Enable controllersecho cpu memory | sudo tee /sys/fs/cgroup/mylimit/cgroup.subtree_control
# Remove cgroup (must be empty)sudo rmdir /sys/fs/cgroup/mylimitCPU Limits
Section titled “CPU Limits”# Set CPU limit (v2) - max microseconds per period# Format: "max period" or "quota period"echo "50000 100000" | sudo tee /sys/fs/cgroup/mylimit/cpu.max# 50000μs out of 100000μs = 50% CPU
# Alternative: Set as percentage (0-10000 = 0-100%)# Not directly available in v2, use cpu.max
# Set CPU weight (relative share)echo 512 | sudo tee /sys/fs/cgroup/mylimit/cpu.weight# Default is 100, range 1-10000
# Check CPU usagecat /sys/fs/cgroup/mylimit/cpu.statMemory Limits
Section titled “Memory Limits”# Set memory limit (hard limit)echo "512M" | sudo tee /sys/fs/cgroup/mylimit/memory.max
# Set memory limit (soft limit, triggers reclaim)echo "256M" | sudo tee /sys/fs/cgroup/mylimit/memory.high
# Disable memory limitsecho "max" | sudo tee /sys/fs/cgroup/mylimit/memory.max
# Check memory usagecat /sys/fs/cgroup/mylimit/memory.currentcat /sys/fs/cgroup/mylimit/memory.stat
# Set swap limit (v2)# Format: "current,max"echo "256M 512M" | sudo tee /sys/fs/cgroup/mylimit/memory.swap.maxI/O Limits
Section titled “I/O Limits”# Set I/O limit (v2)# Format: "device major:minor weight" or "device limit"# Using io.max (absolute limit)echo "8:0 wbps=104857600 rbps=104857600" | sudo tee /sys/fs/cgroup/mylimit/io.max
# Using io.weight (relative)echo "8:0 weight=100" | sudo tee /sys/fs/cgroup/mylimit/io.weight
# Check I/O statisticscat /sys/fs/cgroup/mylimit/io.stat
# List available devicesls /sys/devices/Process Limits
Section titled “Process Limits”# Set max number of processesecho 100 | sudo tee /sys/fs/cgroup/mylimit/pids.max
# Set max recursively (includes children)echo 100 | sudo tee /sys/fs/cgroup/mylimit/pids.max
# Check current process countcat /sys/fs/cgroup/mylimit/pids.current
# Allow root to exceed limitsecho 1 | sudo tee /sys/fs/cgroup/mylimit/pids.allowDevice Access Control
Section titled “Device Access Control”# Allow specific device# Format: "a" for allow, "c" for char, "b" for blockecho "c 1:3 rwm" | sudo tee /sys/fs/cgroup/mylimit/devices.allow# Allow /dev/null
# Deny deviceecho "b 8:0 rwm" | sudo tee /sys/fs/cgroup/mylimit/devices.deny
# List allowed devicescat /sys/fs/cgroup/mylimit/devices.list83.3 Using libcgroup Tools
Section titled “83.3 Using libcgroup Tools”Installation and Basic Usage
Section titled “Installation and Basic Usage”# Install tools (Debian/Ubuntu)sudo apt-get install cgroup-tools
# Install (RHEL/CentOS)sudo yum install libcgroup-tools
# Create cgroup with multiple controllerssudo cgcreate -g cpu,memory,io:/mylimit
# List cgroupsls /sys/fs/cgroup/sudo lscgroupManaging cgroups with Commands
Section titled “Managing cgroups with Commands”# Set CPU limit (cgroup v1)sudo cgset -r cpu.cfs_quota_us=50000 mylimitsudo cgset -r cpu.cfs_period_us=100000 mylimit
# Set memory limitsudo cgset -r memory.limit_in_bytes=512M mylimit
# Set IO limitsudo cgset -r blkio.throttle.write_bps_device="8:0 104857600" mylimit
# Run command in cgroupsudo cgexec -g cpu,memory:mylimit /bin/bash
# Set parameters after creationsudo cgset -r cpu.shares=512 mylimit
# Delete cgroupsudo cgdelete cpu,memory:/mylimit83.4 systemd Integration
Section titled “83.4 systemd Integration”Creating scoped services with limits
Section titled “Creating scoped services with limits”# Run command with memory limit (transient scope)systemd-run --scope -p MemoryMax=512M -p CPUWeight=200 /bin/bash
# Run with CPU limitsystemd-run --scope -p CPUQuota=50% /bin/yes
# Run with multiple limitssystemd-run --scope \ -p MemoryMax=1G \ -p CPUQuota=50% \ -p IOWeight=200 \ -p TasksMax=50 \ /bin/bash
# Check statussystemctl status run-xxxxx.scope
# View resource usagesystemctl show run-xxxxx.scopePermanent cgroups with systemd
Section titled “Permanent cgroups with systemd”# Create drop-in for servicesudo mkdir -p /etc/systemd/system/myservice.service.d
# Add resource limitssudo tee /etc/systemd/system/myservice.service.d/limits.conf << 'EOF'[Service]MemoryMax=1GCPUQuota=50%TasksMax=100IOWeight=200EOF
# Reload and restartsudo systemctl daemon-reloadsudo systemctl restart myservice83.5 Understanding Namespaces
Section titled “83.5 Understanding Namespaces”What are Namespaces?
Section titled “What are Namespaces?”Namespaces partition kernel resources so that each namespace appears to have its own isolated instance of that resource. This provides isolation between processes, enabling containers to have their own view of system resources.
┌────────────────────────────────────────────────────────────────────────┐│ NAMESPACES ARCHITECTURE │├────────────────────────────────────────────────────────────────────────┤│ ││ Each namespace type wraps/isolates specific kernel resources: ││ ││ ┌─────────────────────────────────────────────────────────────────┐ ││ │ Host System │ ││ │ │ ││ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ ││ │ │ PID Namespace │ │ Net Namespace │ │ Mount NS │ │ ││ │ │ │ │ │ │ │ │ ││ │ │ PID 1 │ │ eth0 │ │ / │ │ ││ │ │ PID 2 │ │ lo │ │ /proc │ │ ││ │ │ PID 3 │ │ /etc/net │ │ /sys │ │ ││ │ │ ... │ │ ... │ │ ... │ │ ││ │ └──────────────┘ └──────────────┘ └──────────────┘ │ ││ │ │ ││ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ ││ │ │ User NS │ │ IPC Namespace│ │ UTS Namespace│ │ ││ │ │ │ │ │ │ │ │ ││ │ │ UID 0 │ │ mqueue │ │ hostname │ │ ││ │ │ GID 0 │ │ shm │ │ domain │ │ ││ │ │ capabilities │ │ semaphores │ │ │ │ ││ │ └──────────────┘ └──────────────┘ └──────────────┘ │ ││ │ │ ││ └─────────────────────────────────────────────────────────────────┘ ││ ││ Container Process: ││ ┌─────────────────────────────────────────────────────────────────┐ ││ │ Sees its own PID 1, network stack, mount points, etc. │ ││ │ Can be UID 0 inside while UID is 1000 on host │ ││ └─────────────────────────────────────────────────────────────────┘ ││ │└────────────────────────────────────────────────────────────────────────┘Namespace Types
Section titled “Namespace Types”| Namespace | Flag | Isolates | Use Case |
|---|---|---|---|
| PID | CLONE_NEWPID | Process IDs | Process isolation |
| Network | CLONE_NEWNET | Network devices, stacks | Container networking |
| Mount | CLONE_NEWNS | Mount points | Filesystem isolation |
| User | CLONE_NEWUSER | UIDs, GIDs, capabilities | Unprivileged containers |
| IPC | CLONE_NEWIPC | POSIX message queues, shared memory | Process communication |
| UTS | CLONE_NEWUTS | Hostname, domain name | Container isolation |
| Time | CLONE_NEWTIME | System time | Virtualization |
83.6 Using Namespaces
Section titled “83.6 Using Namespaces”Creating Namespaces
Section titled “Creating Namespaces”# Create new PID namespacesudo unshare --pid --fork --mount-proc /bin/bash
# Create network namespacesudo ip netns add mynetip netns list
# Execute in network namespacesudo ip netns exec mynet /bin/baship link show
# Create mount namespacesudo unshare --mount /bin/bash# Mount changes now isolated
# Create user namespaceunshare --user /bin/bash# Now running as UID mapping
# Create UTS namespacesudo unshare --uts /bin/bashhostname container-host
# Create IPC namespacesudo unshare --ipc /bin/bash
# Combine namespacessudo unshare --pid --mount --net --user /bin/bash
# Create all namespacesunshare --allWorking with Network Namespaces
Section titled “Working with Network Namespaces”# List network namespacesip netns list
# Add network namespacesudo ip netns add websudo ip netns add db
# Execute commands in namespacesudo ip netns exec web ip linksudo ip netns exec web ping 8.8.8.8
# Create virtual ethernet pairsudo ip link add veth0 type veth peer name veth1
# Move one end to namespacesudo ip link set veth1 netns web
# Configure in namespacesudo ip netns exec web ip addr add 10.0.0.2/24 dev veth1sudo ip netns exec web ip link set veth1 up
# Configure in hostip addr add 10.0.0.1/24 dev veth0ip link set veth0 up
# Delete namespacesudo ip netns delete webChecking Namespace IDs
Section titled “Checking Namespace IDs”# View namespace for current processls -la /proc/self/ns/
# View namespaces for specific processls -la /proc/<PID>/ns/
# Check process namespacels -la /proc/self/ns/ | grep -E "pid|net|mnt|user|ipc|uts"
# Read namespace inode to comparestat /proc/self/ns/pid
# Check if processes share namespacels -la /proc/<PID1>/ns/ | /proc/<PID2>/ns/Entering Namespaces
Section titled “Entering Namespaces”# Enter namespace of running process using nsenternsenter -t <PID> -n /bin/bash # Network namespacensenter -t <PID> -m /bin/bash # Mount namespacensenter -t <PID> -p /bin/bash # PID namespacensenter -t <PID> -u /bin/bash # UTS namespacensenter -t <PID> -i /bin/bash # IPC namespacensenter -t <PID> -U /bin/bash # User namespace
# Enter multiplensenter -t <PID> -m -u -i -n -p /bin/bash83.7 Combining cgroups and Namespaces
Section titled “83.7 Combining cgroups and Namespaces”Container from Scratch
Section titled “Container from Scratch”#!/bin/bash# Create isolated container with both cgroups and namespaces
# Create cgroupsudo mkdir -p /sys/fs/cgroup/containerecho 512M | sudo tee /sys/fs/cgroup/container/memory.maxecho 50 | sudo tee /sys/fs/cgroup/container/cpu.weight
# Create cpusetecho "0-1" | sudo tee /sys/fs/cgroup/container/cpuset.cpusecho "0" | sudo tee /sys/fs/cgroup/container/cpuset.mems
# Create network namespacesudo ip netns add container_net
# Create mount namespacesudo unshare --mount --pid --fork --net --user --cgroup /bin/bash << 'CMDS'# Inside containerhostname containerip link set lo upecho "Container running with limits:"cat /sys/fs/cgroup/container/memory.maxcat /sys/fs/cgroup/container/cpu.weight/bin/bashCMDSDocker Integration
Section titled “Docker Integration”Docker uses both cgroups and namespaces:
# Docker automatically creates cgroups and namespacesdocker run -d --name mycontainer nginx
# Check cgroup for containerdocker inspect mycontainer | grep -i cgroup
# Check namespacels -la /proc/$(docker pid mycontainer)/ns/
# Resource limits (cgroups)docker run -d --name limited \ --memory=512m \ --cpus=0.5 \ --cpu-shares=512 \ nginx
# Check limitsdocker stats mycontainer83.8 Practical Examples
Section titled “83.8 Practical Examples”Limiting a Process Resource Usage
Section titled “Limiting a Process Resource Usage”#!/bin/bash# Limit a process using systemd-run
# Memory limitedsystemd-run --scope -p MemoryMax=512M \ -p MemorySwapMax=256M \ /bin/bash -c 'while true; do echo "Running"; sleep 1; done'
# CPU limitedsystemd-run --scope -p CPUQuota=50% \ /bin/bash -c 'while true; do echo $((i++)); done'
# IO limitedsystemd-run --scope -p IOWeight=100 \ /bin/bash -c 'dd if=/dev/zero of=/tmp/test bs=1M count=100'Creating Resource Groups with systemd
Section titled “Creating Resource Groups with systemd”[Unit]Description=Application with Resource Limits
[Service]Type=simpleExecStart=/usr/bin/myappMemoryMax=1GMemoryHigh=512MCPUQuota=50%IOWeight=200TasksMax=50
[Install]WantedBy=multi-user.targetIsolating User Processes
Section titled “Isolating User Processes”#!/bin/bash# Create isolated environment for testing
# Create user namespaceunshare --user --map-root-user /bin/bash
# Or with systemdsystemd-run --user --scope -p MemoryMax=100M /bin/bash
# Check isolationid# Shows UID 0 inside, mapped to actual user outside
# Check /proccat /proc/1/cmdline# Different from host83.9 Troubleshooting
Section titled “83.9 Troubleshooting”Common Issues
Section titled “Common Issues”# cgroup not foundmount -t cgroup2 none /sys/fs/cgroup
# Permission denied with cgroups# Ensure running as root or have proper capabilities
# Namespace operation not permitted# Check kernel capabilitiescapsh --print
# Unshare fails# Check kernel config: CONFIG_*
# Cannot create network namespace# Check iproute2 installed
# cgroup memory limit not working# Ensure using correct cgroup versionDebugging Commands
Section titled “Debugging Commands”# Check cgroup for processcat /proc/<PID>/cgroup
# Check systemd cgroupsystemd-cgls | grep <PID>
# Check namespacels -la /proc/<PID>/ns/
# Check capabilitiescat /proc/<PID>/status | grep Cap
# View cgroup resource usagecat /sys/fs/cgroup/mylimit/memory.statcat /sys/fs/cgroup/mylimit/cpu.stat
# Monitor cgroup eventscgroup_events -m -g /sys/fs/cgroup/mylimit83.10 Interview Questions
Section titled “83.10 Interview Questions”Q1: What is the difference between cgroups and namespaces?
Section titled “Q1: What is the difference between cgroups and namespaces?”Answer:
- cgroups (control groups): Limit and account for resources (CPU, memory, I/O, etc.). They control how much of a resource a process can use.
- Namespaces: Isolate global system resources so processes see different views. They control what resources a process can see/access.
Together they form the foundation of Linux containers - namespaces provide isolation while cgroups provide resource limits.
Q2: What are the different types of namespaces in Linux?
Section titled “Q2: What are the different types of namespaces in Linux?”Answer:
- PID - Process ID isolation (each container has PID 1)
- Network - Network devices, stacks, ports
- Mount - Mount points and filesystems
- User - User and group ID mapping
- IPC - POSIX message queues, shared memory, semaphores
- UTS - Hostname and domain name
- Time - System time (newer)
Q3: How do you limit CPU usage for a process in Linux?
Section titled “Q3: How do you limit CPU usage for a process in Linux?”Answer: Using cgroups v2:
# Create cgroupmkdir /sys/fs/cgroup/limitecho "50000 100000" > /sys/fs/cgroup/limit/cpu.max
# Add processecho <PID> > /sys/fs/cgroup/limit/cgroup.procsOr with systemd:
systemd-run --scope -p CPUQuota=50% /bin/bashQ4: How does Docker use cgroups and namespaces?
Section titled “Q4: How does Docker use cgroups and namespaces?”Answer: When you run a container:
- Docker creates a new cgroup for the container
- Applies resource limits (memory, CPU, etc.) to the cgroup
- Creates namespaces for isolation
- The container process runs inside these cgroup and namespace limits
Each container gets its own cgroup hierarchy and set of namespaces.
Q5: What is the difference between cgroup v1 and v2?
Section titled “Q5: What is the difference between cgroup v1 and v2?”Answer:
- v1: Multiple separate hierarchies per controller, less efficient
- v2: Single unified hierarchy for all controllers, better performance, simpler structure
Most modern systems use v2. You can check with:
mount | grep cgroupls /sys/fs/cgroup/Q6: How do you create a network namespace and configure it?
Section titled “Q6: How do you create a network namespace and configure it?”Answer:
# Create namespacesudo ip netns add mynet
# Add interfacessudo ip link add veth0 type veth peer name veth1sudo ip link set veth1 netns mynet
# Configure in namespacesudo ip netns exec mynet ip addr add 10.0.0.2/24 dev veth1sudo ip netns exec mynet ip link set veth1 upsudo ip netns exec mynet ip link set lo up
# Execute in namespacesudo ip netns exec mynet /bin/bashQ7: What are the security implications of using namespaces?
Section titled “Q7: What are the security implications of using namespaces?”Answer: Namespaces provide isolation but not complete security:
- Not a security boundary by themselves (user namespace is special)
- Need additional security (AppArmor, SELinux, seccomp)
- Container escapes can still occur
- Shared kernel means kernel vulnerabilities affect all containers
Best practice: Use defense in depth - namespaces + cgroups + AppArmor/SELinux + seccomp
Q8: How do you limit memory for a process using cgroups?
Section titled “Q8: How do you limit memory for a process using cgroups?”Answer: Using cgroups v2:
# Create cgroupmkdir /sys/fs/cgroup/limit
# Set memory limitecho 512M > /sys/fs/cgroup/limit/memory.max
# Add processecho <PID> > /sys/fs/cgroup/limit/cgroup.procsOr with systemd:
systemd-run --scope -p MemoryMax=512M /bin/bashQuick Reference
Section titled “Quick Reference”Commands
Section titled “Commands”# Create cgroup (v2)mkdir /sys/fs/cgroup/groupecho $$ > /sys/fs/cgroup/group/cgroup.procs
# Set limitsecho 500M > /sys/fs/cgroup/group/memory.maxecho "50000 100000" > /sys/fs/cgroup/group/cpu.max
# Using systemdsystemd-run --scope -p MemoryMax=512M -p CPUQuota=50%
# Create namespacesunshare --pid --fork /bin/baship netns add mynet
# Enter namespacensenter -t <PID> -n /bin/bashKey Files
Section titled “Key Files”| Path | Purpose |
|---|---|
| /sys/fs/cgroup/ | cgroup v2 mount |
| /proc/self/cgroup | Process cgroup membership |
| /proc/self/ns/ | Process namespaces |
| /sys/fs/cgroup/…/cgroup.procs | Processes in cgroup |
| /sys/fs/cgroup/…/cgroup.controllers | Available controllers |
Summary
Section titled “Summary”In this chapter, you learned:
- ✅ cgroups architecture (v1 vs v2)
- ✅ Creating and managing cgroups
- ✅ Resource limits (CPU, memory, I/O, processes)
- ✅ systemd integration
- ✅ Namespace types and purposes
- ✅ Creating and using namespaces
- ✅ Network namespaces in detail
- ✅ Combining cgroups and namespaces
- ✅ Practical examples
- ✅ Interview questions and answers
Next Chapter
Section titled “Next Chapter”Last Updated: February 2026