Open-Source Wikis

/

Kubernetes

/

Components

/

REST registry layer

kubernetes/kubernetes

REST registry layer

Every Kubernetes resource served by kube-apiserver is wired up through the same generic-storage pattern. This page explains what that pattern looks like and how to add or modify a resource.

The two halves of a resource

Each resource has two implementations in this repo:

  1. Versioned external types in staging/src/k8s.io/api/<group>/<version>/types.go. These are the YAML/JSON shape of the object as seen by clients.
  2. Internal types and registry plumbing in pkg/apis/<group>/ (internal types, conversion to/from external versions, validation, defaulting) and pkg/registry/<group>/<resource>/ (REST handlers, strategy, storage wiring).

Conversion between an external version and the internal hub type is generated by conversion-gen and lives in zz_generated_conversion.go files under pkg/apis/<group>/<version>/.

What a registry directory contains

A typical resource directory in pkg/registry/:

pkg/registry/apps/deployment/
├── doc.go
├── strategy.go              # Validation, defaulting, prepare-for-create/update
├── storage/
│   └── storage.go           # REST endpoint construction; subresources (status, scale)
└── ...

strategy.go implements the rest.RESTCreateUpdateStrategy (and friends) interface from staging/src/k8s.io/apiserver/pkg/registry/rest. The methods it implements are the per-resource hooks the generic store calls during a write:

  • PrepareForCreate(ctx, obj) — strip status, generate a UID, etc.
  • Validate(ctx, obj) — call into pkg/apis/<group>/validation/
  • Canonicalize(obj) — normalize ordering, defaults
  • AllowCreateOnUpdate(), AllowUnconditionalUpdate() — concurrency knobs
  • PrepareForUpdate(ctx, newObj, oldObj) — preserve status, set generation
  • ValidateUpdate(ctx, newObj, oldObj) — reject illegal transitions
  • WarningsOnCreate(ctx, obj) / WarningsOnUpdate(ctx, newObj, oldObj) — non-fatal warnings to the client

storage/storage.go constructs a *genericregistry.Store configured with:

  • NewFunc / NewListFunc — type constructors
  • KeyFunc / KeyRootFunc — etcd key shape (e.g. /deployments/<namespace>/<name>)
  • Strategy — the strategy from strategy.go
  • TableConvertor — for kubectl get -o wide output
  • Subresource storage (e.g. status, scale) when applicable

Registration

The kube-apiserver knows about a resource because pkg/controlplane/instance.go (or the equivalent in pkg/controlplane/apiserver/) builds a RESTStorageProvider per group and feeds it to genericapiserver.GenericAPIServer.InstallAPIGroup. Each provider lives in pkg/registry/<group>/rest/storage_<group>.go and chooses which versions and subresources to install based on feature gates.

Example (paraphrased):

storage := map[string]rest.Storage{}
if resourceEnabled("apps", "v1", "deployments") {
    deployStorage, err := deploymentstore.NewStorage(restOptionsGetter)
    storage["deployments"]         = deployStorage.Deployment
    storage["deployments/status"]  = deployStorage.Status
    storage["deployments/scale"]   = deployStorage.Scale
}

The restOptionsGetter carries etcd config, watch-cache settings, and encryption transformer per resource.

The watch cache

Reads do not normally hit etcd. The generic store wraps every storage with pkg/storage/cacher (in staging/src/k8s.io/apiserver/pkg/storage/cacher). The cacher:

  • Watches etcd at revision=0, populates a thread-safe ring buffer.
  • Serves LIST from the ring with the requested resourceVersion semantics (Exact, NotOlderThan, etc.).
  • Serves WATCH by replaying ring events from the requested resource version.
  • Serves CONSISTENT_READS (a recent feature) by combining cache state with an etcd revision callback.

This is the reason a 5,000-node cluster can sustain many thousands of watches without hammering etcd directly.

Server-side apply

The generic store supports Apply (the application/apply-patch+yaml content type) via staging/src/k8s.io/apiserver/pkg/endpoints/handlers/apply.go. The merge logic uses field-managed metadata stored alongside each object. Apply configurations (typed builders) are codegen'd into staging/src/k8s.io/client-go/applyconfigurations/.

Adding a new resource: checklist

  1. Define versioned types in staging/src/k8s.io/api/<group>/<version>/types.go with +k8s: tags.
  2. Define internal types in pkg/apis/<group>/types.go.
  3. Run hack/update-codegen.sh to generate deepcopy, conversion, defaulter, openapi, clientset, informer, lister, applyconfiguration.
  4. Implement validation in pkg/apis/<group>/validation/validation.go.
  5. Implement strategy in pkg/registry/<group>/<resource>/strategy.go.
  6. Implement storage in pkg/registry/<group>/<resource>/storage/storage.go.
  7. Register in pkg/registry/<group>/rest/storage_<group>.go.
  8. Add a feature gate in pkg/features/kube_features.go if alpha.
  9. Add tests at every layer (validation_test.go, strategy_test.go, storage_test.go, plus test/integration/<group>/).

The sample-apiserver staging module is a working minimal example you can copy.

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

REST registry layer – Kubernetes wiki | Factory