隔离机制是实现Docker容器的重要技术,其中UTS Namespace隔离的是主机与域名,
在Linux
内核中的调用参数为CLONE_NEWUTS
。我们都知道Docker
是用Golang
实现了
那么自然我们可以用Golang
来实现UTS Namespace
隔离
主机环境如下
➜ ~ uname -a
Linux ubuntu 4.4.0-131-generic #157-Ubuntu SMP Thu Jul 12 15:51:36 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
➜ ~ go version
go version go1.6.2 linux/amd64
Golang
源码
package main
import (
"os/exec"
"syscall"
"os"
"log"
)
func main(){
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags:syscall.CLONE_NEWUTS,
}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run();err !=nil{
log.Fatal(err)
}
}
编译运行产生进入到fork出来新的进程里面的shell交互环境
查看当前进程的PID
及系统中进程之间的关系
# echo $$
1805
# pstree -pl
systemd(1)-+-accounts-daemon(868)-+-{gdbus}(889)
| `-{gmain}(881)
|-acpid(865)
|-atd(836)
|-cron(842)
|-dbus-daemon(848)
|-dhclient(962)
|-iscsid(1061)
|-iscsid(1062)
|-login(1138)---zsh(1228)
|-lvmetad(422)
|-lxcfs(845)-+-{lxcfs}(856)
| `-{lxcfs}(857)
|-mdadm(897)
|-nginx(1082)---nginx(1084)
|-polkitd(907)-+-{gdbus}(912)
| `-{gmain}(910)
|-rsyslogd(831)-+-{in:imklog}(861)
| |-{in:imuxsock}(860)
| `-{rs:main Q:Reg}(862)
|-snapd(873)-+-{snapd}(913)
| |-{snapd}(914)
| |-{snapd}(915)
| |-{snapd}(921)
| |-{snapd}(930)
| `-{snapd}(931)
|-sshd(1077)---sshd(1260)---sshd(1291)---zsh(1292)---sudo(1790)---go(1791)-+-ns(1802)-+-sh(1805)---pstree(1806)
| | |-{ns}(1803)
| | `-{ns}(1804)
| |-{go}(1792)
| |-{go}(1793)
| |-{go}(1794)
| `-{go}(1798)
|-systemd(1219)---(sd-pam)(1225)
|-systemd-journal(361)
|-systemd-logind(826)
|-systemd-timesyn(679)---{sd-resolve) S 1 (689)
`-systemd-udevd(436)
fork进程的shell环境查看
(/proc/$PID/ns/下每个文件对应一个namespace, 它是一个符号链接, 会指向一个仅kernel可见的被称为nsfs(namespace filesystem)的文件系统中的一个inode)
# readlink /proc/1805/ns/uts
uts:[4026532192]
# readlink /proc/1802/ns/uts
uts:[4026531838]
在主机上查看
➜ ~ sudo readlink /proc/1802/ns/uts
uts:[4026531838]
➜ ~ sudo readlink /proc/1805/ns/uts
uts:[4026532192]
在fork进程shell环境中查看并修改hostname
# hostname
ubuntu
# hostname -b bird
# hostname
bird
在主机上
➜ ~ hostname
ubuntu
可以看到,fork进程的hostname产生了变更,主机不受影响,同样,主机hostname也不会对fork进程产生影响,由此fork进程的hostname
与主机父进程的hostname成功实现了隔离。
参考
有疑问加站长微信联系(非本文作者)