Working with Containers and Namespaces
1. Understanding Namespaces
| Namespace Type | Description | Key Features | Use Case |
|---|---|---|---|
| pid | Process ID namespace | Each process in a namespace has unique PID, isolated from other namespaces | Process isolation in containers |
| net | Network namespace | Isolates network devices, ports, routing tables, etc. | Container networking |
| ipc | Inter-Process Communication namespace | Isolates shared memory segments, message queues, semaphores | Secure IPC in isolated environments |
| mnt | Mount namespace | Isolates filesystem mount points and filesystem views | Container root filesystem isolation |
| uts | UTS namespace | Isolates hostname and domain name | Container hostnames |
| user | User namespace | Maps UIDs/GIDs to different values in the namespace | Running containers as non-root users |
| cgroup | Cgroup namespace | Isolates cgroup hierarchies and resource limits | Resource control in containers |
Example: Creating a Network Namespace
ip netns add mynamespace
ip netns list
ip netns exec mynamespace ip addr show
Note: Namespaces provide a fundamental isolation mechanism in Linux, allowing processes to operate in separate environments with isolated resources.
2. Understanding Control Groups
| Property | Description | Values |
|---|---|---|
| /sys/fs/cgroup | Mount point for cgroup filesystem | /sys/fs/cgroup |
| cgroup.subtree_control | Enables controllers for a cgroup subtree | cpu io memory |
| cgroup.procs | Process IDs in a cgroup | 1234 5678 |
Example: Creating a new cgroup
mkdir /sys/fs/cgroup/myapp
echo 1234 > /sys/fs/cgroup/myapp/cgroup.procs
Note: Control groups are used to limit, account for, and isolate resource usage (CPU, memory, I/O) of a set of processes.
3. Using systemd-nspawn
systemd-nspawn is a lightweight containerization tool that allows running a full Linux system inside a namespace. It is part of the systemd suite and provides a simple way to isolate processes and filesystems without the overhead of full virtualization.
| Option | Values | Description |
|---|---|---|
| -D, --directory | /path/to/rootfs |
Root directory to use as the container's filesystem. |
| -u, --user | username |
Run the container as a specific user. |
| --bind | /host/path:/container/path |
Bind mount a host directory into the container. |
| --port | host:container |
Forward a port from the host to the container. |
| --ephemeral | true |
Destroy the container after it exits. |
Example: Running a container with systemd-nspawn
systemd-nspawn -D /var/lib/machines/mycontainer --bind /home/user:/home/user
Example: Running a container with port forwarding
systemd-nspawn -D /var/lib/machines/webserver --port 8080:80
Note: The container root filesystem must be a valid Linux root directory, typically created using tools like
debootstrap or dnf with --installroot.
Warning: Using
systemd-nspawn with --bind can expose sensitive host directories to the container if not carefully configured.
Key Features of systemd-nspawn
- Lightweight and fast, ideal for development or testing environments.
- Supports bind mounts, port forwarding, and user mapping.
- Does not require a separate daemon or complex configuration files.
- Can be used to run full Linux distributions inside containers.
4. Creating Isolated Environments
| Namespace Type | Description | Flag | Isolation Scope |
|---|---|---|---|
| mount | Isolates filesystem mounts | --mount |
Process-specific |
| uts | Isolates hostname and NIS domain name | --uts |
Process-specific |
| ipc | Isolates IPC resources (shared memory, semaphores) | --ipc |
Process-specific |
| net | Isolates network interfaces and sockets | --net |
Process-specific |
| pid | Isolates process IDs | --pid |
Process-specific |
| user | Isolates user and group IDs | --user |
Process-specific |
Note: The
unshare command creates a new namespace for the specified subsystems and runs the provided command in that isolated environment.
Key Concepts in Namespace Isolation
- Mount namespaces isolate filesystems and mount points.
- UTS namespaces isolate hostname and NIS domain name.
- IPC namespaces isolate inter-process communication resources.
- Network namespaces isolate network interfaces and sockets.
- PID namespaces isolate process IDs, allowing nested processes.
- User namespaces isolate user and group IDs, enabling root in a container without real root privileges.
5. Managing Resource Limits
| Resource Type | Control Group | Description | Default Value |
|---|---|---|---|
| memory.limit_in_bytes | memory |
Maximum memory usage for the container | Unlimited |
| memory.soft_limit_in_bytes | memory |
Soft limit for memory usage (can be exceeded) | Unlimited |
| cpu.cfs_quota_us | cpu |
CPU time quota in microseconds | -1 (unlimited) |
| cpu.cfs_period_us | cpu |
CPU time period in microseconds | 100000 (100ms) |
| blkio.weight | blkio |
Block I/O weight (10-1000) | 500 |
Note: Resource limits can be managed via cgroups directly or through container runtimes like Docker and Podman.
6. Using unshare for Namespaces
The unshare command in Linux allows you to run a command in a new namespace, effectively isolating the process from the host system's namespaces. This is useful for creating containers or testing applications in isolated environments.
| Option | Description | Example |
|---|---|---|
| --user | Creates a new user namespace | unshare --user bash |
| --mount | Creates a new mount namespace | unshare --mount bash |
| --pid | Creates a new PID namespace | unshare --pid bash |
| --net | Creates a new network namespace | unshare --net bash |
| --ipc | Creates a new IPC namespace | unshare --ipc bash |
| --uts | Creates a new UTS namespace | unshare --uts bash |
| --cgroup | Creates a new cgroup namespace | unshare --cgroup bash |
Example: Running a command in a new mount namespace
unshare --mount 'mount -t tmpfs tmpfs /mnt'
Note: The
unshare command requires root privileges or appropriate capabilities to create certain namespaces, such as PID and user namespaces.
Warning: Be cautious when using
unshare with root privileges, as it can lead to privilege escalation if misused.
7. Viewing Container Processes
| Process | Description | Command |
|---|---|---|
| ps aux | Lists all running processes with detailed information | ps aux |
| top | Real-time view of running processes, sorted by CPU usage | top |
| htop | Enhanced version of top with better UI and process management | htop |
| pstree | Displays processes in a tree format showing parent-child relationships | pstree |
Note: The
nsenter command allows you to enter a namespace of another process, useful for inspecting container processes from the host.
8. Configuring cgroups v2
| Resource | Description | Notes |
|---|---|---|
| /sys/fs/cgroup | Mount point for cgroups v2 hierarchy | Always mounted as none with cgroup2 filesystem type |
| cgroup.subtree_control | Controls which controllers are enabled for a cgroup | Write controller names (e.g., cpu io memory) to enable them |
| cgroup.threads | Number of threads in a cgroup | Read-only; shows current thread count |
Example: Enabling CPU and Memory Controllers
echo "cpu io memory" > /sys/fs/cgroup/cgroup.subtree_control
Note: cgroups v2 uses a single hierarchy, unlike v1 which had multiple hierarchies.
Warning: Modifying cgroup settings directly can affect system stability. Ensure proper testing in a controlled environment.
9. Limiting CPU Usage
| Resource | Value | Description |
|---|---|---|
| cpu.cfs_period_us | 100000 |
Control group CPU period in microseconds (default: 100000) |
| cpu.cfs_quota_us | -1 |
Control group CPU quota in microseconds (default: -1 = unlimited) |
| cpu.shares | 1024 |
Relative weight of CPU time (default: 1024) |
Example: Setting CPU Quota
# Limit container to 50% CPU usage
echo 50000 > /sys/fs/cgroup/cpu/my_container/cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/my_container/cpu.cfs_period_us
Note: The
cpu.cfs_quota_us and cpu.cfs_period_us values are used together to define CPU limits. A value of -1 for cpu.cfs_quota_us means no limit is set.
Warning: Setting
cpu.cfs_quota_us to a value less than cpu.cfs_period_us will effectively limit the CPU usage to a percentage of the period.
10. Limiting Memory Usage
| Option | Values | Notes |
|---|---|---|
| memory.limit_in_bytes | 1073741824 |
Maximum memory usage in bytes (1GB) |
| memory.soft_limit_in_bytes | 1207959552 |
Soft limit for memory usage (1.1GB) |
| memory.swappiness | 60 |
How aggressively to swap memory pages (0-100) |
| memory.memsw.limit_in_bytes | 2147483648 |
Total memory + swap limit (2GB) |
Example: Setting Memory Limits in cgroup
echo 1073741824 > /sys/fs/cgroup/memory/my_container/memory.limit_in_bytes
echo 1207959552 > /sys/fs/cgroup/memory/my_container/memory.soft_limit_in_bytes
Note: Memory limits are enforced at the cgroup level and can be managed via systemd or directly through cgroup filesystems.