Linux Namespace 是 Kernel 的一个功能,它可以隔离一系列的系统资源,比如 PID、UserID、NetWork 等。
Linux Namespace 主要包含以下几种:
- UTS Namespace:隔离 nodename 和 domainname,以便设置独立的 hostname;
- IPC Namespace:隔离 System V IPC 和 POSIX message queue;
- PID Namespace:隔离进程 ID;
- Mount Namespace:隔离挂载点视图,执行 mount/umount 只影响当前进程;
- User Namespace:隔离用户和用户组;
- Network Namespace:隔离网络栈;
使用 golang 创建一个隔离的 shell 环境,代码如下 linux_namespaces.go:
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER | syscall.CLONE_NEWNET,
UidMappings: []syscall.SysProcIDMap{
{
ContainerID: 0,
HostID: 0,
Size: 1,
},
},
GidMappings: []syscall.SysProcIDMap{
{
ContainerID: 0,
HostID: 0,
Size: 1,
},
},
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatal(err)
os.Exit(-1)
}
}
编译并执行该示例程序,验证其隔离性:
1. HOSTNAME
2. PID & Mount
3. Network
4. 把 代码中的 ContainerID 改为 65534,重新编译运行,发现 ID 是不同的