docker源码解析(一)dockerd服务的启动

本文深入解析Docker的源码,主要关注在Linux和Windows平台上的启动流程,包括main函数、newDaemonCommand()、runDaemon()函数。在Linux上,启动过程涉及设置日志、配置Docker目录、创建守护进程、初始化containerd等。在Windows平台,Docker会处理特定的设置,如服务注册。此外,文章还介绍了Docker的配置文件默认值、新守护进程的创建以及与containerd的交互。

本文源码基于docker20.10.8。文中机器安装的docker代码版本为docker20.10.0。
本文的计算机环境是centos-8。因此,不介绍Windows平台的docker。
docker源码地址

参考文献
1. docker的初始化——by lovenashbest-简书
Docker - NewDaemon源码分析——by ETIN-知乎
docker 源码分析NewDaemon 函数——by arwen_spy-博客园

部分参数默认值

Config.Root				/var/lib/docker
Config.ExecRoot			/var/run/docker
Config.Pidfile			/var/run/docker.pid
imageRoot				/var/lib/docker/image/文件系统(linux为overlay2)/

main函数入口

代码位置:/moby/cmd/dockerd/docker.go:

func main() {
   
   
	if reexec.Init() {
   
   
		return
	}

	// initial log formatting; this setting is updated after the daemon configuration is loaded.
	logrus.SetFormatter(&logrus.TextFormatter{
   
   
		TimestampFormat: jsonmessage.RFC3339NanoFixed,
		FullTimestamp:   true,
	})

	// Set terminal emulation based on platform as required.
	_, stdout, stderr := term.StdStreams()

	initLogging(stdout, stderr)

	onError := func(err error) {
   
   
		fmt.Fprintf(stderr, "%s\n", err)
		os.Exit(1)
	}

	cmd, err := newDaemonCommand()
	if err != nil {
   
   
		onError(err)
	}
	cmd.SetOutput(stdout)
	if err := cmd.Execute(); err != nil {
   
   
		onError(err)
	}
}

首先判断reexec.Init()方法的返回值,如果是真,则直接退出运行,否则继续执行。由于在docker运行之前,没有任何initializer注册,所以这段代码执行的返回值为假。

随后调用newDaemonCommand()函数,启动Daemon。

newDaemonCommand()函数

代码路径:/moby/cmd/dockerd/docker.go

func newDaemonCommand() (*cobra.Command, error) {
   
   
	opts := newDaemonOptions(config.New())

	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),
	}
	cli.SetupRootCommand(cmd)

	flags := cmd.Flags()
	flags.BoolP("version", "v", false, "Print version information and quit")
	defaultDaemonConfigFile, err := getDefaultDaemonConfigFile()
	if err != nil {
   
   
		return nil, err
	}
	flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "Daemon configuration file")
	opts.InstallFlags(flags)
	if err := installConfigFlags(opts.daemonConfig, flags); err != nil {
   
   
		return nil, err
	}
	installServiceFlags(flags)

	return cmd, nil
}

首先调用newDaemonOptions()创建flag参数。

然后调用runDaemon()函数。

runDaemon()函数

Windows平台

Windows平台,代码路径:/moby/cmd/dockerd/docker_windows.go

func runDaemon(opts *daemonOptions) error {
   
   
	daemonCli := NewDaemonCli()

	// On Windows, this may be launching as a service or with an option to
	// register the service.
	stop, runAsService, err := initService(daemonCli)
	if err != nil {
   
   
		logrus.Fatal(err)
	}

	if stop {
   
   
		return nil
	}

	// Windows specific settings as these are not defaulted.
	if opts.configFile == "" {
   
   
		opts.configFile = filepath.Join(opts.daemonConfig.Root, `config\daemon.json`)
	}
	if runAsService {
   
   
		// If Windows SCM manages the service - no need for PID files
		opts.daemonConfig.Pidfile = ""
	} else if opts.daemonConfig.Pidfile == "" {
   
   
		opts.daemonConfig.Pidfile = filepath.Join(opts.daemonConfig.Root, "docker.pid")
	}

	err = daemonCli.start(opts)
	notifyShutdown(err)
	return err
}

linux平台

代码路径:/moby/cmd/dockerd/docker_unix.go

func runDaemon(opts *daemonOptions) error {
   
   
	daemonCli := NewDaemonCli()
	return daemonCli.start(opts)
}

代码路径:/moby/cmd/dockerd/daemon.go

首先调用NewDaemonCli()申请了一个结构体实例。

// NewDaemonCli returns a daemon CLI
func NewDaemonCli() *DaemonCli {
   
   
	return &DaemonCli{
   
   }
}

随后调用start()函数。

daemonCli.start()函数

代码路径:/moby/cmd/dockerd/daemon.go

func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
   
   
	opts.SetDefaultOptions(opts.flags)		//TLS加密配置

	loadDaemonCliConfig(opts
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值