Docker源码学习进度(4)

1.实现容器的后台运行, -d Flag

①在runCommand中加入-d Flag

cli.BoolFlag{

Name:  "d",

Usage: "detach container",

}

②-d和-ti不能同时存在

createTty := context.Bool("ti")

detach := context.Bool("d")

if createTty && detach {

return fmt.Errorf("ti and d paramter can not both provided")

}

③在run.go中,使parent进程自动退出,这样就直接进入到了后台运行状态.

//if tty表示detach是true

if tty {

    parent.Wait()

}

2.实现查看运行容器, ps

在容器运行时要记录容器的运行信息

在run.go中的recordContainerInfo中

①利用随机数生成一个容器id

②创建一个containerInfo的接口,里面存放ID,pid,command等信息

③将containerinfo转换为json格式

④将containerinfo存入一以下这个文件中

DefaultInfoLocation string = "/var/run/mydocker/%s/"  //%s为containername

ConfigName          string = "config.json"

在ps时查看容器信息

①调用listCommand中listContainers

其核心是在于遍历DefaultInfoLocation 中所有的containername

然后读取里面的config.json中的内容.

3.实现查看容器日志   logs

在容器运行时要记录容器的运行信息

①创建日志文件,其创建位置以及创建的策略与ps中一致。

②将容器运行的输出方式从标准输出改为日志文件。

cmd.Stdout = stdLogFile

在logs时读取日志信息

就是打开上面的文件,然后再读取的方式进行的。

4.实现进入容器Namespace

进入namespace的意义。就是类似于从后台容器的角度,运行某些指令,使得

后台容器与运行在前台一样。

Cgo

是一种在Go语言中使用C语言的方法。这也是为什么有些GO语言中有C语言的代码。

EnterNamespace函数

①判断环境变量,mydocker_pid与mydocker_cmd是否存在。

②打开namespace所在的文件。

③使用setns系统调用,来进入到namespace中。

④使用system(mydocker_cmd)来调用余下的命令.

ExecContainer函数

①根据containername获得pid

②重新创建一个exec的指令

cmd := exec.Command("/proc/self/exe", "exec")

③设置环境变量,只有设置了环境变量以后,调用EnterNamespace才会有效。

④重新执行新的exec函数.

你可能感兴趣的:(Docker源码学习进度(4))