// containerd-shim is a small shim that sits in front of a runtime implementation that allows it to be reparented to init and handle reattach from the caller.

// the cwd of the shim should be the path to the state directory where the shim can locate fifos and other information\

// Arg0: id of the container

// Arg1: bundle path

// Arg2: runtime binary

在启动容器时,containerd-shim的命令行格式如下所示:

docker-containerd-shim 9decb150527a3b64a86b85cfc6faeb09f786dcb2f4e668611418280c75755539 
/var/run/docker/libcontainerd/9decb150527a3b64a86b85cfc6faeb09f786dcb2f4e668611418280c75755539 docker-runc

  

1、containerd/containerd-shim/main.go

func main()

(1)、创建log文件,f, err := os.OpenFile(filepath.Join(cwd, "shim-log.json") ...)

(2)、调用err := start(f)函数,若err不为nil,当err为errRuntime的时候,直接关闭f并返回,否则将错误记录到shim-log.json中

2、containerd/containerd-shim/main.go

// start handling signals as soon as possible so that things are properly reaped

// or if runtime exits before we hit the handler

func start(log *os.File) error

(1)、set the shim as the subreaper for all orphaned processes created by the container,err := osutils.SetSubreaper(1)

(2)、打开exit pipe和control pipe

(3)、调用p, err := newProcess(flag.Arg(0), flag.Arg(1), flag.Arg(2)),加载process实例,再调用p.create()

(4)、msgC := make(chan controlMesage, 32),创建一个goroutine,从control pipe中不断读取controlMessage

(5)、最后,一个无限for循环,对来自signal的信号和controlMessage进行处理

(6)、当从signal中获得的信号为SIGCHLD时,当退出的进程为runtime时,退出shim

(7)、对来此control pipe的controlMessage进行处理,当msg的Type为0时,关闭stdin,当Type为1时,且p.console不为nil,则调整tty的窗口大小

3、containerd/containerd-shim/process.go

func newProcess(id, bundle, runtimeName string)

(1)、p := &process{id: id, bundle: bundle, runtime: runtimeName}

(2)、调用s, err := loadProcess(),从process.json文件中加载state,p.state = s

(3)、调用p.openIO(),最后,返回p

4、containerd/containerd-shim/process.go

// openIO opens the pre-created fifo's for use with the container in RDWR so that they remain open if the other side stops listening

func (p *process) openIO() error

(1)、先创建一个goroutine,打开p.state.Stdin, p.stdinCloser = os.openFile(p.state.Stdin, syscall.O_WRONLY)

// NewConsole returns an initialized console that can be used within a container by copying bytes from the master side to the slave that is attached as the tty for the container's init process

(2)、如果p.state.Terminal为true,调用master, console, err := newConsole(uid, gid),p.console = master, p.consolePath = console,再打开p.state.Stdin和p.state.Stdout,最后调用io.Copy将stdin/stdout与master相连

(3)、对于非tty的情况,调用i, err := p.initializeIO(uid),p.shimIO = i,再打开p.state.Stdout和p.state.Stderr(方式为可读写)分别与i.Stdou和i.Stderr相连。接着打开p.state.Stdin为只读模式,再将i.Stdin和p.state.Stdin相连

5、containerd/containerd-shim/process.go

func (p *process) initializeIO(rootuid int)

该函数生成三个os.Pipe()并分别将一端赋给i = &IO{},再将另一端赋给p.stdio

6、containerd/containerd-shim/process.go

func (p *process) create() error

(1)、获取当前目录,创建logPath := filepath.Join(cwd, "log.json"),再扩展args := append([]string{"--log", logPath, "--log-format", "json"}, p.state.RuntimeArgs...)

(2)、对exec,checkpoint,create进行不同的处理,这里只讨论create的情况,继续扩展args = append(args, "create", "--bundle", p.bundle, "--console", p.consolepath)

(3)、扩展参数--pid-file,cmd := exec.Command(p.runtime, args...),并且将cmd的stdio设置为p.stdio

(4)、调用cmd.Start(),再调用p.stdio.stdout.Close()和p.stdio.stderr.Close()(why????)

(5)、cmd.Wait(),从pid文件中读出pid,并且将p.containerPid 设置为pid

