【編者的話】containerd v1.0.0的源碼分析祝钢,以docker-containerd --config /var/run/docker/containerd/containerd.toml
為入口,看大神們?nèi)绾谓M織Go語(yǔ)言代碼
分析
程序信號(hào)處理
- 位置:
cmd/containerd/main.go
...
var (
signals = make(chan os.Signal, 2048)
ctx = log.WithModule(gocontext.Background(), "containerd")
)
done := handleSignals(ctx, signals, serverC)
...
signal.Notify(signals, handledSignals...)
...
<-done
...
初始化服務(wù)
- 位置:
cmd/containerd/main.go
...
server, err := server.New(ctx, config)
if err != nil {
return err
}
...
開啟debug / metrics / grpc服務(wù)
- 位置:
cmd/containerd/main.go
- 依賴:
github.com/docker/go-metrics
github.com/grpc-ecosystem/go-grpc-prometheus
...
if config.Debug.Address != "" {
l, err := sys.GetLocalListener(config.Debug.Address, config.Debug.UID, config.Debug.GID)
if err != nil {
return errors.Wrapf(err, "failed to get listener for debug endpoint")
}
serve(log.WithModule(ctx, "debug"), l, server.ServeDebug)
}
if config.Metrics.Address != "" {
l, err := net.Listen("tcp", config.Metrics.Address)
if err != nil {
return errors.Wrapf(err, "failed to get listener for metrics endpoint")
}
serve(log.WithModule(ctx, "metrics"), l, server.ServeMetrics)
}
l, err := sys.GetLocalListener(address, config.GRPC.UID, config.GRPC.GID)
if err != nil {
return errors.Wrapf(err, "failed to get listener for main endpoint")
}
serve(log.WithModule(ctx, "grpc"), l, server.ServeGRPC)
...
containerd架構(gòu)
初始化服務(wù)解析
載入插件
- 位置:
server/server.go
plugins, err := loadPlugins(config)
if err != nil {
return nil, err
}
初始化 grpc服務(wù) 和 傳輸服務(wù)
- 位置:
server/server.go
type Server struct {
rpc *grpc.Server
events *exchange.Exchange
}
grpc服務(wù)
- 位置:
server/server.go
- 依賴:
google.golang.org/grpc
github.com/grpc-ecosystem/go-grpc-prometheus
rpc := grpc.NewServer(
grpc.UnaryInterceptor(interceptor),
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
)
傳輸服務(wù)
- 位置:
events/exchange/exchange.go
- 作用:負(fù)責(zé)傳播事件
- 依賴:github.com/docker/go-events
// Exchange broadcasts events
type Exchange struct {
broadcaster *goevents.Broadcaster
}