0
点赞
收藏
分享

微信扫一扫

go语言学习-用go实现docker-1

docker原理

docker​ 本质其实是一个特殊的进程,这个进程特殊在它被 Namespace​ 和Cgroup​技术做了装饰,Namespace​ 将该进程与Linux​ 系统进行隔离开来,让该进程处于一个虚拟的沙盒中,而 Cgroup 则对该进程做了一系列的资源限制,两者配合模拟出来一个沙盒的环境。

Namespac

Linux 对线程提供了六种隔离机制,分别为:uts pid user mount network ipc ,它们的作用如下:

  • uts: 用来隔离主机名
  • pid:用来隔离进程 PID 号的
  • user: 用来隔离用户的
  • mount:用来隔离各个进程看到的挂载点视图
  • network: 用来隔离网络
  • ipc:用来隔离 System V IPC 和 POSIX message queues

go实现进程隔离

隔离uts

//隔离uts
//main.go
package main

import (
"log" //日志
"os" //操作系统接口
"os/exec" //执行外部命令
"syscall" //包系统调用
)

func main() {
//定义系统命名,创建子系统环境
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS, //配置UTS隔离环境
}
//定义标准输入输出
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
//判断是否异常
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}

编译运行

go build main.go
./main

修改主机名

hostname -b test

go语言学习-用go实现docker-1_系统调用

查看本机主机名

hostname

go语言学习-用go实现docker-1_系统调用_02

这时我们发现,外部的主机名,并没有被改变,说明该进程成功的将自己的 hostname​与外部的 hostname​进行隔离了。这也证明我们使用 uts namespace 成功了。


其他隔离

我们想对此进程进行那种隔离,只需要在 Cloneflags 中添加参数即可

//隔离IPC,pPID,NS等
package main

import (
"log" //日志
"os" //操作系统接口
"os/exec" //执行外部命令
"syscall" //包系统调用
)

func main() {
//定义系统命名,创建子系统环境
cmd := exec.Command("sh")
cmd.SysProcAttr = &syscall.SysProcAttr{
//隔离uts,ipc,pid,mount,user,network
Cloneflags: syscall.CLONE_NEWUTS |
syscall.CLONE_NEWIPC |
syscall.CLONE_NEWNS |
syscall.CLONE_NEWUSER |
syscall.CLONE_NEWNET,

//设置容器的UID和GID
UidMappings: []syscall.SysProcIDMap{
{
//容器的UID
ContainerID: 1,
//宿主机的UID
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)
}
}

测试,在进程上和网络上已经跟宿主机隔离了

go语言学习-用go实现docker-1_系统环境_03


举报

相关推荐

0 条评论