Runc 源码导读

runc 是OCI 的实现,是云原生系统的最底下的积木

关键类及接口

容器对象构建类

//1. 定义
// 容器构造工厂接口
type Factory interface{}
// Factory 的实现类为
type LinuxFactory struct{
//关键成员变量
// InitPath is the path for calling the init responsibilities for spawning
	// a container.
	InitPath string  //初始化进程路径
	// InitArgs are arguments for calling the init responsibilities for spawning
	// a container.
	InitArgs []string// 初始化参数
}
//2. 对象构造
//factory_linux.go:func New 函数
l := &LinuxFactory{
		Root:      root,
		InitPath:  "/proc/self/exe",
		InitArgs:  []string{os.Args[0], "init"},
		Validator: validate.New(),
		CriuPath:  "criu",
	}
//在构造 factory的时候,InitPath 为/proc/self/exe 该参数表明应用程序为自身,启动参数为init

容器接口及容器类

//定义了容器的基本接口
type BaseContainer interface{}
//继承了BaseContainer 接口;增加了暂停,恢复等接口
type Container interface {
	BaseContainer
}
//容器接口实现结构体
type linuxContainer struct{}

runner

容器逻辑执行器

//两个关键参数
type runner struct{
action          CtAct //对容器执行的动作
init            bool  //是否初始化容器
}

以下为runc 指令 分别对 runner的 action和 init的赋值

runc create # init 为true, action CT_ACT_CREATE [该指令创建一个容器]
runc exec  # init 为false,action 为CT_ACT_RUN [该指令在容器中执行一个进程]
runc run  # init 为 true, action为 为CT_ACT_RUN [该指令创建并启动一个容器]
runc restore # init  true,action为CT_ACT_RESTORE [该指令从checkpoint点恢复容器]

process

//#runc/libcontainer/process.go
// Process specifies the configuration and IO for a process inside
// a container.
// 容器对象的内部进程,指定了配置和IO;
type Process struct{}

parent process

//指定了parent process的操作接口
type parentProcess interface{}

//下面三个对象 实现了parent process 接口
//runc runc exec 命令时使用
type setnsProcess struct{}
//调起 runc init 进程 传参env:_LIBCONTAINER_INITTYPE=initSetns
func (p *setnsProcess) start() (err error) {}
//runc create 和runc run 命令时使用
type initProcess struct{} //包含 fifo 管道
//调起 runc init 进程 传参env:_LIBCONTAINER_INITTYPE=initStandard 
func (p *initProcess) start() (retErr error) {}
//runc restore 指令使用
type restoredProcess struct{}
//容器初始接口
type initer interface {
	Init() error
}
//设置容器的的name space
type linuxSetnsInit struct{}
//标准初始化
type linuxStandardInit struct{}

类图

runc_classs

容器创建活动图

各个进程的关系:

  1. containerd 垫片进程拉起 runc create
  2. runc create 拉起 runc init parent (runc/libcontainer/process_linux.go: initProcess.start())
  3. runc init parent 通过clone 函数创建 runc init child 进程 (runc/libcontainer/nsenter/nsexec.c: clone_parent())
  4. runc init child 进程通过clone 函数创建 runc init grand child 进程(runc/libcontainer/nsenter/nsexec.c:clone_parent())

runc_activity

时序图

runc 进程通信时序图

runc_sequence

参考

opencontainers

runc