SECTION 10.3

Process Isolation

Running in a New PID Namespace

With CLONE_NEWPID, the child process becomes PID 1 in its own namespace:

func child() {
    fmt.Printf("PID as seen inside: %d\n", os.Getpid()) // prints 1

    // Set hostname in our new UTS namespace
    syscall.Sethostname([]byte("container"))

    // Run the user's command
    cmd := exec.Command(os.Args[2], os.Args[3:]...)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.Run()
}

What PID 1 Means

Inside a PID namespace, your process is PID 1 — the init process. This has consequences:

This is why containers need proper signal handling — and why tini or dumb-init exist.

Viewing Namespaces

From the host, you can inspect namespaces:

# See namespaces of a process
ls -la /proc/<pid>/ns/

# Enter a running container's namespaces
nsenter --target <pid> --mount --uts --ipc --net --pid

This is what docker exec and kubectl exec do under the hood.