zoukankan      html  css  js  c++  java
  • docker 源码分析 三(基于1.8.2版本),NewDaemon启动

    本文来分析一下New Daemon的启动过程;在daemon/daemon.go文件中;

    func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemon, err error) {

        setDefaultMtu(config)    //设置默认的MTU,这里的默认值时1500

        // Ensure we have compatible configuration options

        if err := checkConfigOptions(config); err != nil {

            return nil, err

        }                               //检查是否出现有冲突的配置,主要有(1)config.Bridge.Iface 与 config.Bridge.IP 这两项配置不能都有,设置一个就可;

                                         //(2) config.Bridge.EnableIPTables 与 config.Bridge.InterContainerCommunication,后者是icc,表示docker容器间是否可以互相通信,

                                         // icc是通过iptables来实现的,即在iptables的FORWARD链中增加规则,所以不能在两者同时为false,但不清楚icc=true,但EntableIPTables为false的时候会怎么样;

                                         // (3) 当config.Bridge.EnableIPTables为false时,config.Bridge.EnableIPMasq,ip伪装功能不能为true,和(2) 一样,因为ip伪装是通过iptables来实现的;

        // Do we have a disabled network?

        config.DisableBridge = isBridgeNetworkDisabled(config)   // 判断config.Bridge.Iface 与 disableNetworkBridge是否相等,犹豫Iface默认值为空,disableNetworkBridge默认值为none,所以这个config.DisableBridge  为false

        

        // Verify the platform is supported as a daemon

        if !platformSupported {

            return nil, ErrSystemNotSupported

        }                                //在非 linux,freebsd,windows三种os下,这个取为false;

        // Validate platform-specific requirements

        if err := checkSystem(); err != nil {

            return nil, err

        }                               //checkSystem主要验证运行docker的进程是否为root,需要root权限;还有包括验证linux kernel的版本;

    // set up SIGUSR1 handler on Unix-like systems, or a Win32 global event

        // on Windows to dump Go routine stacks

        setupDumpStackTrap()    //  用来接收SIGUSR1信号,接收到信号后,将堆栈信息打印出来;通过标准库中signal.Notify()函数来实现;

        // get the canonical path to the Docker root directory

        var realRoot string

        if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {

            realRoot = config.Root                                  

        } else {

            realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root)

            if err != nil {

                return nil, fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)

            }

        }                 //获取docker运行时的根路径,后续的流程会在这个根目录下创建各种子目录,默认的是在"/var/lib/docker"路径下;

        config.Root = realRoot

        // Create the root directory if it doesn't exists

        if err := system.MkdirAll(config.Root, 0700); err != nil {

            return nil, err

        }                //如果根路径不存在,那么建立一个;

        // set up the tmpDir to use a canonical path

        tmp, err := tempDir(config.Root)

        if err != nil {

            return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err)

        }

        realTmp, err := fileutils.ReadSymlinkedDirectory(tmp)

        if err != nil {

            return nil, fmt.Errorf("Unable to get the full path to the TempDir (%s): %s", tmp, err)

        }

        os.Setenv("TMPDIR", realTmp)    //建立temp文件的存放路径,读取环境变量DOCKER_TMPDIR值,如果没有那么直接在根路径下建立tmp子目录 ,即/var/lib/docker/tmp

        // Set the default driver

        graphdriver.DefaultDriver = config.GraphDriver  //设立graph driver,graphdriver主要是来管理镜像,以及镜像与镜像之间关系的实现方法。

    // Load storage driver

        driver, err := graphdriver.New(config.Root, config.GraphOptions) 

        if err != nil {

            return nil, fmt.Errorf("error initializing graphdriver: %v", err)

        }

        logrus.Debugf("Using graph driver %s", driver)   

    //设立graph driver,graphdriver主要是来管理镜像,以及镜像与镜像之间关系的实现方法。由于config.GraphDriver的默认值为空,所以主要的处理流程在graphdriver.New()中;

    //加载的优先级的顺序为 priority = []string{"aufs","btrfs","zfs","devicemapper","overlay","vfs"}, 

        d := &Daemon{}

        d.driver = driver

        // Ensure the graph driver is shutdown at a later point

        defer func() {

            if err != nil {

                if err := d.Shutdown(); err != nil {

                    logrus.Error(err)

                }

            }

        }()

        // Verify logging driver type

        if config.LogConfig.Type != "none" {

            if _, err := logger.GetLogDriver(config.LogConfig.Type); err != nil {

                return nil, fmt.Errorf("error finding the logging driver: %v", err)

            }

        }              //进行log driver的配置,默认的log driver 是json-file, 在deamon/logger 目录下是各种log driver,包括: fluentd,syslogd,journald, gelf等(前三种了解,gelf不太知道 https://www.graylog.org/resources/gelf/)

                                                                                                                                                                                                      

        logrus.Debugf("Using default logging driver %s", config.LogConfig.Type)

        // Configure and validate the kernels security support

        if err := configureKernelSecuritySupport(config, d.driver.String()); err != nil {

            return nil, err

        }            //设置系统是否使用SELinux,SElinux有个问题是不能和btrfs的graphdriver一起使用;

        daemonRepo := filepath.Join(config.Root, "containers")

        if err := system.MkdirAll(daemonRepo, 0700); err != nil {

            return nil, err            //创建容器的存储目录,在根目录下创建container子目录,/var/log/docker/container

        // Migrate the container if it is aufs and aufs is enabled

        if err := migrateIfDownlevel(d.driver, config.Root); err != nil {

            return nil, err

        }            // 将可能存在的老版本docker中image和container的存储形式迁移到新版本的docker中的存储形式;

        logrus.Debug("Creating images graph")

        g, err := graph.NewGraph(filepath.Join(config.Root, "graph"), d.driver)

        if err != nil {

            return nil, err

        }           //使用driver实例化一个NewGraph对象,这个管理文件系统的镜像 以及 文件系统之间的关系;

        // Configure the volumes driver

        volStore, err := configureVolumes(config)

        if err != nil {

            return nil, err

        }                                //设置数据卷driver,数据卷是docker容器之间进行数据共享的一种手段;数据卷可以是一个本机命令(通过-v 标识挂载在到容器的某个目录下)

                                          //数据卷也可以作为数据卷容器,通过--volumes-from挂载到某个容器中;

        trustKey, err := api.LoadOrCreateTrustKey(config.TrustKeyPath) 

        if err != nil {

            return nil, err

        }                          //创建key,路径在/etc/docker/key.json

        trustDir := filepath.Join(config.Root, "trust")

        if err := system.MkdirAll(trustDir, 0700); err != nil {

            return nil, err

        }     

        trustService, err := trust.NewStore(trustDir)

        if err != nil {

            return nil, fmt.Errorf("could not create trust store: %s", err)

        }   // 创建trustService ,用于提供验证服务;

        eventsService := events.New()

        logrus.Debug("Creating repository list")

        tagCfg := &graph.TagStoreConfig{

            Graph:    g,

            Key:      trustKey,

            Registry: registryService,

            Events:   eventsService,

            Trust:    trustService,

        }

        repositories, err := graph.NewTagStore(filepath.Join(config.Root, "repositories-"+d.driver.String()), tagCfg)

        if err != nil {

            return nil, fmt.Errorf("Couldn't create Tag store repositories-%s: %s", d.driver.String(), err)

        }         //TagStore是用来存储镜像的仓库列表,

        if restorer, ok := d.driver.(graphdriver.ImageRestorer); ok {

            if _, err := restorer.RestoreCustomImages(repositories, g); err != nil {

                return nil, fmt.Errorf("Couldn't restore custom images: %s", err)

            }

        }

        d.netController, err = initNetworkController(config)

        if err != nil {

            return nil, fmt.Errorf("Error initializing network controller: %v", err)

        }    //初始化docker网络环境;

        graphdbPath := filepath.Join(config.Root, "linkgraph.db")

        graph, err := graphdb.NewSqliteConn(graphdbPath)

        if err != nil {

            return nil, err

        }     //graphdb是一个图数据,纪录的是镜像与镜像之间的关系;

        d.containerGraph = graph

        var sysInitPath string

        if config.ExecDriver == "lxc" {

            initPath, err := configureSysInit(config)

            if err != nil {

                return nil, err

            }

            sysInitPath = initPath

        }

        sysInfo := sysinfo.New(false)

        // Check if Devices cgroup is mounted, it is hard requirement for container security,

        // on Linux/FreeBSD.

        if runtime.GOOS != "windows" && !sysInfo.CgroupDevicesEnabled {

            return nil, fmt.Errorf("Devices cgroup isn't mounted")

        }

        ed, err := execdrivers.NewDriver(config.ExecDriver, config.ExecOptions, config.ExecRoot, config.Root, sysInitPath, sysInfo)

        if err != nil {

            return nil, err

        }   // execdriver 是使用docker容器的执行驱动,由execdriver执行容器的创建和运行等,通过调用cgroup,usernamespace等等实现;

        d.ID = trustKey.PublicKey().KeyID()

        d.repository = daemonRepo

        d.containers = &contStore{s: make(map[string]*Container)}

        d.execCommands = newExecStore()

        d.graph = g

        d.repositories = repositories

        d.idIndex = truncindex.NewTruncIndex([]string{})

        d.config = config

        d.sysInitPath = sysInitPath

        d.execDriver = ed

        d.statsCollector = newStatsCollector(1 * time.Second)

        d.defaultLogConfig = config.LogConfig

        d.RegistryService = registryService

        d.EventsService = eventsService

        d.volumes = volStore

        d.root = config.Root

        go d.execCommandGC()

        if err := d.restore(); err != nil {

            return nil, err

        }

        return d, nil
    }

  • 相关阅读:
    SQL慢查询安装过程
    grafana + influxdb + telegraf , 构建性能监控平台
    JDK安装、java环境配置
    多源最短路Floyd 算法————matlab实现
    单源最短路Dijkstra算法——matlab实现
    Layout基本属性总结
    Scrollview中嵌套ListView(自定义组件解决)
    SQL 一列拆分多行
    C# 在异步中使用HttpWebRequest出现的“正在终止线程”错误的解决方案
    sqlserver中分区函数 partition by与 group by 区别 删除关键字段重复列
  • 原文地址:https://www.cnblogs.com/yuhan-TB/p/4861210.html
Copyright © 2011-2022 走看看