zoukankan      html  css  js  c++  java
  • docker containerd shim分析

    // 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

  • 相关阅读:
    地图的可视化--Folium
    GIS性能策略
    计算多边形中心线
    生成凹壳
    路径分析之NetworkX实例
    网络分析之networkx(转载)
    网络分析之Pgrouting(转载)
    颜色空间变换(RGB-HSV)
    计算坡度与坡向
    计算山体阴影
  • 原文地址:https://www.cnblogs.com/YaoDD/p/6004556.html
Copyright © 2011-2022 走看看