第一天-地鼠文档


本站和网页 https://www.topgoer.cn/docs/seven-docker/seven-docker-1dpdobohuea3q 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

第一天-地鼠文档
七天用 Go 写个 docker
首页
打印
首页
下载pdf
分享
目录
搜索
第一天第二天第三天第四天第五天第六天第七天
暂无相关搜索结果!
本文档使用 topgoer 发布
第一天
docker 详解很多人刚接触 docker 的时候就会感觉非常神奇,感觉这个技术非常新颖,其实并不然,docker 使用到的技术都是之前已经存在过的,只不过旧酒换了新瓶罢了。简单来说 docker 本质其实是一个特殊的进程,这个进程特殊在它被 Namespace 和Cgroup技术做了装饰,Namespace 将该进程与Linux 系统进行隔离开来,让该进程处于一个虚拟的沙盒中,而 Cgroup 则对该进程做了一系列的资源限制,两者配合模拟出来一个沙盒的环境。
NamespacLinux 对线程提供了六种隔离机制,分别为:uts pid user mount network ipc ,它们的作用如下:
uts: 用来隔离主机名pid:用来隔离进程 PID 号的user: 用来隔离用户的mount:用来隔离各个进程看到的挂载点视图network: 用来隔离网络ipc:用来隔离 System V IPC 和 POSIX message queues
环境配置因为我们是在 Windows 里面写代码,然后将代码编译好,放到 Linux 中执行,所以这里我们要更改下我们 goland 的环境,因为在不同的环境中,go 导入的文件也是不同,如果我们的环境使用的 Windows,那么使用 os/exec 包时,导入的将是 exec_windows.go,而如果我们的环境是 Linux,那么将会导入 exec_linux.go 文件,因为只有 Linux 才会给创建进程时提供这个隔离参数,所以我们需要把环境改成 Linux。
Go 实现进程隔离隔离 utspackage main
import (
"log"
"os"
"os/exec"
"syscall"
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)
我们编译一下,放到 Linux 中测试一下,windows 中编译需要先把 GOOS 改成 Linux,然后再执行 go build,编译脚本如下
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go
将 main 放到 Linux 环境中运行,这里我用的是 Centos
4.2 测试能否隔离主机名给 main 文件添加可执行权限
chmod +x main查看当前主机名
执行 main 文件
./main
修改主机名
hostname -b 新主机名
再次查看主机名,我们看到已经将主机名修改为 test 了
退出 shell,再次查看主机名
这时我们发现,外部的主机名,并没有被改变,说明该进程成功的将自己的 hostname与外部的 hostname进行隔离了。这也证明我们使用 uts namespace 成功了。
其他的隔离我们想对此进程进行那种隔离,只需要在 Cloneflags 中添加参数即可
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_NEWPID |
syscall.CLONE_NEWNS |
syscall.CLONE_NEWUSER |
syscall.CLONE_NEWNET,
// 设置容器的UID和GID
UidMappings: []syscall.SysProcIDMap{
// 容器的UID
ContainerID: 1,
// 宿主机的UID
HostID: 0,
Size: 1,
},
},
GidMappings: []syscall.SysProcIDMap{
// 容器的GID
ContainerID: 1,
// 宿主机的GID
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)
}转自:微信号 跟派大星学编程最后编辑: kuteng  文档更新时间: 2022-04-14 17:15   作者:kuteng
×Close
项目分享
项目地址
关闭
×Close
项目分享
项目地址
关闭