所有文章

DOCKER源码-启动流程

dockerd启动流程

  1. 当用户执行命令systemctl start docker后,systemd检查docker配置文件/usr/lib/systemd/system/docker.service

  2. 因为docker配置文件中定义了BindsTo=containerd.service,所以containerd将先启动。

  3. 如果containerd启动失败,那么dockerd也将启动失败。

  4. containerd启动成功后,dockerd二进制文件开始启动,开始执行main()函数。

  5. dockerd程序的main函数所在文件:cmd/dockerd/docker.go

  6. main函数中的调用的newDaemonCommand()函数用于构建一个Command对象,该对象定义如下:

    cmd := &cobra.Command{
            Use:           "dockerd [OPTIONS]",
            Short:         "A self-sufficient runtime for containers.",
            SilenceUsage:  true,
            SilenceErrors: true,
            Args:          cli.NoArgs,
            RunE: func(cmd *cobra.Command, args []string) error {
                opts.flags = cmd.Flags()
                return runDaemon(opts)
            },
            DisableFlagsInUseLine: true,
            Version:               fmt.Sprintf("%s, build %s", dockerversion.Version, dockerversion.GitCommit),
        }
    
  7. Command对象中的RunE字段就是用来启动dockerd的函数,它最终调用了DaemonCli.start()函数,DaemonCli定义:
    cmd/dockerd/daemon.go

    type DaemonCli struct {
        *config.Config
        configFile *string
        flags      *pflag.FlagSet
        api             *apiserver.Server
        d               *daemon.Daemon
        authzMiddleware *authorization.Middleware
    }
    
  8. DaemonCli实例中的start()函数是dockerd启动的主要逻辑,主要包含以下事项:

    • 从命令行中加载日志相关参数,并配置logrus日志对象
    • 根据命令行参数判断是否打开Debug模式,是否打开实验特性
    • 创建--data-root目录
    • 创建PID文件
    • 是否启用无root模式
    • 加载API Server相关配置,包括证书
    • 创建API Server,但现在不启动
    • 创建一个协程与containerd保持心跳,如果连接containerd失败,则dockerd启动失败
    • 监听信号量并设置hook函数用于释放DaemonCli对象
    • 创建Daemon实例,创建Daemon的过程中创建了几个重要对象(这里只列出部分,后面会细讲):
      • containerd:负责容器相关操作,且依赖一个RPC客户端,大部分容器相关操作都通过RPC调用containerd进程来完成
      • volumes:负责volume的创建、查找、删除等
      • imageService:负责镜像相关操作
      • netController:负责网络设备的相关操作
    • 将Daemon对象放入DaemonCli对象中
    • 启动Metrics服务,默认地址:unix:/var/run/docker/metrics.sock
    • 如果之前配置过swarm的话,则重新加入集群,并启动集群总的服务
    • 构建API路由:用Daemon对象中包含的各核心功能与API Path对应起来
    • 启动API Server,默认地址:unix:/var/run/docker.sock
    • 阻塞直到API Server协程发生错误或完成退出后,结束各个协程

Daemon结构体

以下是Daemon结构体的定义,在19.03.7版本中包含40个字段,下面我们只分析几个重要字段:
daemon/daemon.go

type Daemon struct {
    // ... 省略多行 ...
    repository        string
    containers        container.Store
    containersReplica container.ViewDB
    execCommands      *exec.Store
    imageService      *images.ImageService
    netController     libnetwork.NetworkController
    volumes           *volumesservice.VolumesService
    discoveryWatcher  discovery.Reloader
    root              string
    graphDrivers map[string]string // By operating system
    containerdCli         *containerd.Client
    containerd            libcontainerdtypes.Client
    // ... 省略多行 ...
}

字段说明:

相关文章


编写日期:2020-03-13