美文网首页
runC的checkpoint功能模块源码分析

runC的checkpoint功能模块源码分析

作者: 之江数字孪生与数据智能 | 来源:发表于2020-08-29 18:14 被阅读0次

    runC是什么?

    RunC 是一个轻量级的工具,它是用来运行容器的,只用来做这一件事,并且这一件事要做好。我们可以认为它就是个命令行小工具,可以不用通过 docker 引擎,直接运行容器。事实上,runC 是标准化的产物,它根据 OCI 标准来创建和运行容器。而 OCI(Open Container Initiative)组织,旨在围绕容器格式和运行时制定一个开放的工业化标准。

    概述

    本文对runC的checkpoint功能模块源码进行分析,主要包括:

    1. 梳理checkpoint功能模块源码的调用流程;
    2. 梳理checkpoint功能模块源码中用到的struct、method和第三方库;
    3. 梳理checkpoint功能模块源码中涉及的专业知识(需要学习的部分);

    checkpoint功能模块源码的调用流程

    runC源码入口为:

    runc/main.go

    func main() {
        app := cli.NewApp()
        app.Name = "runc"
        app.Usage = usage
            ...
    
            app.Flags = []cli.Flag{
            ...
        }
        app.Commands = []cli.Command{
            checkpointCommand,
            ...
        }
        ...
    }
    

    由main()函数可知,checkpointCommand是checkpoint功能模块的入口,进入checkpointCommand定义:

    runc/checkpoint.go

    var checkpointCommand = cli.Command{
        ...
        Flags: []cli.Flag{
            ...
        },
        Action: func(context *cli.Context) error {
            ...
            container, err := getContainer(context)
            ...
            
            options := criuOptions(context)
            ...
            return container.Checkpoint(options)
        },
    }
    

    由checkpointCommand定义可知,checkpointCommand核心内容由Flags和Action组成,Flags中各个flag的作用通过定义可以一目了然,接下来深入分析Action中定义的函数。

    Action函数

    由checkpointCommand定义可知,Action函数核心内容包括:container, err := getContainer(context) 、options := criuOptions(context)和container.Checkpoint(options)三个函数调用,接下来逐个函数深入分析。

    container, err := getContainer(context)

    函数getContainer(...)的作用是获取需要checkpoint的容器实例,进入函数getContainer(...)的定义:

    runc/utils_linux.go

    func getContainer(context *cli.Context) (libcontainer.Container, error) {
        ...
        factory, err := loadFactory(context)
        ...
        return factory.Load(id)
    }
    

    由getContainer(...)函数的定义可知,其作用是通过从状态加载指定的容器实例并返回,整个过程是由factory, err := loadFactory(context)和factory.Load(id)联合完成的,接下来对它们的实现进行深入分析。

    factory, err := loadFactory(context)

    进入loadFactory(context)函数定义:

    runc/utils_linux.go

    func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
        ...
        return libcontainer.New(abs, cgroupManager, intelRdtManager,
            libcontainer.CriuPath(context.GlobalString("criu")),
            libcontainer.NewuidmapPath(newuidmap),
            libcontainer.NewgidmapPath(newgidmap))
    }
    

    由 loadFactory(...)函数的定义可知,该函数的主要作用就是根据指定配置创建一个容器实例并返回,该功能主要由libcontainer.New(...)函数完成,进入其定义:

    runc/libcontainer/factory_linux.go

    func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
        ...
        l := &LinuxFactory{
            Root:      root,
            InitPath:  "/proc/self/exe",
            InitArgs:  []string{os.Args[0], "init"},
            Validator: validate.New(),
            CriuPath:  "criu",
        }
        ...
        return l, nil
    }
    

    由New(...)函数的定义可知,创建factory实例最终是由struct LinuxFactory{...}(runc/libcontainer/factory_linux.go)来实现的,该struct实现了Factory interface {...}(runc/libcontainer/factory_linux.go)。

    factory.Load(id)

    进入factory.Load(id)函数定义:

    runc/libcontainer/factory_linux.go

    func (l *LinuxFactory) Load(id string) (Container, error) {
        ...
        c := &linuxContainer{
            ...
        }
        c.state = &loadedState{c: c}
        ...
        return c, nil
    }
    

    由factory.Load(id)函数的定义可知,创建容器实例最终是由linuxContainer struct{...}(runc/libcontainer/container_linux.go)来实现的,该struct实现了Container interface {...}(runc/libcontainer/container_linux.go)。

    至此,就分析完了getContainer(context)函数的整个实现流程,接下来分析options := criuOptions(context)。

    options := criuOptions(context)

    函数criuOptions(context)用来获取checkpoint的配置项实例,进入函数 criuOptions(context)的定义:

    runc/restore.go

    func criuOptions(context *cli.Context) *libcontainer.CriuOpts {
        imagePath := getCheckpointImagePath(context)
        ...
        }
        return &libcontainer.CriuOpts{
            ImagesDirectory:         imagePath,
            WorkDirectory:           context.String("work-path"),
            ParentImage:             context.String("parent-path"),
            LeaveRunning:            context.Bool("leave-running"),
            TcpEstablished:          context.Bool("tcp-established"),
            ExternalUnixConnections: context.Bool("ext-unix-sk"),
            ShellJob:                context.Bool("shell-job"),
            FileLocks:               context.Bool("file-locks"),
            PreDump:                 context.Bool("pre-dump"),
            AutoDedup:               context.Bool("auto-dedup"),
            LazyPages:               context.Bool("lazy-pages"),
            StatusFd:                context.Int("status-fd"),
        }
    }
    

    由criuOptions(context)函数定义可知,该函数就是用来获取checkpoint的各配置项,并最终创建一个CriuOpts实例
    返回。

    container.Checkpoint(options)

    函数container.Checkpoint(options)负责执行容器的checkpoint操作,进入其定义:

    runc/libcontainer/container_linux.go

    func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
        ...
        if err := os.Mkdir(criuOpts.ImagesDirectory, 0700); err != nil && !os.IsExist(err) {
            return err
        }
        ...
            rpcOpts := criurpc.CriuOpts{
            ...
        }
    
        c.handleCriuConfigurationFile(&rpcOpts)
    
        ...
        var t criurpc.CriuReqType
        if criuOpts.PreDump {
            ...
        } else {
            ...
        }
    
        if criuOpts.LazyPages {
            ...
        }
    
        req := &criurpc.CriuReq{
            Type: &t,
            Opts: &rpcOpts,
        }
    
        // no need to dump all this in pre-dump
        if !criuOpts.PreDump {
            
            ...
        }
    
        err = c.criuSwrk(nil, req, criuOpts, nil)
        ...
        return nil
    }
    

    由container.Checkpoint(options)函数的定义可知,容器实例根据配置项将运行的容器checkpoint出来。

    至此,就梳理完了runC的checkpoint功能模块源码的调用流程。

    checkpoint功能模块源码中用到的struct、method和第三方库

    相关文章

      网友评论

          本文标题:runC的checkpoint功能模块源码分析

          本文链接:https://www.haomeiwen.com/subject/uyejsktx.html