概述
containerd的插件机制是个很重要的能力,降低了用户改造containerd的难度,其中bin类型插件的代表是shim-v2,而proxy类型插件的代表是snapshot。
details
LoadPlugins
cmd/containerd/builtins.go 通过init注册内部plugin
pluginType
const (
// InternalPlugin implements an internal plugin to containerd
InternalPlugin Type = "io.containerd.internal.v1"
// RuntimePlugin implements a runtime
RuntimePlugin Type = "io.containerd.runtime.v1"
// RuntimePluginV2 implements a runtime v2
RuntimePluginV2 Type = "io.containerd.runtime.v2"
// ServicePlugin implements a internal service
ServicePlugin Type = "io.containerd.service.v1"
// GRPCPlugin implements a grpc service
GRPCPlugin Type = "io.containerd.grpc.v1"
// TTRPCPlugin implements a ttrpc shim service
TTRPCPlugin Type = "io.containerd.ttrpc.v1"
// SnapshotPlugin implements a snapshotter
SnapshotPlugin Type = "io.containerd.snapshotter.v1"
// TaskMonitorPlugin implements a task monitor
TaskMonitorPlugin Type = "io.containerd.monitor.v1"
// DiffPlugin implements a differ
DiffPlugin Type = "io.containerd.differ.v1"
// MetadataPlugin implements a metadata store
MetadataPlugin Type = "io.containerd.metadata.v1"
// ContentPlugin implements a content store
ContentPlugin Type = "io.containerd.content.v1"
// GCPlugin implements garbage collection policy
GCPlugin Type = "io.containerd.gc.v1"
// EventPlugin implements event handling
EventPlugin Type = "io.containerd.event.v1"
// TracingProcessorPlugin implements a open telemetry span processor
TracingProcessorPlugin Type = "io.containerd.tracing.processor.v1"
)
plugin impl kind
- binary: 比如shim-v2,直接根据PATH调用二进制
- proxy: 通过sock文件访问,需要plugin主动用plugin.Register注册,例如snapshot plugin
- in-tree: 直接放入源码,通过plugin.Register注册
snapshotter 单独部署为容器,将sock path加入到containerd的配置文件中
# The `address` field specifies through which socket snapshotter and containerd communicate.
[proxy_plugins]
[proxy_plugins.nydus]
type = "snapshot"
address = "/run/containerd-nydus/containerd-nydus-grpc.sock"
impl
snapshotter
- snapshotter进行了插件化,例如containerd官方项目下就有其他snapshotter的插件。
- snapshotter和OCI那套镜像manifest没关系,那套东西由content service管理
- Snapshotter接口只是抽象出了rootfs准备过程中的各个阶段,调用这些方法的实体是diff
type Snapshotter interface {
Stat(ctx context.Context, key string) (Info, error)
Update(ctx context.Context, info Info, fieldpaths ...string) (Info, error)
Usage(ctx context.Context, key string) (Usage, error)
Mounts(ctx context.Context, key string) ([]mount.Mount, error)
Prepare(ctx context.Context, key, parent string, opts ...Opt) ([]mount.Mount, error)
View(ctx context.Context, key, parent string, opts ...Opt) ([]mount.Mount, error)
Commit(ctx context.Context, name, key string, opts ...Opt) error
Remove(ctx context.Context, key string) error
Walk(ctx context.Context, fn WalkFunc, filters ...string) error
Close() error
}
// snapshots/native/native.go
type snapshotter struct {
root string
ms *storage.MetaStore
}
rootfs/apply.go
containerd的rootfs/apply负责真正调用snapshotter。applyLayers 是被image.go的Unpack方法调用的。
// applyLayers
mounts, err = sn.Prepare(ctx, key, parent.String(), opts...)
diff, err = a.Apply(ctx, layer.Blob, mounts, applyOpts...)
err = sn.Commit(ctx, chainID.String(), key, opts...)
content
- api/services/content/v1/content.pb.go
- services/content/contentserver/contentserver.go
- metadata/content.go