Docker源码分析三:启动Docker Daemon
Docker Daemon是Docker架构中运行在后台的守护进程,大致可以分为Docker Server、Engine和Job部分。三者的关系大致如下:Docker Daemon通过Docker Server模块接收Docker Client的请求,并在Engine处理请求,然后根据请求类型,创建出指定的Job并运行。本文基于Docker 18.02.0-ce的源码分析Docker Daemon的启动相关内容。
Daemon的main函数位于docker-ce/components/engine/cmd/dockerd/docker.go文件中,如下:
func main() {
if reexec.Init() {
return
}
// Set terminal emulation based on platform as required.
_, stdout, stderr := term.StdStreams()
// @jhowardmsft - maybe there is a historic reason why on non-Windows, stderr is used
// here. However, on Windows it makes no sense and there is no need.
if runtime.GOOS == "windows" {
logrus.SetOutput(stdout)
} else {
logrus.SetOutput(stderr)
}
// 创建cmd
cmd := newDaemonCommand()
cmd.SetOutput(stdout)
// 执行cmd
if err := cmd.Execute(); err != nil {
fmt.Fprintf(stderr, "%s\n", err)
os.Exit(1)
}
}
func newDaemonCommand() *cobra.Command {
opts := newDaemonOptions(config.New())
cmd := &cobra.Command{
Use: "dockerd [OPTIONS]", // 命令用法
Short: "A self-sufficient runtime for containers.", // help时输出的命令提示信息
SilenceUsage: true,
SilenceErrors: true,
Args: cli.NoArgs,
// 命令的执行时的回调函数
RunE: func(cmd *cobra.Command, args []string) error {
opts.flags = cmd.Flags()
return runDaemon(opts) // 接受命令行参数执行启动函数
},
}
// 为根命令设置usage, help等命令及错误处理
cli.SetupRootCommand(cmd)
// 新建一个flag
flags := cmd.Flags()
// 添加-v查看版本的参数
flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit")
// 添加-config-file参数
flags.StringVar(&opts.configFile, "config-file", defaultDaemonConfigFile, "Daemon configuration file")
opts.InstallFlags(flags)
installConfigFlags(opts.daemonConfig, flags)
installServiceFlags(flags)
return cmd
}
// 命令的执行方法
func runDaemon(opts *daemonOptions) error {
if opts.version {
showVersion() // 打印出版本信息
return nil
}
// 新建一个daemon CLI
daemonCli := NewDaemonCli()
// Windows specific settings as these are not defaulted.
if runtime.GOOS == "windows" {
if opts.daemonConfig.Pidfile ==