1. 环境
containerd版本:v1.7.2,containerd debug搭建教程链接- 操作系统:
Ubuntu22.04
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的时候实际上执行的时App的Action方法,因此我们需要关心的是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 :=
containerd初始化流程详解

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

被折叠的 条评论
为什么被折叠?