docker containerd shim分析的更多相关文章

  1. docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储

    前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...

  2. docker 源码分析 一(基于1.8.2版本),docker daemon启动过程;

    最近在研究golang,也学习一下比较火的开源项目docker的源代码,国内比较出名的docker源码分析是孙宏亮大牛写的一系列文章,但是基于的docker版本有点老:索性自己就git 了一下最新的代 ...

  3. Docker源码分析(九):Docker镜像

    1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...

  4. Docker源码分析(八):Docker Container网络(下)

    1.Docker Client配置容器网络模式 Docker目前支持4种网络模式,分别是bridge.host.container.none,Docker开发者可以根据自己的需求来确定最适合自己应用场 ...

  5. Docker源码分析(七):Docker Container网络 (上)

    1.前言(什么是Docker Container) 如今,Docker技术大行其道,大家在尝试以及玩转Docker的同时,肯定离不开一个概念,那就是“容器”或者“Docker Container”.那 ...

  6. Docker源码分析(六):Docker Daemon网络

    1. 前言 Docker作为一个开源的轻量级虚拟化容器引擎技术,已然给云计算领域带来了新的发展模式.Docker借助容器技术彻底释放了轻量级虚拟化技术的威力,让容器的伸缩.应用的运行都变得前所未有的方 ...

  7. Docker源码分析(五):Docker Server的创建

    1.Docker Server简介 Docker架构中,Docker Server是Docker Daemon的重要组成部分.Docker Server最主要的功能是:接受用户通过Docker Cli ...

  8. Docker源码分析(四):Docker Daemon之NewDaemon实现

    1. 前言 Docker的生态系统日趋完善,开发者群体也在日趋庞大,这让业界对Docker持续抱有极其乐观的态度.如今,对于广大开发者而言,使用Docker这项技术已然不是门槛,享受Docker带来的 ...

  9. Docker源码分析(三):Docker Daemon启动

    1 前言 Docker诞生以来,便引领了轻量级虚拟化容器领域的技术热潮.在这一潮流下,Google.IBM.Redhat等业界翘楚纷纷加入Docker阵营.虽然目前Docker仍然主要基于Linux平 ...

随机推荐

  1. Run python as a daemon process

    I am using `&`: why isn't the process running in the background?     No problem. We won't show y ...

  2. java判定字符串中仅有数字和- 正则表达式匹配 *** 最爱那水货

    1.当有其他字符出现时,返回的数组长度>1 String s = "3---6\\5656";        Pattern pattern = Pattern.compil ...

  3. ABAP - 3D Graphs with SAP

    在ABAP设计中,程序员经常需要用图形显示报表的统计结果,我们可以使用函数:GRAPH_MATRIX_3D来达到图形显示.GRAPH_MATRIX_3D函数参数很多,但只有三个参数必须需要输入:Tab ...

  4. 使用Python给要素添加序号

    在ArcGIS的属性表中,由于编辑修改的原因,默认的FID或OID并不连续,经常需要给要素添加连读的序号,可使用Python代码完成. rec=-1 def autoIncrement(): glob ...

  5. Oracle执行计划与统计信息的一些总结

    [日期:2011-08-05]来源:Linux社区  作者:wangshengfeng1986211[字体:大 中 小] 2010-07-01 15:03 1.SET AUTOTRACE ON EXP ...

  6. C#获取本地系统日期格式

    我们可以通过使用DataTime这个类来获取当前的时间.通过调用类中的各种方法我们可以获取不同的时间:如:日期(2008-09-04).时间(12:12:12).日期+时间(2008-09-04 12 ...

  7. Android-adb 常用命令 和 sqlite

    Android开发环境中,ADB是我们进行Android开发经常要用的调试工具,它的使用当然是我们Android开发者必须要掌握的. ADB概述 Android Debug Bridge,Androi ...

  8. Python学习 windows下面安装Python和pip(一)

    windows下面安装Python和pip 安装Python 第一步,我们先来安装Python, https://www.python.org/downloads/ 这里选择的是2.7.10 第二步. ...

  9. Silverlight项目笔记8:层次布局、客户端读取shp、ExecuteCountAsync、柱状图、url传参

    1.层次布局 由于地图窗口和菜单栏都在一个父容器内,在浏览器缩小到一定程度点击地图弹出infoWindow时,会出现菜单栏遮挡infoWindow中间部分的现象,于是通过设置Canvas.ZIndex ...

  10. ios 删除系统从相册压缩的视频

    iOS的沙盒机制,应用只能访问自己应用目录下的文件.iOS不像android,没有SD卡概念,不能直接访问图像.视频等内容.iOS应用产生的内容,如图像.文件.缓存内容等都必须存储在自己的沙盒内.默认 ...