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

本文深入剖析Docker Daemon的NewDaemon功能,详细讲解从配置信息应用、系统支持检测、存储驱动加载到网络环境创建等一系列关键步骤,揭示Docker Daemon启动过程的核心逻辑,帮助读者理解Docker Daemon的内部工作机制。
摘要由CSDN通过智能技术生成

【摘要】

Docker架构中Docker Daemon支撑着整个后台的运行,同时也统一化管理着Docker架构中graph、graphdriver、execdriver、volumes、Docker container等众多资源。可以说,Docker Daemon复杂的运作均由daemon对象来调度,而newDaemon的实现恰巧可以帮助大家了解这一切的来龙去脉。

1. 前言

Docker的生态系统日趋完善,开发者群体也在日趋庞大,这让业界对Docker持续抱有极其乐观的态度。然而,对于广大开发者而言,使用Docker这项技术已然不是门槛,享受Docker带来的技术福利已不是困难。如今,如何探寻Docker适应的场景,如何发展Docker周边的技术,以及如何弥合Docker新技术与传统物理机或VM技术的鸿沟,已经占据Docker研究者们的思考与实践。

本文为《Docker源码分析》第四篇——Docker Daemon之NewDaemon实现,力求帮助广大Docker爱好者更多得理解Docker 的核心——Docker Daemon的实现。

2. NewDaemon作用简介

在Docker架构中有很多重要的概念,如:graph,graphdriver,execdriver,networkdriver,volumes,Docker containers等。Docker的实现过程中,需要将以上实体进行统一化管理,而Docker Daemon中的daemon实例就是设计来完成这一任务。

从源码的角度,NewDaemon函数的执行出色的完成了Docker Daemon创建并加载daemon的任务,最终实现统一管理Docker Daemon的资源。

3. NewDaemon源码分析内容安排

本文从源码角度,分析Docker Daemon加载过程中NewDaemon的实现,整个分析过程如下图:

NewDaemon流程
4. NewDaemon具体实现

在《Docker源码分析》系列第三篇中,有一个重要的环节为:使用goroutine加载daemon对象并运行。在加载并运行daemon对象时,所做的第一个工作即为:

d, err := daemon.NewDaemon(daemonCfg, eng)

 

该部分代码分析如下:

  • 函数名:NewDaemon;
  • 函数调用具体实现所处的包位置:./docker/daemon
  • 函数具体实现源文件:./docker/daemon/daemon.go
  • 函数传入实参:daemonCfg,定义了Docker Daemon运行过程中所需的众多配置信息;eng,在mainDaemon中创建的engine对象实例;
  • 函数返回类型:d,具体的Daemon对象实例;err,错误状态。

进入./docker/daemon/daemon.go中NewDaemon的具体实现,代码如下


    func NewDaemon(config *Config, eng *engine.Engine) (*Daemon, error) {
        daemon, err := NewDaemonFromDirectory(config, eng)
        if err != nil {
            return nil, err
        }
        return daemon, nil
    }

 

可见,在实现NewDaemon的过程中,主要依靠NewDaemonFromDirectory函数来实现创建Daemon的运行环境。该函数的实现,传入参数以及返回类型与NewDaemon相同。下文将大篇幅分析其实现细节。

4.1. 应用配置信息

在NewDaemonFromDirectory的实现过程中,第一个工作是:如何应用传入的配置信息。这部分配置信息服务于Docker Daemon的运行,并在Docker Daemon启动初期就初始化完毕。配置信息的主要功能是:供用户自由配置Docker的可选功能,使得Docker的运行更贴近用户所期待的运行场景。

配置信息的处理包含4部分:

  • 配置Docker容器的MTU;
  • 检测网桥配置信息;
  • 查验容器通信配置;
  • 处理PID文件配置。

以下逐一分析配置信息的处理。

4.1.1. 配置Docker容器的MTU

config信息中的Mtu应用于容器网络的最大传输单元(MTU)特性。有关MTU的源码如下:

if config.Mtu == 0 {
            config.Mtu = GetDefaultNetworkMtu()
    }

 

如果config信息中Mtu的值为0的话,则通过GetDefaultNetworkMtu函数将Mtu设定为默认的值;否则,采用config中的Mtu值。由于在默认的配置文件./docker/daemon/config.go(下文简称为默认配置文件)中,初始化时Mtu属性值为0,故执行GetDefaultNetworkMtu。 GetDefaultNetworkMtu函数的具体实现位于./docker/daemon/config.go:


    func GetDefaultNetworkMtu() int {
        if iface, err := networkdriver.GetDefaultRouteIface(); err == nil {
            return iface.MTU
        }
        return defaultNetworkMtu
    }

 

GetDefaultNetworkMtu的实现中,通过networkdriver包的GetDefaultRouteIface方法获取具体的网络设备,若该网络设备存在,则返回该网络设备的MTU属性值;否则的话,返回默认的MTU值defaultNetworkMtu,值为1500。

4.1.2. 检测网桥配置信息

处理完config中的Mtu属性之后,马上检测config中BridgeIface和BridgeIP这两个信息。BridgeIface和BridgeIP的作用是为创建网桥的任务”init_networkdriver”提供参数。代码如下:

if config.BridgeIface != "" && config.BridgeIP != "" {
        return nil, fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one.")
    }

 

以上代码的含义为:若config中BridgeIface和BridgeIP两个属性均不为空,则返回nil对象,并返回错误信息,错误信息内容为:用户同时指定了BridgeIface和BridgeIP,这两个属性属于互斥类型,只能至多指定其中之一。在默认配置文件中,BridgeIface和BridgeIP均为空。

4.1.3. 查验容器通信配置

检测容器的通信配置,主要是针对config中的EnableIptables和InterContainerCommunication这两个属性。EnableIptables属性的作用是启用Docker对iptables规则的添加;InterContainerCommunication的作用是启动Docker container之间互相通信的功能。代码如下:

if !config.EnableIptables && !config.InterContainerCommunication {
        return nil, fmt.Errorf("You specified --iptables=false with --icc=false. ICC uses iptables to function. Please set --icc or --iptables to true.")
    }

 

代码含义为:若EnableIptables和InterContainerCommunication两个属性的值均为false,则返回nil对象以及错误信息。其中错误信息为:用户将以上两属性均置为false,container间通信需要iptables的支持,需设置至少其中之一为true。而在默认配置文件中,这两个属性的值均为true。

4.1.4. 处理网络功能配置

接着,处理config中的DisableNetwork属性,以备后续在创建并执行创建Docker Daemon网络环境时使用,即在名为”init_networkdriver”的job创建并运行中体现。

config.DisableNetwork = config.BridgeIface == DisableNetworkBridge

 

由于config中的DisableNetwork属性值为空,另外DisableNetworkBridge的值为字符串”none”,因此最终config中DisableNetwork的值为false。后续的”init_networkdriver”的job需要执行。

4.1.5. 处理PID文件配置

处理PID文件配置,主要工作为:为Docker Daemon运行时的PID号创建一个PID文件,文件的路径即为config中的Pidfile属性。并且为Docker Daemon的shutdown操作添加一个删除该Pidfile的函数,以便在D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值