简介
通过对前面Linux的Namespace、Cgroups、Union File System的学习,对Docker实现的基础知识有了一点点了解,接下来就跟着作者开始编写
源码说明
同时放到了Gitee和Github上,都可进行获取
本章节对应的版本标签是:3.1,防止后面代码过多,不好查看,可切换到标签版本进行查看
思路整理
下图是《自动动手写docker》中这一章节的核心流程图,我们在跟着作者写的时候也是这个思路:
在学习的过程,根据自己的学习精简了下(是对于编写代码的精简)
- 1.输入运行命令:如 run -ti /bin/sh
- 2.解析参数:得到输入的参数
- 3.创建并启动namespace隔离的容器进程:使用Linux的Namespace隔离进程环境
- 4.容器内调用自己,挂载proc文件系统,完成运行
注:本章的代码运行一次后,再次运行会出现下面的错误提示:
{
"level":"error","msg":"fork/exec /proc/self/exe: no such file or directory","time":"2022-03-05T08:51:07+08:00"}
此时,我们运行下面的命令后,再次运行就可以了,可能是挂载proc文件系统的影响
mount -t proc proc /proc
1.命令解析
在书中,使用了组件库进行实现,我们照抄即可:
文件: main.go
package main
import (
"dockerDemo/mydocker/command"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
"os"
)
const usage = `mydocker is a simple container runtime implementation.
The purpose of this projects is to learn how docker works and how to write a docker by ourselves
Enjoy it, just for fun.`
func main() {
app := cli.NewApp()
app.Name = "mydocker"
app.Usage = usage
app.Commands = []cli.Command{
command.InitCommand,
command.RunCommand,
}
app.Before = func(context *cli.Context) error {
log.SetFormatter(&log.JSONFormatter{
})
log.SetOutput(os.Stdout)
return nil
}
if err := app.Run(os.Args); err != nil {
log.Fatal(err