Open-Source Wikis

/

containerd

/

Systems

/

Metadata store

containerd/containerd

Metadata store

A bbolt-backed key/value store at plugins/metadata/ that holds everything that isn't a blob: images, containers, leases, sandboxes, namespaces, snapshot metadata, and label sidecars on content blobs.

Purpose

  • Provide ACID-ish updates (bbolt is single-writer) for objects that need to be queried by id, by labels, or by reference.
  • Wrap the content store and snapshotters so that labels on those blobs/snapshots are tracked here even though their payloads live elsewhere.
  • Be the canonical source of truth for the GC reference graph.

Directory layout

core/metadata/
├── images.go         # image manifest store
├── containers.go     # container CRUD
├── leases.go         # lease manager wrapper
├── sandboxes.go      # sandbox metadata
├── snapshotter.go    # snapshotter wrapper that stores labels and indexes
├── content.go        # content store wrapper
├── namespaces.go
├── gc.go             # GC reference walker (the shaving brush)
└── ...

plugins/metadata/
└── ...               # plugin registration; opens a single bbolt db file

Bbolt schema

The metadata store packs everything into a single meta.db file under the plugin's root directory (e.g. /var/lib/containerd/io.containerd.metadata.v1.bolt/meta.db). Top-level structure:

v1/                         (schema version)
└── <namespace>/
    ├── containers/<id>/    (labels, image, snapshotter, runtime, spec, ...)
    ├── images/<name>/      (target descriptor + labels)
    ├── leases/<id>/        (resources owned by the lease)
    ├── sandboxes/<id>/     (sandbox state)
    ├── snapshots/<name>/   (snapshotter labels indexed by snapshotter id)
    └── content/blob/<digest>/ (blob labels)

The schema version is bumped on incompatible changes; the migration logic lives in plugins/metadata/migrations.go.

Key abstractions

Type File Purpose
metadata.DB plugins/metadata/db.go The bbolt database wrapper, exposes Init, View, Update, GarbageCollect
metadata.imageStore core/metadata/images.go Implements images.Store over bbolt
metadata.containerStore core/metadata/containers.go Implements containers.Store
metadata.snapshotter core/metadata/snapshotter.go Wraps a real snapshotter and stores labels in bbolt
metadata.contentStore core/metadata/content.go Wraps the local content store and stores labels in bbolt
metadata.GCRoots core/metadata/gc.go Iterator over GC roots; consumed by the GC scheduler

How writes propagate

Updates to an image, container, or lease are wrapped in a single bbolt transaction. If the request also touches the content store (e.g. a label update on a blob), the update goes through the metadata.contentStore wrapper — the wrapper reads/writes labels in the bbolt transaction and delegates the content-side update to the underlying content store. This keeps the two views consistent.

Snapshotter integration

metadata.snapshotter wraps an underlying snapshotter and stores per-snapshot labels and namespacing metadata in bbolt:

  • The bbolt key holds the labels and the namespace.
  • The underlying snapshotter holds the actual snapshot data.

This allows the metadata store to participate in GC: it knows which snapshots are referenced by which containers and which leases.

GC integration

core/metadata/gc.go walks the bbolt buckets to enumerate GC roots:

  • Containers' image and snapshot references
  • Leased resources
  • Image manifest descendants (manifests → layers → blobs)
  • Sandbox-related blobs and snapshots

The walker emits gc.Node records that the scheduler in plugins/gc/ consumes. See GC.

Concurrency

bbolt allows a single writer at a time. The metadata package serializes writes through bbolt's Update transaction. Reads use View and are non-blocking against each other. Long-running reads that span many keys (typically GC scans) hold a snapshot view and don't block writers.

Entry points for modification

  • Add a new object type: define a bucket layout under core/metadata/, implement a Store interface, and add a migration step in plugins/metadata/migrations.go.
  • Add a new GC reference: extend the references function in core/metadata/gc.go. Be careful — missing a reference here causes silent data loss when the GC runs.
  • Schema upgrade: add a migration entry that runs once on first open of the new version.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Metadata store – containerd wiki | Factory