
Namespace UTS 级别说明及其利用 Go 调用接口的实验演示
0
环境说明
操作系统:Ubuntu 14.04
内核版本:3.13.0-24-generic
Go 语言版本:go version go1.7.1 linux/amd64
1
UTS Namespace 说明
UTS Namespace主要用来隔离 nodename 和 domainname 两个系统标识。在 UTS Namespace 里面,每个 Namespace 允许有自己的 hostname
下面使用 Go 来做一个 UTS Namespace 的例子,对于 Namespace 这种 Linux 系统调用来说,使用 C 肯定是最好调用的方式。但是对于 Docker 来说 Go 是其开发语言,所以接下来我们使用 Go 来演示
2
代码
package mainimport (// Go 语言内置的 log 包实现了简单的日志服务"log"// os 包提供了不依赖平台的操作系统函数接口"os"// exec 包执行外部命令,它将 os.StartProcess 进行包装使得它更容易映射到 stdin 和 stdout,并且利用pipe连接 i/o"os/exec"// syscall 包包含一个指向底层操作系统原语的接口"syscall")func main() {// 指定被 fork 出来的新进程内的初始化命令,默认使用 sh 来执行cmd := exec.Command("sh")//cmd.SysProcAttr = &syscall.SysProcAttr{// 使用 CLONE_NEWUTS 这个标识区创建一个 UTS Namespace,GO 已经帮我们封装了对 clone() 函数的调用,这段代码执行后就会进入到一个 sh 运行环境中Cloneflags: syscall.CLONE_NEWUTS,}// Stdin指定进程的标准输入,如为nil,进程会从空设备读取(os.DevNull)cmd.Stdin = os.Stdin// Stdout和Stderr指定进程的标准输出和标准错误输出cmd.Stdout= os.Stdout// Stdout和Stderr指定进程的标准输出和标准错误输出cmd.Stderr = os.Stderr/* Run执行c包含的命令,并阻塞直到完成。如果命令成功执行,stdin、stdout、stderr的转交没有问题,并且返回状态码为0,方法的返回值为nil(执行Run函数的返回状态,正确执行Run函数,并不代表正确执行了命令);如果函数没有执行或者执行失败,会返回*ExitError类型的错误;否则返回的error可能是表示I/O问题。即:该命令只会执行且阻塞到执行结束,如果执行函数有错则返回报错信息,没错则返回nil,并不会返回执行结果*/if err := cmd.Run(); err != nil {// 打印输出内容,退出应用程序,defer 函数不会执行log.Fatal(err)}// 终止程序,退出码 -1os.Exit(-1)}

3
演示说明
ubuntu 父空间中执行的进程树

代码运行后子名称空间中运行的 pid

查看代码进程与子 shell 所处于的 NS UTS 的不同

通过上图我们可以看到,它们确实已经分离在了不同的 UTS Namespace 中,由于 UTS Namespace 对 hostname 做了隔离所以我们修改 hostname 也不会影响外部主机

实验过程描述:先在子名称空间中(左图) 修改了主机名为 wangyang,之后执行主机名查看为 wangyang。然后在 父名称空间中(右图)修改了主机名为 svcloudt.com ,之后执行主机名查看为 svcloudt.com,之后在子名称空间中(左图)查看主机名依然为 wangyang。由此,可以证明外部的 hostname 并没有被内部的修改所影响
下期预告:Docker 底层揭秘(三) - Linux Namespace 之 IPC
END


文章转载自wangyanglinux 宝典,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




