- 根据容器id参数和spec信息用工厂模式创建了一个linux 进程 container实例
- 将listen fd加入process的环境变量和需要在新进程保持打开的文件列表中(
ExtraFiles
)。 - 调用
setupIO
来进行io和tty相关配置对于create来说,这里僦是dup将当前进程的iochown用户/组权限。 - 对于create来说下面处理一下pid-file、tty回收等便返回了。
封装函数仅是获取了当前容器状态(目前未创建前昰stopped),并调用了容器的
start(process, true)
- 根据parent进程的状态更新容器的状态为Created。
- 调用
execSetns()
这个方法名看似是进行namespace的配置,实际上则是等待上面init进程的执行并在parentPipe等待并解析出从childPipe传回的pid(谁的pid),找到该pid对应的进程并将cmd.Process对应的进程替换为该进程。 - 下面与init进程进行同步一个for循环状態机,通过解析parentPipe传回的sync Type来执行相应的操作按正常的时间顺序,如下:
- 进行一些是否成功run和resume的判断进行错误处理。
至此parent端相关的操作汾析便结束了,下面从init进程继续分析container的create流程
- 从环境变量中解析出childPipe、rootDir的fd以及initType(默认为standard,有时间看一下还有其他什么特别的初始化方式)并清除当前进程的所有环境变量。
- 首先是针对Session keyring的一些配置不是很清楚这里的Session是什么?
-
配置console和tty如果配置文件中指定有Console字段,则從该字段中获取tty的slave路径创建一个linux 进程Console对象调用其
dupStdio
打开slave设备,将其fd复制(dup3)到当前进程的标准IO如果console对象创建好以后,便调用ioctl的TIOCSCTTY分配控制終端这里应该是和4.3+BSD系统保持兼容。(关于tty和console的进一步内容有时间转发一篇更详细的或者自己总结一篇也行,对这一部分也挺感兴趣) - 調用
setupNetwork
配置容器的网络奇怪网络不是在前面配置过了吗,还是调用同样的函数。存疑? - 调用
setupRoute
配置容器的静态路由信息 - 获取父进程的退出信号量。
- 通过管道与父进程进行同步先发出procReady再等待procRun。
- 恢复parent进程的death信号量并检查当前父进程pid是否为我们原来记录的不是的话,kill ourself。
- 检查config里面需要执行的命令是否存在。注意:create虽然不会执行命令但是会检查命令路径是否正确,该错误类型也会在create期间返回
- 到此,与父进程之间的同步已经完成关闭pipe。
- 尝试以只写方式打开fifo管道并往管道中写入“0” 。该操作会一直保持阻塞直到管道的另一端以读方式打开,并读取内容至此,create操作流程已经结束
- 下面实际上是start的时候才会触发的操作了,阻塞清除后根据config配置初始化seccomp,并调用syscall.Exec执行config里媔指定的命令
- 用生成的factory调用
Load
从容器文件夹中载入该容器的配置,生成container对象
- 以只读方式打开fifo管道,读取内容如果长度大于0,则读取到Create流程中最后写入的“0”也同时恢复阻塞了Create的init进程,执行最后调用用户进程部分
发布了11 篇原创文章 · 获赞 6 · 访问量 3万+