containerd插件机制(proxy)初探

419 阅读2分钟

概述

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

ref

docs/PLUGINS.md

What is a containerd snapshotter