• docker 源码分析NewDaemon 函数


    NewDaemon函数是Daemon初始化时的重要函数,该函数做好了daemon处理消息的准备

        setDefaultMtu(config)  //  设置默认MTU 1500
        ModifyRootKeyLimit() //  "/proc/sys/kernel/keys/root_maxkeys"  key权限不足的话修改权限
        verifyDaemonSettings(config) //   检查配置是否正确,不正确退出
        config.DisableBridge = isBridgeNetworkDisabled(config)   // conf.BridgeConfig.Iface == config.DisableNetworkBridge

        if !platformSupported {  //   系统是否支持
            return nil, errSystemNotSupported
        }

        checkSystem()  //   检查系统版本等信息

        uidMaps, gidMaps, err := setupRemappedRoot(config)  // pkg/idtools/idtools.go  根据username、groupname创建两个map
        rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) // pkg/idtools/idtools.go 创建根uid、gid

        setupDaemonProcess(config)   // linux   设置 /proc/self/oom_score_adj
        tmp, err := tempDir(config.Root, rootUID, rootGID)  //  创建tmp文件夹
        realTmp, err := fileutils.ReadSymlinkedDirectory(tmp)  //  pkg/fileutils/fileutils.go 给tmp创建一个symlink
        os.Setenv("TMPDIR", realTmp)

        d := &Daemon{configStore: config}   //创建个daem 实例
        defer func() {  // 函数退出时 daemon 关闭
            if err != nil {
                if err := d.Shutdown(); err != nil {
                    logrus.Error(err)
                }
            }
        }()

        d.setupSeccompProfile()  // 需要的话创建 seccompProfile
        d.setDefaultIsolation()  // 只是windows使用,决定 isolation mode

        configureMaxThreads(config)  // linux 下面设置最大线程 /proc/sys/kernel/threads-max
        ensureDefaultAppArmorProfile()  // 如果使能 AppArmor ,则加载

        daemonRepo := filepath.Join(config.Root, "containers")   // 创建一个containers的目录
        if err := idtools.MkdirAllAs(daemonRepo, 0700, rootUID, rootGID); err != nil && !os.IsExist(err) {
            return nil, err
        }

        if runtime.GOOS == "windows" {   //  windows创建credentialspecs的目录
            if err := system.MkdirAll(filepath.Join(config.Root, "credentialspecs"), 0); err != nil && !os.IsExist(err) {
                return nil, err
            }
        }

        driverName := os.Getenv("DOCKER_DRIVER")   // 取环境变量设置值,未设置取配置
        if driverName == "" {
            driverName = config.GraphDriver
        }

        d.RegistryService = registryService
        d.PluginStore = plugin.NewStore(config.Root) // todo: remove
        // Plugin system initialization should happen before restore. Do not change order.
        d.pluginManager, err = plugin.NewManager(plugin.ManagerConfig{   // plugin/manager.go  创建plugin manager 实例
            Root:               filepath.Join(config.Root, "plugins"),
            ExecRoot:           getPluginExecRoot(config.Root),
            Store:              d.PluginStore,
            Executor:           containerdRemote,
            RegistryService:    registryService,
            LiveRestoreEnabled: config.LiveRestoreEnabled,
            LogPluginEvent:     d.LogPluginEvent, // todo: make private
        })

        d.layerStore, err = layer.NewStoreFromOptions(layer.StoreOptions{   // lay/layer_store.go 创建graphDriver实例,从driver创建layer仓库的实例
            StorePath:                 config.Root,
            MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
            GraphDriver:               driverName,
            GraphDriverOptions:        config.GraphOptions,
            UIDMaps:                   uidMaps,
            GIDMaps:                   gidMaps,
            PluginGetter:              d.PluginStore,
            ExperimentalEnabled:       config.Experimental,
        })

        graphDriver := d.layerStore.DriverName()   // 取layer里面的graphDriver
        imageRoot := filepath.Join(config.Root, "image", graphDriver) 


        configureKernelSecuritySupport(config, graphDriver)  // linux内核安全支持的配置
        d.downloadManager = xfer.NewLayerDownloadManager(d.layerStore, *config.MaxConcurrentDownloads)   // distribution/xfer/download.go 创建层下载管理实例
        d.uploadManager = xfer.NewLayerUploadManager(*config.MaxConcurrentUploads)  // distribution/xfer/upload.go 创建层上传管理实例
        ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))   // image/fs.go   创建仓库后端的文件系统
        d.imageStore, err = image.NewImageStore(ifs, d.layerStore)  // image/store.go  创建镜像仓库实例
        volStore, err := d.configureVolumes(rootUID, rootGID) // 创建 volumes driver实例
        trustKey, err := api.LoadOrCreateTrustKey(config.TrustKeyPath)  //  api/common.go 按照路径加载libtrust key ,没有就新建一个

        trustDir := filepath.Join(config.Root, "trust")
        system.MkdirAll(trustDir, 0700)
        distributionMetadataStore, err := dmetadata.NewFSMetadataStore(filepath.Join(imageRoot, "distribution"))  // distribution/metadata/metadata.go  按照路径创建一个基于文件系统的元数据仓库实例

        eventsService := events.New()   //  daemon/events/events.go  创建event服务实例
        referenceStore, err := refstore.NewReferenceStore(filepath.Join(imageRoot, "repositories.json"))  // reference/store.go  按照路径创建 reference仓库实例

        v1.Migrate(config.Root, graphDriver, d.layerStore, d.imageStore, referenceStore, distributionMetadataStore) // migrate/v1/migrate.go  迁移metadata


        d.initDiscovery(config) // 创建 discoveryWatcher 实例

        sysInfo := sysinfo.New(false)   // 获取系统信息,linux 不支持cgroup则返回
        if runtime.GOOS == "linux" && !sysInfo.CgroupDevicesEnabled {
            return nil, errors.New("Devices cgroup isn't mounted")
        }

        d.ID = trustKey.PublicKey().KeyID()  // 赋值
        d.repository = daemonRepo
        d.containers = container.NewMemoryStore()
        d.execCommands = exec.NewStore()
        d.referenceStore = referenceStore
        d.distributionMetadataStore = distributionMetadataStore
        d.trustKey = trustKey
        d.idIndex = truncindex.NewTruncIndex([]string{})
        d.statsCollector = d.newStatsCollector(1 * time.Second)
        d.defaultLogConfig = containertypes.LogConfig{
            Type:   config.LogConfig.Type,
            Config: config.LogConfig.Config,
        }
        d.EventsService = eventsService
        d.volumes = volStore
        d.root = config.Root
        d.uidMaps = uidMaps
        d.gidMaps = gidMaps
        d.seccompEnabled = sysInfo.Seccomp
        d.apparmorEnabled = sysInfo.AppArmor
        d.nameIndex = registrar.NewRegistrar()
        d.linkIndex = newLinkIndex()
        d.containerdRemote = containerdRemote

        go d.execCommandGC()  // 新建协程清理容器不需要的命令

        d.containerd, err = containerdRemote.Client(d) //  创建和daemon相关的容器客户端 libcontainerd
        d.restore()    //  restart  container

        // FIXME: this method never returns an error
        info, _ := d.SystemInfo()   // 获取host server系统信息

        engineVersion.WithValues(
            dockerversion.Version,
            dockerversion.GitCommit,
            info.Architecture,
            info.Driver,
            info.KernelVersion,
            info.OperatingSystem,
        ).Set(1)
        engineCpus.Set(float64(info.NCPU))
        engineMemory.Set(float64(info.MemTotal))

        // set up SIGUSR1 handler on Unix-like systems, or a Win32 global event
        // on Windows to dump Go routine stacks
        stackDumpDir := config.Root
        if execRoot := config.GetExecRoot(); execRoot != "" {
            stackDumpDir = execRoot
        }
        d.setupDumpStackTrap(stackDumpDir)  // 创建处理系统信号的通道和协程

  • 相关阅读:
    Linux(8)查看服务器系统信息
    Scrapy爬取西刺代理ip流程
    Scrapy提取多个标签的text
    Scrapy常用命令行工具
    暴力&打表
    博客试水
    Linux --远程访问控制
    php--最新正则(手机号码)
    MySQLdump常用命令
    关于XSS攻击
  • 原文地址:https://www.cnblogs.com/arwen-spy/p/6624362.html
Copyright © 2020-2023  润新知