containerd/containerd
Events
containerd publishes lifecycle events (image created, container started, task exited, …) through an in-process event exchange and forwards them onto a gRPC stream that any client can subscribe to. Code lives in core/events/, plugins/events/, and plugins/services/events/.
Purpose
- Decouple producers (the runtime, the image service, the metadata store) from consumers (CRI, metrics, third-party clients).
- Allow filtered subscriptions: a consumer can subscribe to
topic ~= "/tasks/.*"rather than receive everything. - Persist nothing — events are best-effort. A consumer that's slow loses old events.
Pieces
| Piece | File | Role |
|---|---|---|
| Event exchange | core/events/exchange/ |
In-process publisher/subscriber with topic filters |
| Event plugin | plugins/events/ |
Registers the exchange as the EventPlugin |
| gRPC events service | plugins/services/events/ |
Exposes Subscribe / Publish / Forward over gRPC |
| Event types | api/events/ |
Protobuf event types (TaskCreate, ImageDelete, …) |
| Filters | pkg/filters/ |
Field-path selectors used by subscriptions |
How publishing works
publisher := events.GetPublisher(ic) // from plugin InitContext
publisher.Publish(ctx, "/tasks/start", &eventstypes.TaskStart{...})Internally, the exchange writes to every subscriber's channel asynchronously. If a subscriber's channel is full, the event is dropped for that subscriber. The exchange is namespaced — a subscriber sees only events from its own namespace by default.
How subscribing works
ch, errCh := publisher.Subscribe(ctx, "topic~='/tasks/.*'")
for {
select {
case env := <-ch: ...
case err := <-errCh: ...
case <-ctx.Done(): return
}
}The CRI plugin uses this to drive its container status cache; ctr events uses it to print events to stdout.
Wire format
api/events/ defines the event type registry. Each event embeds a typeurl that the deserializer uses to dispatch to the right Go type. The events service envelopes them with topic, namespace, and timestamp (api/services/events/v1/events.proto).
Forward
The events service has a Forward RPC that lets one daemon's events be republished into another's exchange. This is used in test setups and in some multi-daemon deployments.
Entry points for modification
- New event type: add a
.protounderapi/events/, regenerate, and import a typeurl alias for it. - New subscriber pattern: use
pkg/filters/to compose aFilterand pass its string form toSubscribe. - Replace the exchange: register a new
EventPluginand disable the built-in.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.