docker run源码分析(二)之Docker daemon--container create

本文探讨了Docker daemon在接收到Docker client的`docker run`请求后的处理,重点分析了Docker daemon的结构,包括Docker Server、Engine和Job,并详细解析了container创建的源码流程,涉及postContainersCreate、ContainerCreate和create函数,阐述了从接收请求到创建容器的步骤,如合并配置、创建容器对象和网络配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇文章咱们分析了docker run命令在Docker client中的处理,这一篇文章咱们分析在Docker daemon中的处理。

Docker client发送容器管理请求,由Docker daemon接收并处理。源码基于Docker-ce17.09

1、所谓“运行docker”,即运行Docker daemon。其主要有两方面的作用:

  • 接收并处理 Docker Client 发送的请求。

  • 管理所有的 Docker 容器。

Docker Daemon 运行时,会在后台启动一个 Server Se er 负责接收 Docker Client 发送 的请求;接收请求后, Server 通过路由与分发调度,找到相应的 Handler 来处理请求。

2、Docker daemon的结构分布:

Docker Server、Docker Engine 和 Docker Job。

2.1、Docker Server

Docker Server Docker 架构中专门服务于 Docker Client ,它的功能是接收并调度分发 Docker Client 发送的请求。

2.2、Docker Engine

Engine Docker 架构中的运行引擎,同时也是 Docker 运行的核心模块。 Engine 存储着 大量的容器信息,同时管理着 Docker 大部分 Job 的执行。在Docker 源码中,有关 Engine 的数据结构定义中含有一个名为 handlers 的对象。该 handlers 对象存储的是关于众多特定 Job 各自的处理方式 handler。

2.3、Docker Job

Job 可以认为是 Docker 架构中 Engine 内部最基本的工作执行单元。DockerDaemon 以完成的每一项工作都会呈现为一个Job 。例如,在 Docker 容器内部运行一个进程,这是 一个 Job; 创建一个新的容器,这是一个 Job; 在网络上下载一个文档,这是一个 Job; 包括 之前在 Docker Server 部分谈及的,创建 Server 服务于 HTTP 协议的 API ,这也是一个 Job 等等。

对于 Job 而言,定义完毕之后,运行才能完成 Job 自身真正的使命。 Job 的运行函数 RunO 则用以执行 Job 本身。

3、

在上一篇中,ContainerCreate()ContainerStart()分别向daemon发送了create和start命令。还是从docker engine的main()函数开始:

2.2、源码:newDaemonCommand()

func newDaemonCommand() *cobra.Command {
	//获取配置信息
	opts := newDaemonOptions(config.New())
	//docker daemon命令行对象,与docker client分析的一样
	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()
			//daemon command执行时,执行该函数
			return runDaemon(opts)
		},
	}
	cli.SetupRootCommand(cmd)

	//解析命令
	flags := cmd.Flags()
	//设置docker daemon启动的时候是否使用了version等一些命令
	flags.BoolVarP(&opts.version, "version", "v", false, "Print version information and quit")
	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客户端对象
	daemonCli := NewDaemonCli()

	// Windows specific settings as these are not defaulted.
	if runtime.GOOS == "windows" {
		if opts.daemonConfig.Pidfile == "" {
			opts.daemonConfig.Pidfile = filepath.Join(opts.daemonConfig.Root, "docker.pid")
		}
		if opts.configFile == "" {
			opts.configFile = filepath.Join(opts.daemonConfig.Root, `config\daemon.json`)
		}
	}

	// 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
	}

	// If Windows SCM manages the service - no need for PID files
	if runAsService {
		opts.daemonConfig.Pidfile = ""
	}

	//启动daemonCli
	err = daemonCli.start(opts)
	notifyShutdown(err)
	return err
}
// NewDaemonCli returns a daemon CLI
func NewDaemonCli() *DaemonCli {
	return &DaemonCli{}
}


// DaemonCli represents the daemon CLI.
type DaemonCli struct {
	*config.Config      //配置信息
	configFile *string     //配置文件
	flags      *pflag.FlagSet    //flag参数信息

	api             *apiserver.Server   //APIServer:提供api服务,定位在/engine/api/server/server.go
	d               *daemon.Daemon       //Daemon对象,结构体定义在/engine/daemon/daemon.go
	authzMiddleware *authorization.Middleware // authzMiddleware enables to dynamically reload the authorization plugins
}

位置:Server 结构体    Daemon 结构体

2.3、

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值