Linux Namespace可以隔离一系列的系统资源,如一下6种不同类型的Namespace:
1.Network Namespace
用来隔离网络设备,IP地址端口等网络栈的Namespace,让每个容器拥有自己独立的(虚拟的)网络设备,而且容器内的应用可以绑定到自己的端口,每个Namespace内的端口都不会冲突.在宿主机上搭建网桥后,能很方面地实现容器之间的通信.
可以使用命令ifconfig,在宿主机查看网络设备,运行最下方例子后,再次运行ifconfig会发现网络设备不同.
2.UTS Namespace
用来隔离nodename和domainname两个系统标识.在UTS Namespace里面,每个Namespace允许有自己的hostname.
可以使用命令pstree -pl查看系统中进程之间的关系
通过命令redlink /proc/19912/ns/uts
redlink /proc/19912/ns/uts
验证一下父进程和子进程是否不再同一个UTS Namespace里面
在不同的UTS Namespace通过命令hostname -b xxxxhostname 绑定一个hostname,并在宿主机(另一个UTS Namespace)上运行hostname,可以看到宿主机的hostname不受绑定影响.
3.IPC Namespace
用来隔离System V和POSIX message queues.
通过命令ipcmk -Q创建一个message queue.查看命令ipcs -q来验证
4.PID Namespace
用来隔离进程ID.同样一个进程在不同的PID Namespace里可以拥有不同的PID.
通过命令pstree -pl查看进程树,ps -ef查看进程来验证
5.Mount Namespace
用来隔离各个进程看到的挂载点视图.在不同Namespace的进程中,看到的文件系统层次是不一样的.在Mout Namespace中调用mount()和umount()仅仅只会影响当前Namespace内的文件系统,而对全局的文件系统是没有影响的.
通过查看文件内容来验证:
ls /proc
mount -t proc poc /proc
ls /proc
6.User Namespace
用来隔离用户的用户组ID.也就是说,一个进程的User ID和Group ID在User Namespace内外是不同的.通常是让一个用户在自己的User Namespace拥有自己的root权限,但对外没有root权限.
go代码例子:
package main
import(
"log"
"os"
"os/exec"
"syscall"
)
func main(){
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Clonefalgs: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID|
syscall.CLONE_NEWNS | syscall.CLONE_NEWUSER | syscall.CLONE_NEWNET,
}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(1),Gid: uint32(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)
}参考自<自己动手写Docker>