我正在学习容器和码头工人。我刚刚观看了这个 Liz Rice 视频,其中她从头开始创建了一个容器(repo 在 github.com/lizrice)。我无法完全遵循它,因为我是 Docker 和容器的新手,而且我不懂 Go 编程语言。但是,我想看看是否有人可以非常快速地解释代码中的这些项目是/试图完成的内容:
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strconv"
"syscall"
)
// go run main.go run <cmd> <args>
func main() {
switch os.Args[1] {
case "run":
run()
case "child":
child()
default:
panic("help")
}
}
func run() {
fmt.Printf("Running %v \n", os.Args[2:])
cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
Unshareflags: syscall.CLONE_NEWNS,
}
must(cmd.Run())
}
func child() {
fmt.Printf("Running %v \n", os.Args[2:])
cg()
cmd := exec.Command(os.Args[2], os.Args[3:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
must(syscall.Sethostname([]byte("container")))
must(syscall.Chroot("/home/liz/ubuntufs"))
must(os.Chdir("/"))
must(syscall.Mount("proc", "proc", "proc", 0, ""))
must(syscall.Mount("thing", "mytemp", "tmpfs", 0, ""))
must(cmd.Run())
must(syscall.Unmount("proc", 0))
must(syscall.Unmount("thing", 0))
}
特别是,我对容器的理解是,它是一个虚拟化的运行时环境,用户可以在其中将应用程序与底层系统隔离开来,而容器只是运行在单个主机上的隔离进程组,它们实现了一组“通用”特征。我很清楚容器是什么,并试图在更广泛的意义上完成,但我希望帮助理解这样的具体示例。如果有人很好地理解这一点 - 导入块中正在导入什么;主要功能中的情况是什么;run 函数中的语句有什么用,child 和 cg 函数正在完成什么?
我认为以我目前的理解和阅读 Docker 教程,加上一个从头开始的真实代码示例的解释将非常有益。只是为了确认 - 此代码与 Docker 本身无关,除了代码创建容器之外,Docker 是一种使创建容器更容易的技术。
千万里不及你
天涯尽头无女友
相关分类