[containerd] 初始化流程概览

containerd初始化流程详解
文章详细分析了containerd的初始化流程,包括加载配置、创建目录、处理信号、清理临时目录、实例化服务器、开启调试接口和暴露服务。重点讨论了Action方法中的主要操作,如加载配置、监听信号、实例化containerdserver以及加载和注册插件等步骤。

1. 环境

2. 初始化流程

  containerd的入口为:cmd/containerd/main.go,如下:

func main() {
   
   
	// TODO 实例化containerd
	app := command.App()
	// 实际上这里的app是一个命令行工具封装的,app.Run的运行也是固定的,主要是为了执行app.Action,所以只需要重点分析app.Action干了啥
	if err := app.Run(os.Args); err != nil {
   
   
		fmt.Fprintf(os.Stderr, "containerd: %s\n", err)
		os.Exit(1)
	}
}

  这里的App实际上一个命令行工具的封装,这里执行app.Run的时候实际上执行的时AppAction方法,因此我们需要关心的是containerd是如何实现这个Action

  不过,话说回来,在如今cobra大行其道的时候,containerd居然会使用urfave这个命令行工具,这个工具相比于cobra有何优略势以后倒是可以研究下。

  containerd实现的App有很多细节我们并不需要关心,这里我们重点关心containerd是如何实现Action方法的,毕竟,containerd开始运行后,第一时间就是执行Action方法

func App() *cli.App {
   
   
	... // 省略不需要太关心的代码
	app.Action = func(context *cli.Context) error {
   
   
		var (
			start       = time.Now()
			signals     = make(chan os.Signal, 2048)
			serverC     = make(chan *server.Server, 1)
			ctx, cancel = gocontext.WithCancel(gocontext.Background())
			config      = defaultConfig()
		)

		defer cancel()

		// Only try to load the config if it either exists, or the user explicitly
		// told us to load this6 path.
		configPath := context.GlobalString("config") // 获取配置文件路径
		_, err := os.Stat(configPath)
		if !os.IsNotExist(err) || context.GlobalIsSet("config") {
   
   
			if err := srvconfig.LoadConfig(configPath, config); err != nil {
   
   
				return err
			}
		}

		// Apply flags to the config 解析/etc/containerd/config.toml配置文件到config对象当中
		if err := applyFlags(context, config); err != nil {
   
   
			return err
		}

		if config.GRPC.Address == "" {
   
   
			return fmt.Errorf("grpc address cannot be empty: %w", errdefs.ErrInvalidArgument)
		}
		if config.TTRPC.Address == "" {
   
   
			// If TTRPC was not explicitly configured, use defaults based on GRPC.
			config.TTRPC.Address = config.GRPC.Address + ".ttrpc"
			config.TTRPC.UID = config.GRPC.UID
			config.TTRPC.GID = config.GRPC.GID
		}

		// Make sure top-level directories are created early. 确保一些目录必须存在
		if err := server.CreateTopLevelDirectories(config); err != nil {
   
   
			return err
		}

		// Stop if we are registering or unregistering against Windows SCM. 仅和Windows有关
		stop, err := registerUnregisterService(config.Root)
		if err != nil {
   
   
			logrus.Fatal(err)
		}
		if stop {
   
   
			return nil
		}

		done := handleSignals(ctx, signals, serverC, cancel) // 处理退出信号
		// start the signal handler as soon as we can to make sure that
		// we don't miss any signals during boot
		signal.Notify(signals, handledSignals...)

		// cleanup temp mounts
		if err := mount.SetTempMountLocation(filepath.Join(config.Root, "tmpmounts")); err != nil {
   
   
			return fmt.Errorf("creating temp mount location: %w", err)
		}
		// unmount all temp mounts on boot for the server
		warnings, err := mount.CleanupTempMounts(0)
		if err != nil {
   
   
			log.G(ctx).WithError(err).Error("unmounting temp mounts")
		}
		for _, w :=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值