avatar🌌
TangentTangent Blog

技术博客 | Go & Kubernetes & Linux

技术博客 | Go & Kubernetes & Linux

Linux unshare Command Explained: From Namespaces to DIY Containers

unshare is a powerful low-level Linux command-line tool. It runs a program with certain shared resources detached from the parent process, and is the foundational building block behind modern container technologies like Docker and Podman.

Core Concept: Linux Namespaces ​

unshare is essentially a wrapper around the unshare() system call. The core concept it operates on is Linux Namespaces.

In a traditional Linux system, all processes share the same set of global resources (network stack, PID list, filesystem mount tree, etc.). Namespaces allow these global resources to be partitioned and isolated, giving different process groups different views of the system.

The Linux kernel supports seven major namespace types:

NamespaceWhat It Isolates
Mount (mnt)Filesystem mount points. Mounts/unmounts in the new space don’t affect the host
PID (pid)Process IDs. The first process in the new space gets PID 1 and cannot see host processes
Network (net)Network devices, IP addresses, routing tables, firewall rules
IPC (ipc)System V IPC and POSIX message queues
UTS (uts)Hostname and domain name
User (user)User and group IDs. A regular user can be mapped to root inside the new space
Cgroup (cgroup)Cgroup root directory view

unshare Parameters ​

Namespace Flags ​

FlagNamespaceEffect
-m, --mountMountIsolate mount point view
-u, --utsUTSIsolate hostname
-i, --ipcIPCIsolate inter-process communication
-n, --netNetworkIsolate networking; new env has only lo in down state
-p, --pidPIDIsolate process IDs
-U, --userUserIsolate user IDs
-C, --cgroupCgroupIsolate cgroup view

Essential Auxiliary Flags ​

Namespace flags alone aren’t enough. These three flags make the isolated environment actually usable:

  • --fork (-f): Required with PID isolation. The kernel dictates that the process creating a new PID namespace keeps its original PID — only its child process becomes PID 1 in the new space. So -p must be paired with -f.
  • --mount-proc: Required with PID isolation. Tools like ps and top read /proc for process info. Without remounting, they still show host processes. This flag automatically mounts a fresh /proc in the new mount namespace.
  • --map-root-user (-r): Used with User isolation. Maps the current host user to root inside the new user namespace, granting admin privileges within that space.

Common Use Cases ​

1. Isolated Hostname (UTS Isolation) ​

Temporarily change the hostname without affecting the host:

bash
sudo unshare -u /bin/bash
hostname test-container
hostname  # shows test-container

2. Clean Network Test Environment (Network Isolation) ​

bash
sudo unshare -n /bin/bash
ip a  # only lo interface, completely disconnected

3. Simulated Container Environment (PID + Mount) ​

bash
sudo unshare -p -f --mount-proc /bin/bash
ps aux  # only bash and ps visible, bash has PID 1

4. Fully Isolated Namespaces ​

Isolate all seven namespace types at once:

bash
sudo unshare --mount --uts --ipc --net --pid --user --cgroup \
    --fork --map-root-user --mount-proc /bin/bash

Short form:

bash
sudo unshare -muinpUC -f -r --mount-proc /bin/bash

Verify isolation:

bash
ps aux          # only bash and ps, PIDs start from 1
ip a            # only lo, in DOWN state
hostname box    # changing hostname doesn't affect the host
ls -l /proc/$/ns  # compare with host — inode numbers are different

Key Insight: Mount Isolation ≠ Filesystem Isolation ​

This is a critical distinction: unshare -m isolates the mount point list view, not the filesystem itself.

When you run unshare -m, the kernel copies the host’s entire mount tree to the new space. Mount/unmount operations in the new space won’t affect the host, but the root directory / still points to the host’s disk partition.

This means:

  • File modifications affect the host: echo "hello" > /root/test.txt writes directly to the host disk
  • Mount operations don’t affect the host: mount -t tmpfs none /mnt only takes effect in the new space

Why Is /proc Isolated Then? ​

The --mount-proc flag remounts the /proc pseudo-filesystem inside the new space. /proc isn’t a real on-disk filesystem — it’s dynamically generated by the kernel in memory. When proc is mounted inside an isolated PID namespace, the kernel only exposes processes belonging to that namespace.

Building a Real Isolated Container with chroot ​

To achieve Docker-like filesystem isolation, combine unshare with chroot or pivot_root to switch the root directory.

Prepare an Independent Root Filesystem ​

Use the lightweight Alpine Linux (~5MB):

bash
mkdir -p /tmp/my-container && cd /tmp/my-container
curl -O https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/x86_64/alpine-minirootfs-3.19.1-x86_64.tar.gz
tar -xvf alpine-minirootfs-3.19.1-x86_64.tar.gz
rm alpine-minirootfs-3.19.1-x86_64.tar.gz

Launch the Isolated Container ​

bash
sudo unshare --mount --uts --ipc --net --pid --user --cgroup \
    --fork --map-root-user \
    chroot /tmp/my-container /bin/sh

Then manually mount /proc inside:

bash
mount -t proc proc /proc
ps aux   # only the sh process
ls /     # Alpine's filesystem, no longer the host's

Files created inside the container only exist within /tmp/my-container and won’t pollute the host’s root filesystem.

The User Namespace Permission Trap ​

When using --user --map-root-user, you may encounter Permission denied even if the files belong to your user.

The reason: --map-root-user maps you to UID 0 (root) inside the container, but the filesystem permission check sees UID 0 doesn’t match the file owner’s UID (e.g., 1000) on the host, so access is denied.

Solutions:

bash
sudo chown -R $(whoami) /tmp/my-container

sudo unshare --mount --uts --ipc --net --pid --fork --mount-proc \
    chroot /tmp/my-container /bin/sh

Summary ​

unshare is the core tool for manipulating Linux kernel Namespaces and the key to understanding container technology. A complete container can be summarized as:

Container=Namespaces(resourceisolation)+Chroot(filesystemisolation)+Cgroups(resourcelimits)Container = Namespaces (resource isolation) + Chroot (filesystem isolation) + Cgroups (resource limits)

  • unshare handles "what you can see" and "which network interface you can use"
  • chroot / pivot_root handles "which files you can modify"
  • cgroups handles "how much CPU and memory you can use"
runc 源码解读(一):从 SPEC.md 看容器命名空间
Linux unshare 命令详解:从命名空间到手工容器
由 Valaxy v1.2.2 驱动|主题-Yunv1.2.2