Skip to content

Source-Reading Corpus: k/k Packages, KEPs and Design Docs per Depth Area

Resolves k3ii/k8s-academy#3. Parent map: #1.

Verified 2026-08-17 against kubernetes/kubernetes@master (tree pushed 2026-08-17T12:50Z, CHANGELOG-1.37 in development), kubernetes/enhancements@master, kubernetes/community@main, kubernetes/design-proposals-archive@main, etcd-io/etcd@main (k/k vendors go.etcd.io/etcd/* v3.7.0), etcd-io/raft@main, containernetworking/cni@main, container-storage-interface/spec@master, kubernetes-sigs/gateway-api@main, cilium/cilium@main.

Every path below was checked to exist today via the git-tree API. All 69 KEP numbers, titles and statuses were read out of each KEP's own kep.yaml — none are cited from memory. Byte sizes are quoted where they drive the difficulty rating; a 156 KB file is hostile no matter how simple the concept.


How to read the difficulty markers

The learner is a complete Kubernetes beginner and a solid programmer who will be reading Go, not writing it. That combination makes file size and self-containment matter more than language sophistication. Markers:

Marker Meaning
[A] Approachable Readable from Phase 1–2. Self-contained, well-commented, no prior k8s-internals vocabulary needed beyond "what is a Pod".
[B] Grounded Needs ~one phase of grounding: has run a cluster, knows the object model (GVK, spec/status, labels/selectors, resourceVersion).
[C] Deep Needs two-plus phases. Assumes fluency with informers, the reconcile pattern, and the apiserver request path.
[D] Reference-only / hostile Do not assign as linear reading. Grep it, or read a named function with a guide. Assigning these early is the single biggest way to stall the learner.

Three standing traps for this curriculum:

  1. staging/src/k8s.io/api/core/v1/types.go is 471 KB. It is the canonical Pod/Service/PV type reference and its doc comments are excellent — but it is a lookup table, never a read. Always point at a line range or type name, never the file.
  2. Most staging/src/k8s.io/*/README.md files are ~1.5 KB boilerplate ("this is a staging repo, do not file issues here"). Only four are worth reading; they are named in the Foundational section. Recommending "the staging READMEs" wholesale wastes the learner's time.
  3. apimachinery is where beginners drown. runtime.Scheme, codec chains and the conversion/defaulting generators are genuinely necessary for control-plane mastery but are terrible first reading. They are deferred to [C] throughout, and the Foundational section gives the doc-first substitute.

Area 0 — Foundational reading

Read essentially all of this before opening Go source. This section is the cheapest leverage in the whole corpus, and most of it is prose, not code.

Ordered approachable → hard:

# Item Teaches Difficulty
1 Borg paper — "Large-scale cluster management at Google with Borg" (Verma et al., EuroSys 2015) · https://research.google/pubs/large-scale-cluster-management-at-google-with-borg/ Why Kubernetes is shaped the way it is: declarative specs, allocs→pods, priority/preemption, and the bin-packing economics that justify a scheduler at all. Read §2 (workload/priority), §5 (scalability), §8 (lessons → the k8s section). [A]
2 architecture/architecture.md — https://github.com/kubernetes/design-proposals-archive/blob/main/architecture/architecture.md The original architecture design doc: control plane vs node components, the "level-triggered, edge-driven" reconciliation stance. Still the clearest single statement of the mental model. [A]
3 architecture/principles.md — https://github.com/kubernetes/design-proposals-archive/blob/main/architecture/principles.md The design axioms (no hidden state, APIs are versioned, controllers are independent). Short. Explains why later source looks repetitive. [A]
4 https://kubernetes.io/docs/concepts/architecture/ The maintained version of the above. Use as the current-facts cross-check against the two archived docs, which predate several renames. [A]
5 contributors/devel/sig-architecture/object-lifecycle.md (4.7 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-architecture/object-lifecycle.md Creation → update → graceful deletion → finalizers → GC, in five pages. The correct primer before any controller source. [A]
6 contributors/devel/sig-api-machinery/controllers.md (11.8 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-api-machinery/controllers.md The "how to write a controller" doc. Level vs edge triggering, why you re-read from the cache, why you never trust the event payload. Highest value-per-byte document in the entire corpus. [A]
7 architecture/declarative-application-management.md — https://github.com/kubernetes/design-proposals-archive/blob/main/architecture/declarative-application-management.md Why kubectl apply and later server-side apply exist; the config-management problem statement. [B]
8 contributors/devel/sig-architecture/api-conventions.md (115 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-architecture/api-conventions.md The rulebook every k8s API obeys: spec/status split, TypeMeta/ObjectMeta/ListMeta, conditions, optional-vs-required, resourceVersion opacity, label selectors, verbs and subresources. Do not read cover to cover. Assign the sections Types (Kinds), Objects → Spec and Status, Typical status properties/Conditions, Resource Version, and Lists and Simple Kinds. [B] for the named sections, [D] as a whole
9 contributors/devel/sig-architecture/api_changes.md (70 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-architecture/api_changes.md Compatibility rules, alpha/beta/GA graduation, and the internal-vs-versioned type split with the generated conversion/defaulting machinery. Read the "On compatibility" and "Adding new API types" sections; this is the doc that makes pkg/apis/** legible. [C]
10 contributors/devel/sig-architecture/feature-gates.md (31 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-architecture/feature-gates.md How every KEP actually lands in code. Makes --feature-gates and the if utilfeature.DefaultFeatureGate.Enabled(...) idiom (which is everywhere in the source) readable. [B]
11 contributors/devel/sig-architecture/staging.md (2.6 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-architecture/staging.md Why staging/src/k8s.io/* exists and how it publishes to k8s.io/client-go etc. Two pages that stop a lot of confusion about the repo layout. [A]
12 hack/local-up-cluster.sh — https://github.com/kubernetes/kubernetes/blob/master/hack/local-up-cluster.sh Not prose, but the most honest inventory of what a control plane actually is: read the flags it passes to each binary. Excellent Phase-1 companion to a from-source cluster on the homelab. [B]

The four staging READMEs actually worth reading

Verified sizes; the other 29 are stubs.

Item Teaches Difficulty
staging/src/k8s.io/cri-api/README.md (15.7 KB) CRI's scope, versioning and the runtime/image service split. The best CRI orientation in-tree. [B]
staging/src/k8s.io/client-go/README.md (9.8 KB) Client flavours (typed/dynamic/discovery), versioning-vs-k8s-release compatibility matrix. [A]
staging/src/k8s.io/sample-controller/README.md (7.8 KB) + docs/controller-client-go.md + docs/images/client-go-controller-interaction.jpeg The canonical reflector→DeltaFIFO→indexer→workqueue diagram, with prose. Read before any tools/cache source. [A]
staging/src/k8s.io/sample-apiserver/README.md (8.1 KB) What an aggregated apiserver must implement — the concrete frame for the kube-aggregator section. [C]

Note on contributors/design-proposals/: in kubernetes/community this is now a single README.md pointer — the real corpus was moved to the separate kubernetes/design-proposals-archive repo (334 files). That repo is underused and is cited throughout this document; several of its design docs (PLEG, kubelet eviction, volume-topology scheduling, garbage collection) remain the only narrative explanation of code that is otherwise comment-only.


Area 1 — etcd

The one area that needs no Kubernetes cluster at all — which matters given factory's ~9.9 GB ceiling. A standalone single-node etcd plus etcdctl is enough for revisions, watches, compaction and defrag.

⭐ ENTRY POINT: server/storage/mvcc/key_index.go (10.4 KB) — https://github.com/etcd-io/etcd/blob/main/server/storage/mvcc/key_index.go One small file, one data structure, and it is MVCC: generations, revision{main,sub}, tombstones, and what compact() physically removes. Read this and revisions stop being magic. It rewards reading before anything else in etcd because everything else in the store is built on it.

Ordered approachable → hard:

# Item Teaches Difficulty
1 https://etcd.io/docs/v3.6/learning/data_model/ Revisions, key-space, generations, compaction — the prose companion to key_index.go. (v3.6 URLs verified live; k/k vendors 3.7, whose docs are also published at /docs/v3.7/.) [A]
2 https://etcd.io/docs/v3.6/learning/api/ The gRPC surface Kubernetes actually uses: Range, Txn, Watch, Lease, and WithRev. [A]
3 https://etcd.io/docs/v3.6/learning/api_guarantees/ Linearizability vs serializability, atomicity, isolation. The doc for understanding what resourceVersion can and cannot promise upstream. [A]
4 server/storage/mvcc/key_index.go (10.4 KB) ⭐ Entry point — see above. [A]
5 server/storage/mvcc/revision.go (3.5 KB) — https://github.com/etcd-io/etcd/blob/main/server/storage/mvcc/revision.go The main/sub revision encoding and its byte layout. Tiny; makes bbolt key dumps readable. [A]
6 Raft paper — "In Search of an Understandable Consensus Algorithm (Extended Version)", Ongaro & Ousterhout · https://raft.github.io/raft.pdf (USENIX ATC'14 version: https://www.usenix.org/system/files/conference/atc14/atc14-paper-ongaro.pdf) Leader election, log replication, safety, membership changes. Figure 2 is the whole protocol. Non-negotiable before any consensus code. [A] (long, but genuinely written to be understood)
7 etcd-io/raft/design.md (5.6 KB) — https://github.com/etcd-io/raft/blob/main/design.md How the library differs from the paper: it is a state machine, not a server — no disk, no network, no clock. Explains the Ready()/Advance() contract. [A]
8 etcd-io/raft/doc.go (17 KB) — https://github.com/etcd-io/raft/blob/main/doc.go The package doc: usage protocol, MsgProp/MsgApp, snapshotting, the strict ordering rules for persisting Ready. The best code-adjacent Raft explanation available. [B]
9 server/storage/mvcc/index.go (6.8 KB) — https://github.com/etcd-io/etcd/blob/main/server/storage/mvcc/index.go The in-memory B-tree keyIndex over key_index.go. Short; completes the read path. [B]
10 server/storage/mvcc/watcher_group.go (7.0 KB) + server/storage/mvcc/watcher.go (6.1 KB) The watch-fanout data structures: synced vs unsynced watcher sets, and the interval tree for range watches. See also pkg/adt/README.md for the interval tree itself. [B]
11 server/storage/mvcc/watchable_store.go (15.9 KB) — https://github.com/etcd-io/etcd/blob/main/server/storage/mvcc/watchable_store.go The watch mechanism. syncWatchers, the victim list, and how a slow watcher gets moved to unsynced and eventually gets ErrCompacted. This is the direct upstream cause of apiserver "too old resource version". [B]
12 server/storage/mvcc/kvstore_compaction.go (3.4 KB) + server/storage/mvcc/kvstore.go (14.9 KB) Compaction as a batched bbolt delete loop, and the store's revision bookkeeping. Explains why compaction frees revisions but not disk. [B]
13 https://etcd.io/docs/v3.6/op-guide/maintenance/ Auto-compaction modes, defragmentation (why it is needed, why it blocks), space quota and the NOSPACE alarm. Pair with a lab that deliberately fills the quota. [A]
14 https://etcd.io/docs/v3.6/op-guide/recovery/ + etcdutl/README.md Snapshot save/restore, etcdutl snapshot status, and disaster recovery of a quorum-lost cluster. Backup/restore lab anchor. [A]
15 https://etcd.io/docs/v3.6/op-guide/performance/ + https://etcd.io/docs/v3.6/op-guide/hardware/ fsync latency, --heartbeat-interval/--election-timeout derivation from RTT, disk/network sizing. Directly relevant: factory is a 35 W i5 with contended disk, so etcd will misbehave and the learner should be able to explain why. [A]
16 server/storage/backend/backend.go (20.5 KB) + batch_tx.go (10.8 KB) The bbolt layer: batch transactions, commit intervals, and where Defrag() actually happens. [C]
17 https://etcd.io/docs/v3.6/learning/persistent-storage-files/ On-disk layout: WAL segments, snapshot files, db. Read alongtools/etcd-dump-db/README.md and actually dump a db. [B]
18 server/etcdserver/raft.go (12.8 KB) — https://github.com/etcd-io/etcd/blob/main/server/etcdserver/raft.go The glue: raftNode.start() consuming Ready, persisting to WAL, then applying. The cleanest place to see the library-vs-server boundary from the server side. [C]
19 Documentation/postmortems/v3.5-data-inconsistency.md — https://github.com/etcd-io/etcd/blob/main/Documentation/postmortems/v3.5-data-inconsistency.md A real data-inconsistency incident, root-caused in public. Outstanding distributed-systems debugging reading and a natural chaos-drill/incident-report model. [B]
20 server/etcdserver/corrupt.go (18.8 KB) + server/storage/mvcc/hash.go The corruption detector the postmortem produced. [C]
21 server/etcdserver/server.go (75.5 KB) — https://github.com/etcd-io/etcd/blob/main/server/etcdserver/server.go The apply loop, linearizable-read barrier (linearizableReadLoop), lease and compaction scheduling. Reference-only — navigate to named functions. [D]
22 etcd-io/raft/raft.go (84 KB) — https://github.com/etcd-io/raft/blob/main/raft.go The actual protocol state machine. Worth targeted reading of stepLeader/stepFollower/becomeLeader after the paper, never linearly. [D]
23 etcd-io/raft/tla/ — https://github.com/etcd-io/raft/tree/main/tla TLA+ specifications of the implementation. Optional, high reward for a distributed-systems-curious learner; skip unless the learner wants formal methods. [D]
24 Documentation/etcd-internals/diagrams/*.png — https://github.com/etcd-io/etcd/tree/main/Documentation/etcd-internals/diagrams write_workflow_leader.png, write_workflow_follower.png, consistent_read_workflow.png, etcd_internal_parts.png. Note: the prose that used to accompany these has moved to the website; only the diagrams remain in-repo. Still the best single-picture summary of the write path. [A]

Area 2 — API machinery

The area with the highest ratio of essential to readable. Sequencing matters more here than anywhere else.

⭐ ENTRY POINT: staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go (10.4 KB) — https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go It is short, and it is the kubectl→apiserver→etcd path in one readable function: decode the body → admit (mutating) → Validate → admit (validating) → storage.Create. Every abstraction the learner will later need is visible here as a single named call, which makes it the ideal index into the rest of the area.

Ordered approachable → hard:

# Item Teaches Difficulty
1 contributors/devel/sig-architecture/api-conventions.md — named sections (see Foundational #8) Prerequisite vocabulary. Do this first or the source is noise. [B]
2 staging/src/k8s.io/apiserver/pkg/endpoints/handlers/create.go (10.4 KB) ⭐ Entry point — the write path end to end. [B]
3 staging/src/k8s.io/apiserver/pkg/endpoints/handlers/get.go (12.0 KB) + watch.go The read path and the WATCH upgrade; where resourceVersion and resourceVersionMatch are honoured. [B]
4 staging/src/k8s.io/apiserver/pkg/endpoints/filters/ — read requestinfo.go, then authentication.go (6.8 KB), then authorization.go The handler chain, one small file at a time. requestinfo.go shows how a URL becomes {verb, group, version, resource, namespace, name}; the other two are the authn and authz links. Each file is small and single-purpose — ideal reading. [B]
5 staging/src/k8s.io/apiserver/pkg/admission/interfaces.go (8.3 KB) + chain.go (2.2 KB) The Interface/MutationInterface/ValidationInterface split and the chain that runs them. chain.go is 2 KB and explains the whole ordering model: all mutating plugins run, then all validating plugins — never interleaved. [B]
6 KEP-492: Graduate Admission Webhooks to GA (implemented) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/492-admission-webhooks The normative statement of webhook semantics: ordering, failurePolicy, reinvocationPolicy, timeouts, and why mutating webhooks may be called more than once. [B]
7 plugin/pkg/admission/ — pick two: limitranger/, serviceaccount/ Real built-in admission plugins, small and comprehensible. Best proof that admission is "just a function". 27 plugin dirs exist; podtolerationrestriction/ and noderestriction/ are good follow-ups. [B]
8 staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/ — plugin.go, dispatcher.go, reinvocationcontext.go How mutating webhooks are actually dispatched, and the reinvocation bookkeeping that implements KEP-492's ordering guarantees. reinvocationcontext.go is the file that makes webhook re-entry click. [C]
9 staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/{plugin,dispatcher}.go + webhook/generic/webhook.go The validating counterpart and the shared machinery (matching, conversion, failure policy). [C]
10 KEP-3716: Admission Webhook Match Conditions (implemented, v1.30) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3716-admission-webhook-match-conditions CEL-based narrowing of webhook invocation; the modern way to avoid webhook blast radius. [C]
11 KEP-3488: CEL for Admission Control (implemented, v1.30) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3488-cel-admission-control ValidatingAdmissionPolicy — in-process, webhook-free validation. Now the default answer for policy, so it belongs in CKS-adjacent reading too. [C]
12 KEP-3962: Mutating Admission Policies (implemented, v1.36) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3962-mutating-admission-policies The mutating half of the CEL story. Recent — good example of a KEP the learner can watch graduate. [C]
13 staging/src/k8s.io/apiserver/pkg/registry/rest/{rest,create,update}.go The RESTStorage / RESTCreateStrategy / RESTUpdateStrategy interfaces — the seam between "generic apiserver" and "this specific resource". [C]
14 pkg/registry/core/pod/strategy.go A concrete strategy: Pod's defaulting, validation, status-subresource rules, and field/label selector conversion. Best example of the previous item. [C]
15 staging/src/k8s.io/apiserver/pkg/registry/generic/registry/store.go (43.8 KB) The generic etcd-backed store — Create/Update/Delete with optimistic concurrency, plus finalizer and graceful-deletion handling. Long but genuinely central; read Create, Update, Delete. [C]
16 staging/src/k8s.io/apiserver/pkg/storage/interfaces.go (21.1 KB) The storage contract the apiserver programs against, with the resourceVersion semantics documented in the comments. Read the comments on GetOptions/ListOptions/Preconditions. [C]
17 KEP-956: Watch Bookmark (implemented) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/956-watch-bookmark Why bookmarks exist: let a client advance its resourceVersion without receiving object churn, so reconnects don't blow the watch cache window. [B]
18 KEP-365: Paginated API Lists (implemented, v1.29) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/365-paginated-lists limit/continue, and the consistency caveats of a chunked list. Pairs with api-machinery/api-chunking.md in the archive. [B]
19 KEP-1904: Efficient watch resumption after kube-apiserver reboot (implemented, v1.24) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1904-efficient-watch-resumption How the watch cache is warmed from etcd on restart. Directly explains a class of post-restart Unexpected watch close behaviour. [C]
20 KEP-2340: Consistent Reads from Cache (implementable, v1.34) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/2340-Consistent-reads-from-cache Serving quorum-consistent reads from the watch cache using etcd progress notifications. The single best KEP for understanding the apiserver/etcd consistency contract. [C]
21 staging/src/k8s.io/apiserver/pkg/storage/cacher/watch_cache.go (23.8 KB) The ring buffer behind every watch: startIndex/endIndex, capacity, and the exact origin of "too old resource version". [C]
22 staging/src/k8s.io/apiserver/pkg/storage/cacher/{cacher.go (55.2 KB), cache_watcher.go, delegator.go} The full watch-cache implementation, per-watcher dispatch, and (in delegator.go) the KEP-2340 decision of cache-vs-etcd. Reference-heavy. [D]
23 staging/src/k8s.io/apiserver/pkg/storage/etcd3/{store.go (43.8 KB), watcher.go, compact.go, lease_manager.go} Where Kubernetes finally talks etcd gRPC: key layout, Txn-based optimistic concurrency, watch translation, and the apiserver-side compactor. Read compact.go and watcher.go first — both are tractable. [C]/[D]
24 KEP-3157: Allow informers for getting a stream of data instead of chunking (implementable, v1.37) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list WatchList / streaming initial state — replaces the memory-spiking big LIST. Very relevant to a RAM-constrained homelab. [C]
25 KEP-1040: Priority and Fairness for API Server Requests (implemented, v1.30) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/1040-priority-and-fairness APF: FlowSchemas, PriorityLevelConfigurations, queuing and shuffle sharding. The correct mental model for apiserver overload. [C]
26 staging/src/k8s.io/apiserver/pkg/util/flowcontrol/{apf_filter.go, apf_controller.go} APF implementation. Good code; needs KEP-1040 first. [C]
27 KEP-95: Graduate CustomResourceDefinitions to GA (implemented, 1.16) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/95-custom-resource-definitions The CRD contract: structural schemas, pruning, defaulting, subresources, spec.versions. [B]
28 KEP-598: CustomResourceDefinition Conversion Webhook (implemented) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/598-crd-conversion-webhook Multi-version CRDs, the storage version, and round-trip requirements. [C]
29 KEP-2876: CRD Validation Expression Language (implemented, v1.29) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/2876-crd-validation-expression-language x-kubernetes-validations CEL rules — validation without a webhook. [B]
30 staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go (59.1 KB) How CRDs are actually served: one handler that dynamically builds per-CRD RESTStorage, an unstructured-object codec, and tears it down on CRD change. This is the file that answers "how can a CRD behave like a built-in?" — but it is long and dense. Read ServeHTTP and getOrCreateServingInfoFor. [D] (targeted [C])
31 staging/src/k8s.io/kube-aggregator/pkg/apiserver/{apiserver.go, handler_proxy.go, handler_apis.go} API aggregation: APIService objects, and handler_proxy.go — a genuinely small, readable reverse proxy. Start with handler_proxy.go. [C]
32 cmd/kube-apiserver/app/{server.go, aggregator.go} How the three servers are actually chained: kube-apiserver → apiextensions-apiserver → kube-aggregator, with the delegation and not-found handler wiring. Read after the three previous items; it is the payoff. [C]
33 staging/src/k8s.io/apiserver/pkg/server/config.go (52.7 KB) + handler.go The authoritative construction of the handler chain (DefaultBuildHandlerChain). Skim handler.go for the chain order, treat config.go as reference. [D]
34 KEP-555: Apply (server-side apply) (implemented, v1.22) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/555-server-side-apply Field management, managedFields, apply-vs-update conflict detection. Pair with contributors/devel/sig-api-machinery/strategic-merge-patch.md (12.3 KB) for the old model it replaces. [C]
35 staging/src/k8s.io/apimachinery/pkg/runtime/{interfaces.go, scheme.go (32 KB), codec.go} runtime.Object, Scheme as the GVK↔Go-type registry plus conversion/defaulting, and the codec/negotiation chain. Deliberately last. This is the "generics" trap named in the ticket — necessary for mastery, disastrous as early reading. Precede with api_changes.md. [C]/[D]
36 Authn/authz reading: staging/src/k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go, staging/src/k8s.io/apiserver/pkg/authorization/authorizer/interfaces.go, then plugin/pkg/auth/authorizer/rbac/rbac.go, then plugin/pkg/auth/authorizer/node/{node_authorizer.go, graph.go} The two interfaces are tiny and clarifying. rbac.go is a readable rule-matcher. The Node authorizer's graph is the interesting one: why a kubelet may only read its own node's secrets. [B] for interfaces + rbac; [C] for node graph
37 KEP-3331: Structured authentication config (implemented, v1.35) and KEP-3221: Structured Authorization Configuration (implemented, v1.32) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/3331-structured-authentication-configuration · https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/3221-structured-authorization-configuration The current, file-based way authn/authz is configured (multiple JWT issuers; ordered authorizer chains with CEL). Supersedes the flag-soup most material still teaches. [C]
38 KEP-1205: Bound Service Account Tokens (implemented, v1.22) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-auth/1205-bound-service-account-tokens Audience-and-time-bound projected tokens replacing forever-secrets. Core CKS material with a real mechanism behind it. [B]
39 Archive cross-reads: api-machinery/apiserver-watch.md, api-machinery/api-chunking.md, api-machinery/aggregated-api-servers.md, api-machinery/protobuf.md, api-machinery/admission_control.md — https://github.com/kubernetes/design-proposals-archive/tree/main/api-machinery Original design narratives for the watch cache, chunking, aggregation and protobuf serialization. Often the only prose explanation; apiserver-watch.md is the best possible primer for item 21. [B]
40 staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go The client end of the path: how kubectl apply builds a request. Good bookend to the entry point. [B]

Area 3 — Scheduler

The best-documented area in the tree, and the one where SIG-provided reading genuinely removes the need to reverse-engineer. Read the three contributors/devel/sig-scheduling/ docs first — they were written for exactly this purpose and most people never find them.

⭐ ENTRY POINT: pkg/scheduler/framework/interface.go (17.6 KB) — https://github.com/kubernetes/kubernetes/blob/master/pkg/scheduler/framework/interface.go Every extension point — PreFilterPlugin, FilterPlugin, PostFilterPlugin, PreScorePlugin, ScorePlugin, ReservePlugin, PermitPlugin, PreBindPlugin, BindPlugin, PostBindPlugin — declared as a small Go interface with a doc comment explaining when it runs and what returning an error means. It is a table of contents for the whole scheduler, it teaches the architecture without any implementation noise, and a beginner can read it on day one of the scheduler phase.

Ordered approachable → hard:

# Item Teaches Difficulty
1 contributors/devel/sig-scheduling/scheduling_code_hierarchy_overview.md (21.9 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-scheduling/scheduling_code_hierarchy_overview.md A guided tour of pkg/scheduler written by the SIG, function by function, in call order. This is the single most underused document in the entire Kubernetes corpus. Read it with the source open. [A]
2 contributors/devel/sig-scheduling/scheduler_framework_plugins.md (5.5 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-scheduling/scheduler_framework_plugins.md Which in-tree plugins implement which extension points, in a table. The map for framework/plugins/. [A]
3 KEP-624: Scheduling Framework (implemented, v1.19) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/624-scheduling-framework The KEP that defines the framework. Extension points, the scheduling-cycle-vs-binding-cycle split, plugin lifecycle. Read alongside interface.go. Original narrative: scheduling/scheduling-framework.md in the archive. [B]
4 pkg/scheduler/framework/interface.go (17.6 KB) ⭐ Entry point — see above. [A]
5 pkg/scheduler/framework/plugins/registry.go (4.8 KB) The default plugin set in one 4.8 KB file — the concrete answer to "what actually runs?". [A]
6 pkg/scheduler/framework/plugins/noderesources/fit.go (37.8 KB) NodeResourcesFit: requests-vs-allocatable, PreFilter state passing, the insufficient-resource messages you see in real FailedScheduling events, and the scoring strategies. Concrete and high-value; skim the scoring half. [B]
7 pkg/scheduler/framework/plugins/nodename/, nodeunschedulable/, tainttoleration/ Three tiny plugins (a few KB each). Read these to internalise the plugin shape before the big ones. Genuinely [A] once interface.go is done. [A]
8 pkg/scheduler/schedule_one.go (54.5 KB) The filter → score → reserve → permit → bind cycle as one narrative: schedulingCycle, bindingCycle, findNodesThatFitPod, prioritizeNodes, assume, and the async bind. Long, but it is the control flow. Read function by function, guided by doc #1. [C]
9 pkg/scheduler/framework/cycle_state.go How PreFilter hands state to Filter without globals. Small and clarifying. [B]
10 KEP-268: Promote Pod Priority and Preemption to GA (implementable) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/268-priority-preemption The preemption KEP. PriorityClass, victim selection, PodDisruptionBudget respect, the nominated-node mechanism. Original design: scheduling/pod-preemption.md + scheduling/pod-priority-api.md in the archive. [B]
11 pkg/scheduler/framework/preemption/preemption.go (23.2 KB) The reusable preemption algorithm: candidate nodes → simulate removal → pick victims → PostFilter returns a nominated node. Readable and well-structured. [C]
12 pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go The default policy plugged into the above (selectVictimsOnNode, PDB accounting). [C]
13 KEP-4832: Asynchronous Preemption (implementable, v1.33) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/4832-async-preemption Why victim deletion moved off the scheduling thread. Read with pkg/scheduler/framework/preemption/executor.go. [C]
14 contributors/devel/sig-scheduling/scheduler_queues.md (7.2 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-scheduling/scheduler_queues.md activeQ / backoffQ / unschedulablePods explained in seven pages, including the flush timings. Mandatory before the queue source. [B]
15 KEP-4247: Per-plugin callback functions for efficient requeueing in the scheduling queue (implemented, v1.34) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/4247-queueinghint QueueingHint: how a cluster event decides whether an unschedulable pod is worth retrying. The modern heart of scheduler throughput. [C]
16 pkg/scheduler/backend/queue/{backoff_queue.go, unschedulable_entities.go, active_queue.go} Path note: the queue now lives under pkg/scheduler/backend/queue/ — older material citing pkg/scheduler/internal/queue/ is stale. Read backoff_queue.go for the exponential backoff, then the others. [C]
17 pkg/scheduler/backend/queue/scheduling_queue.go (101.6 KB) The full priority queue with QueueingHint integration. Reference-only — the largest file in the scheduler. Use doc #14 plus targeted function reads. [D]
18 pkg/scheduler/eventhandlers.go Which informer events feed the queue — closes the loop between the controllers area and the scheduler. [C]
19 KEP-3521: Pod Scheduling Readiness (implemented, v1.30) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/3521-pod-scheduling-readiness schedulingGates — pods that are deliberately not schedulable yet. Small, clean KEP; good gateway to the queue's PreEnqueue stage. [B]
20 KEP-1451: Multi Scheduling Profiles (implementable, v1.19) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-scheduling/1451-multi-scheduling-profiles One scheduler binary, several named profiles via schedulerName. Read with pkg/scheduler/profile/. [C]
21 pkg/scheduler/framework/types.go (64.3 KB) NodeInfo, PodInfo, QueuedPodInfo, resource accounting. Reference-only, but look up NodeInfo specifically — it is the scheduler's cached view of a node. [D]
22 pkg/scheduler/framework/plugins/interpodaffinity/, podtopologyspread/ The genuinely hard plugins. Optional; assign only if the learner is enjoying this. Backing KEPs: KEP-895: Pod Topology Spread (implemented) and KEP-3022: Tuning the number of domains in PodTopologySpread (implemented). [D]
23 contributors/devel/sig-scheduling/scheduler_benchmarking.md (3.6 KB) How to run the scheduler's own perf tests — a ready-made lab on a RAM-constrained node. [B]

Area 4 — Controllers

The area with the best on-ramp in the entire corpus, provided the learner reads sample-controller before client-go/tools/cache. Doing it the other way round is the specific failure mode the ticket warns about: reflector.go (55 KB) and shared_informer.go (58 KB) are miserable cold, and delightful once the pattern is known.

⭐ ENTRY POINT: staging/src/k8s.io/sample-controller/controller.go (16.9 KB) — https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/sample-controller/controller.go A complete, working, heavily-commented controller in one file: informer setup, event handlers that enqueue keys (not objects), the worker loop, syncHandler, owner references, and status update. It is the Rosetta Stone for every other controller in the tree — and it maps directly onto the learner's Rust kube-rs build track, since the same five moving parts must be wired by hand there.

Ordered approachable → hard:

# Item Teaches Difficulty
1 contributors/devel/sig-api-machinery/controllers.md (11.8 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-api-machinery/controllers.md Level-triggered reconciliation, why you re-read from the cache instead of trusting the event, idempotency, and the rate-limiting rules. Read first, always. [A]
2 staging/src/k8s.io/sample-controller/README.md + docs/controller-client-go.md + the client-go-controller-interaction.jpeg diagram The reflector→DeltaFIFO→indexer→workqueue picture with prose. Ten minutes that saves ten hours. [A]
3 staging/src/k8s.io/sample-controller/controller.go (16.9 KB) ⭐ Entry point — see above. [A]
4 staging/src/k8s.io/client-go/util/workqueue/queue.go (9.5 KB) The workqueue: Add/Get/Done, and the dirty/processing sets that give de-duplication and single-worker-per-key. Small and elegant — the best first piece of client-go source. [A]
5 staging/src/k8s.io/client-go/util/workqueue/{delaying_queue.go, rate_limiting_queue.go, default_rate_limiters.go} AddAfter, exponential per-item backoff, and the overall bucket limiter. Explains hot-loop symptoms in a broken controller. [B]
6 staging/src/k8s.io/client-go/tools/cache/store.go (13.9 KB) + thread_safe_store.go Store/Indexer, keys as namespace/name, and how indices work. Prerequisite vocabulary for the informer. [B]
7 staging/src/k8s.io/client-go/tools/cache/delta_fifo.go (28.3 KB) DeltaFIFO: why the queue holds deltas per key, what Replace does on a re-list, and how Sync deltas differ from Added. The conceptual crux of the informer. [C]
8 staging/src/k8s.io/client-go/tools/cache/reflector.go (55 KB) The reflector: ListAndWatch, resourceVersion bookkeeping, ErrResourceExpired/410 handling, re-list on watch failure, and the WatchList path (KEP-3157). Read ListAndWatch and watchHandler; skip the rest. This is the file that connects the controllers area back to API machinery. [C]
9 staging/src/k8s.io/client-go/tools/cache/shared_informer.go (58.2 KB) The shared informer cache: one watch shared by many handlers, HasSynced, resync semantics, and the per-listener delivery buffers. Read Run, HandleDeltas, and the processorListener comments. [C]
10 staging/src/k8s.io/client-go/tools/cache/controller.go (38 KB) The Config/controller that glues reflector+DeltaFIFO+process-loop, and NewInformer. Read after #7–9; it is the assembly. [C]
11 pkg/controller/replicaset/replica_set.go (38.3 KB) The most readable exemplar controller in-tree. Diff-driven reconcile (count actual vs desired), manageReplicas, adopt/orphan via owner refs, and the expectations mechanism. Start here, not with Deployment. [C]
12 pkg/controller/controller_utils.go (56.6 KB) Where ControllerExpectations lives — the mechanism that stops a controller over-creating while its cache is stale. Read the Expectations types and their comments only; the rest is grab-bag. [C] (targeted)
13 pkg/controller/deployment/{deployment_controller.go (24.1 KB), sync.go, rolling.go, rollback.go, progress.go} Deployment, split into readable files: sync.go for ReplicaSet selection/creation, rolling.go for maxSurge/maxUnavailable arithmetic, progress.go for progressDeadlineSeconds. A controller that manages another controller's objects. [C]
14 pkg/controller/nodelifecycle/node_lifecycle_controller.go (55.4 KB) Node lifecycle: heartbeat/lease observation, NodeReady transitions, taint-based eviction and the rate limiters that implement zone-aware eviction. The controller behind "why did my pods not get evicted for 5 minutes?" — an excellent chaos-drill anchor. [C]
15 cmd/kube-controller-manager/names/controller_names.go + cmd/kube-controller-manager/app/{controllermanager.go, core.go, apps.go} controller_names.go is a one-file inventory of every controller in the control plane — a great orientation artefact. Then controllermanager.go shows the shared informer factory, one-goroutine-per-controller startup, and leader election. [B] for names; [C] for the app
16 staging/src/k8s.io/client-go/tools/leaderelection/leaderelection.go (21.5 KB) Leader election: LeaseLock, renew deadline vs lease duration, and the OnStoppedLeading contract. Self-contained, well-commented, and directly demonstrable in the homelab with a multi-replica controller. [B]
17 KEP-4355: Coordinated Leader Election (implementable, v1.33) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/4355-coordinated-leader-election LeaseCandidate and coordinated leader selection for skew-aware upgrades. The modern extension of #16. [C]
18 api-machinery/controller-ref.md — https://github.com/kubernetes/design-proposals-archive/blob/main/api-machinery/controller-ref.md The ControllerRef design doc. Explains adoption/orphaning and why exactly one owner may have controller: true. The prose behind the ReplicaSet adoption code. [B]
19 api-machinery/garbage-collection.md + api-machinery/synchronous-garbage-collection.md — https://github.com/kubernetes/design-proposals-archive/tree/main/api-machinery Owner refs, cascading deletion, Orphan/Background/Foreground propagation policies, and the foregroundDeletion finalizer. Read before the GC source. [B]
20 pkg/controller/garbagecollector/{graph.go, graph_builder.go, garbagecollector.go (32.6 KB)} The GC's owner-reference graph: built from every resource discovered at runtime, with attemptToDelete/attemptToOrphan workers. graph.go is small — start there. Explains stuck deletions and finalizer deadlocks. [C]
21 pkg/controller/namespace/ + KEP-5080: Ordered Namespace Deletion — https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5080-ordered-namespace-deletion The kubernetes finalizer and why namespaces get stuck in Terminating — the single most-encountered real-world finalizer problem. [C]
22 pkg/controller/{job,statefulset,daemon}/ Progressively harder exemplars. Optional; job/ is the most instructive (indexed jobs, backoff limits, pod-failure policy). [D]
23 contributors/devel/sig-api-machinery/generating-clientset.md (4.9 KB) + staging/src/k8s.io/code-generator/README.md How typed clients, listers and informers are generated. Only matters if the learner writes a Go controller — and the build track is Rust, so this is optional. Read it to understand pkg/generated/ directories, not to use it. [C]

Area 5 — Networking

The area where the specs are more readable than the code. pkg/proxy/*/proxier.go are 61–71 KB rule-generation machines; the CNI spec is 40-odd pages of clear prose. Lead with specs and API types.

⭐ ENTRY POINT: staging/src/k8s.io/api/discovery/v1/types.go (11 KB) — https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/api/discovery/v1/types.go The EndpointSlice API in one small, thoroughly-commented file: Endpoint, EndpointConditions{Ready,Serving,Terminating}, EndpointHints, ports, and the addressType split. It is the data structure that everything in Kubernetes service networking consumes — kube-proxy, Cilium, every ingress controller — so understanding it first makes the dataplane code legible instead of arbitrary. Small enough to read in one sitting on day one.

Ordered approachable → hard:

# Item Teaches Difficulty
1 CNI spec — SPEC.md — https://github.com/containernetworking/cni/blob/main/SPEC.md The CNI specification itself. Operations (ADD/DEL/CHECK/GC/STATUS), the JSON config format, plugin chaining, the result type, and how the runtime invokes plugins as executables with env vars. Very readable prose; no Kubernetes knowledge needed. [A]
2 CONVENTIONS.md — https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Conventions layered on the spec (IPAM, port mappings, bandwidth) — where "real" plugin config comes from. [A]
3 network/networking.md — https://github.com/kubernetes/design-proposals-archive/blob/main/network/networking.md The original Kubernetes networking model: IP-per-pod, no NAT between pods, the four communication paths. The axioms every CNI must satisfy. [A]
4 staging/src/k8s.io/api/discovery/v1/types.go (11 KB) ⭐ Entry point — see above. [A]
5 KEP-752: EndpointSlice API (implemented, v1.22) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/0752-endpointslices The KEP that introduced EndpointSlice. Why Endpoints did not scale (one object per service, full rewrite on every pod change), the slicing strategy, and the dual-write migration. (Directory is 0752-; the KEP is 752.) [B]
6 KEP-4974: Deprecate v1.Endpoints and Associated Controllers (implementable, v1.37) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/4974-deprecate-endpoints The end state of the migration — current as of today, so the learner learns the right API first. [B]
7 staging/src/k8s.io/api/core/v1/types.go — ServiceSpec/ServiceStatus types only ClusterIP/NodePort/LoadBalancer/ExternalName, externalTrafficPolicy, internalTrafficPolicy, sessionAffinity, ipFamilies. The file is 471 KB — navigate by type name, never read linearly. [A] (as targeted lookup)
8 staging/src/k8s.io/endpointslice/reconciler.go (27.9 KB) The EndpointSlice reconciler, moved to staging by KEP-3685: Move EndpointSlice Reconciler into Staging (implemented) so other projects can reuse it: pod→endpoint mapping, slice packing, and the churn-minimising placement heuristic. The most readable substantial piece of networking code in the tree. [C]
9 pkg/controller/endpointslice/endpointslice_controller.go The controller that drives the reconciler off Service/Pod/Node informers. [C]
10 pkg/proxy/{serviceport.go, endpoint.go, servicechangetracker.go, endpointschangetracker.go, endpointslicecache.go, topology.go} Read these small backend-agnostic files before any proxier.go. They define kube-proxy's internal model: what a "service port" and "endpoint" are, how changes are accumulated between syncs, and (in topology.go) how topology hints filter endpoints. This is the correct on-ramp and it is routinely skipped. [B]
11 KEP-3866: Add an nftables-based kube-proxy backend (implemented, v1.33) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/3866-nftables-proxy The nftables backend, and — more usefully — a clear-eyed account of iptables mode's scaling problems that motivated it. [B]
12 KEP-5343: Make nftables the default kube-proxy backend (provisional, v1.37) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/5343-nftables-to-default Current direction of travel. Teach nftables as first-class, not a footnote. [B]
13 KEP-265: IPVS Load Balancing Mode in Kubernetes (implemented, v1.11) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/265-ipvs-based-load-balancing IPVS mode: real-server/virtual-server model, schedulers (rr/lc/dh…), and the ipset use that avoids iptables rule explosion. [C]
14 KEP-5495: Deprecate ipvs mode in kube-proxy (implementable, v1.37) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/5495-deprecate-ipvs-mode-in-kube-proxy Important currency note: IPVS is on its way out. The ticket asks for iptables and IPVS; teach IPVS as comparative/historical, with nftables as the future. [B]
15 pkg/proxy/iptables/proxier.go (61.2 KB) iptables mode: the KUBE-SERVICES/KUBE-SVC-*/KUBE-SEP-* chain structure and iptables-restore batching. Read syncProxyRules only, with a live iptables-save dump beside it — that pairing turns a hostile file into a great lab. [D] (targeted [C])
16 pkg/proxy/nftables/proxier.go (69.9 KB) Same job, nftables: verdict maps instead of chain-per-service. Compare syncProxyRules with #15 — the comparison is the lesson. [D] (targeted [C])
17 pkg/proxy/ipvs/{proxier.go (70.8 KB), ipset.go, graceful_termination.go} IPVS implementation. graceful_termination.go is the interesting small file — connection draining for terminating endpoints. [D]
18 KEP-2433: Topology Aware Hints (implementable, v1.33) and KEP-536: Topology-aware service routing (status: replaced) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/2433-topology-aware-hints · https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/536-topology-aware-routing Zone-aware routing. Cite 2433, not 536 — 536 is formally marked replaced. Good example of reading KEP status metadata rather than trusting a search hit. [C]
19 KEP-4444: Traffic Distribution for Services (implemented, v1.33) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/4444-service-traffic-distribution spec.trafficDistribution — the current, simpler successor to topology hints. [B]
20 staging/src/k8s.io/api/networking/v1/types.go (37.7 KB) — NetworkPolicy types NetworkPolicy semantics from the types and their comments: the default-allow→default-deny flip on selection, ingress/egress rule union, podSelector+namespaceSelector AND-vs-OR (the classic mistake), ipBlock/except, and policy types. The comments here are the normative semantics. [B]
21 network/network-policy.md — https://github.com/kubernetes/design-proposals-archive/blob/main/network/network-policy.md The original NetworkPolicy design doc — the intent behind the semantics above. Note that k8s ships no NetworkPolicy enforcer; enforcement is the CNI's job, which is the bridge to Cilium. [B]
22 KEP-2091: Add support for AdminNetworkPolicy resources (implementable, v1.24) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/2091-admin-network-policy AdminNetworkPolicy/BaselineAdminNetworkPolicy: cluster-scoped, explicitly-ordered Allow/Deny/Pass — fixing NetworkPolicy's inability to express a real deny. Strong CKS material. [C]
23 pkg/registry/core/service/ipallocator/{ipallocator.go, bitmap.go, cidrallocator.go} + pkg/registry/core/service/storage/{storage.go, alloc.go} How ClusterIPs and NodePorts are actually allocated — bitmap allocator, the repair controller, and the allocate-then-create transaction. Small files, satisfying, and rarely taught. [C]
24 KEP-1880: Multiple Service CIDRs (implemented, v1.33) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/1880-multiple-service-cidrs ServiceCIDR/IPAddress objects replacing the static --service-cluster-ip-range bitmap. Read with pkg/controller/servicecidrs/. [C]
25 KEP-1453: Graduate Ingress API to GA (implemented, v1.19) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/1453-ingress-api Ingress's final shape — and, read carefully, an honest list of its limitations (no cross-namespace, no L4, annotation sprawl) that motivated Gateway API. [B]
26 Gateway API — https://gateway-api.sigs.k8s.io/ ; types in apis/v1/ of kubernetes-sigs/gateway-api; docs source at site/content/en/docs/concepts/ The role-oriented model: GatewayClass (infra provider) → Gateway (cluster operator) → HTTPRoute (app developer), with cross-namespace ReferenceGrant. Note: it is an out-of-tree CRD API, not in k/k. [B]
27 GEP-713: Metaresources and Policy Attachment (status: Memorandum) — https://github.com/kubernetes-sigs/gateway-api/blob/main/geps/gep-713/index.md ; GEP-2648: Direct Policy Attachment; GEP-2649: Inherited Policy Attachment; GEP-1364: Status and Conditions Update (Standard); GEP-1016: GRPCRoute (Standard) Gateway API's answer to annotation sprawl, and (GEP-1364) how status/conditions work across multiple implementations. GEP-713 is the conceptually important one. [C]
28 Cilium eBPF datapath docs — Documentation/network/ebpf/lifeofapacket.rst — https://github.com/cilium/cilium/blob/main/Documentation/network/ebpf/lifeofapacket.rst "Life of a Packet" — the single best document for understanding an eBPF dataplane: which hooks (XDP, tc ingress/egress, socket) a packet traverses and where policy is enforced. Read with intro.rst, maps.rst, and iptables.rst (which explicitly contrasts with kube-proxy). [B]
29 Documentation/reference-guides/bpf/architecture.rst + progtypes.rst — https://github.com/cilium/cilium/tree/main/Documentation/reference-guides/bpf The eBPF primer: program types, maps, verifier, tail calls, JIT. Genuine prerequisite for the learner's Aya/Rust eBPF build-track work, and readable without Cilium context. [B]
30 network/external-lb-source-ip-preservation.md + network/service-external-name.md — https://github.com/kubernetes/design-proposals-archive/tree/main/network Why externalTrafficPolicy: Local exists and what it costs. Directly relevant: factory's NAT'd bridge with no physical port makes LoadBalancer/source-IP behaviour a lab in itself. [B]

Area 6 — Storage

Read the CSI spec first. It is a clean gRPC contract document and it makes the entire in-tree volume subsystem — which is otherwise sprawling, historically layered, and full of in-tree-plugin vestiges — suddenly coherent.

⭐ ENTRY POINT: container-storage-interface/spec/spec.md — https://github.com/container-storage-interface/spec/blob/master/spec.md The CSI specification: the Identity/Controller/Node service split, and the five-call lifecycle CreateVolume → ControllerPublishVolume (attach) → NodeStageVolume (mount once per node) → NodePublishVolume (bind-mount per pod) and their unwinds. Once the learner can name which component makes which call, every k8s storage component has an obvious job. Read with csi.proto beside it. For the in-tree entry point, use pkg/controller/volume/persistentvolume/index.go (6.8 KB) — the PVC→PV matching predicate, small and immediately intelligible.

Ordered approachable → hard:

# Item Teaches Difficulty
1 spec.md + csi.proto — https://github.com/container-storage-interface/spec ⭐ Entry point — the CSI spec. Also read lib/README.md for how the Go bindings are generated. [A]
2 storage/persistent-storage.md — https://github.com/kubernetes/design-proposals-archive/blob/main/storage/persistent-storage.md The original PV/PVC design: why storage is two objects, the claim/bind lifecycle, and reclaim policies. Short and clarifying. [A]
3 storage/volume-provisioning.md — https://github.com/kubernetes/design-proposals-archive/blob/main/storage/volume-provisioning.md Dynamic provisioning and the StorageClass concept. [A]
4 pkg/controller/volume/persistentvolume/index.go (6.8 KB) ⭐ In-tree entry point: findBestMatchForClaim — the actual PVC→PV matching rules (access modes, capacity, selector, class, volume mode). Small, self-contained, and the single most useful storage file for a beginner. [A]
5 staging/src/k8s.io/api/storage/v1/types.go (42.9 KB) — types only StorageClass (incl. volumeBindingMode, allowedTopologies), VolumeAttachment, CSIDriver (incl. attachRequired, podInfoOnMount), CSINode. Navigate by type name; the comments are the reference. [B]
6 CSI sidecars — kubernetes-csi/external-provisioner doc/design.md — https://github.com/kubernetes-csi/external-provisioner/blob/master/doc/design.md ; plus https://kubernetes-csi.github.io/docs/ csi-provisioner: watches PVCs, calls CreateVolume, creates the PV. The sidecar pattern — Kubernetes controllers translating k8s objects into CSI RPCs — is the key architectural idea. The kubernetes-csi/docs site covers external-attacher, external-resizer, external-snapshotter, node-driver-registrar and livenessprobe with the same framing. [B]
7 storage/container-storage-interface.md + storage/container-storage-interface-skip-attach.md — https://github.com/kubernetes/design-proposals-archive/tree/main/storage How CSI was grafted onto Kubernetes, and why CSIDriver.attachRequired exists. [C]
8 pkg/controller/volume/persistentvolume/pv_controller_base.go (31.7 KB) The controller skeleton: informers, the two sync loops (claim worker, volume worker), and periodic resync. Read before the big one. [C]
9 pkg/controller/volume/persistentvolume/pv_controller.go (92.8 KB) PV/PVC binding, the state machine at the heart of storage: syncClaim/syncVolume, Pending→Bound→Released, the bidirectional claimRef/volumeName binding, provisioning, and deletion/recycling. Reference-only as a whole — assign syncClaim, syncVolume, bind, and provisionClaim. [D] (targeted [C])
10 KEP-557: CSI Volume Topology (implemented) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/557-csi-topology Topology-constrained volumes: nodeAffinity on PVs, allowedTopologies on StorageClasses. [C]
11 storage/volume-topology-scheduling.md — https://github.com/kubernetes/design-proposals-archive/blob/main/storage/volume-topology-scheduling.md The WaitForFirstConsumer design doc. Why binding must be delayed until the pod is scheduled (otherwise you bind a volume in zone A and schedule the pod in zone B), and how scheduler and PV controller share responsibility. Essential — the code below is nearly unreadable without it. [B]
12 pkg/scheduler/framework/plugins/volumebinding/volume_binding.go (24.8 KB) Where WaitForFirstConsumer actually lives — in the scheduler, not the PV controller. PreFilter/Filter/Reserve/PreBind implementing delayed binding. Path note: this moved from pkg/controller/volume/scheduling/, which no longer exists — older material citing that path is stale. [C]
13 pkg/scheduler/framework/plugins/volumebinding/{binder.go (42.6 KB), assume_cache.go} FindPodVolumes/AssumePodVolumes/BindPodVolumes, and the assume cache that lets the scheduler act on not-yet-persisted binds. [D]
14 KEP-1472: Storage Capacity Constraints for Pod Scheduling (implemented, v1.24) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1472-storage-capacity-tracking CSIStorageCapacity — letting the scheduler avoid nodes whose backing storage is full. [C]
15 pkg/controller/volume/attachdetach/attach_detach_controller.go (33.3 KB) + attachdetach/reconciler/ The attach/detach controller and its desired-state/actual-state-of-world pattern. That desiredStateOfWorld/actualStateOfWorld idiom recurs in the kubelet volume manager, so learn it here where it is smaller. Also read --attach-detach-reconcile-sync-period implications for stuck detaches. [C]
16 pkg/kubelet/volumemanager/volume_manager.go (26.5 KB) + volumemanager/reconciler/ + volumemanager/populator/ The kubelet volume manager: the node-side half — mount/unmount, WaitForAttach, and the same DSW/ASW pattern. populator/ shows how the pod list becomes desired state. [C]
17 KEP-3756: Robust VolumeManager reconstruction after kubelet restart (implemented, v1.30) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/3756-volume-reconstruction How the kubelet rediscovers mounts it made before restarting. A great "why is this hard?" read and a natural chaos drill (kill kubelet with volumes mounted). [C]
18 pkg/volume/csi/{csi_plugin.go (33.3 KB), csi_attacher.go, csi_mounter.go, csi_client.go} The kubelet-side CSI client: csi_client.go maps directly onto the spec RPCs read in #1; csi_mounter.go implements Node{Stage,Publish}Volume. Read csi_client.go first. [C]
19 KEP-284: Growing Persistent Volume size (implementable, v1.24) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/284-enable-volume-expansion Volume expansion: the controller-then-node two-phase resize and the FileSystemResizePending condition. [C]
20 KEP-556: Support for CSI volume resizing (implementable) and KEP-1790: Recover from volume expansion failure (implemented) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/556-csi-volume-resizing · https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1790-recover-resize-failure The CSI expansion RPCs, and how to undo an expansion you cannot fulfil (a wonderfully instructive failure mode). Code: pkg/controller/volume/expand/expand_controller.go, pkg/volume/csi/expander.go. [C]
21 KEP-177: CSI Snapshot (implemented, v1.20) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/177-volume-snapshot Snapshots: VolumeSnapshot/VolumeSnapshotContent/VolumeSnapshotClass — the same two-object pattern as PVC/PV, plus pre-provisioned vs dynamic. Note snapshots are CRDs + external-snapshotter, out of tree. Also storage/csi-snapshot.md in the archive. [B]
22 KEP-3476: Volume Group Snapshot — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/3476-volume-group-snapshot Crash-consistent multi-volume snapshots. Optional. [C]
23 KEP-625: In-tree Storage Plugin to CSI Migration (implementable, v1.25) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/625-csi-migration Why pkg/volume/ still contains legacy plugin scaffolding and how in-tree specs are translated to CSI. Read this to know what to ignore in pkg/volume/ — otherwise the learner wastes time on dead code. Code: staging/src/k8s.io/csi-translation-lib/. [B]
24 KEP-596: Ephemeral Inline CSI Volumes (implemented, v1.25) and KEP-1698: generic ephemeral inline volumes (implemented, v1.23) The two flavours of pod-lifetime volumes, and why generic ephemeral won. Code: pkg/controller/volume/ephemeral/controller.go (small and readable). [C]
25 KEP-1710: Skip SELinux relabeling of volumes (implemented) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1710-selinux-relabeling — and pkg/controller/volume/selinuxwarning/ Mount-time SELinux labelling instead of a recursive relabel — a real performance/security intersection. CKS-adjacent. [D]
26 pkg/controller/volume/{pvprotection,pvcprotection}/ The kubernetes.io/pvc-protection finalizer that stops you deleting a PVC in use. Tiny packages; excellent concrete finalizer example. [B]

Area 7 — kubelet

The hardest area to read, and the one where the curriculum must change approach. pkg/kubelet/kubelet.go is 156 KB, kuberuntime_manager.go is 107 KB, pod_workers.go is 78 KB. There is no readable "main loop" file. The corpus therefore leads with the SIG doc plus the archived design proposals — which, for the kubelet specifically, are unusually good and are the only narrative descriptions of PLEG, eviction and the cgroup hierarchy — and then enters code through the small, self-contained sub-managers.

⭐ ENTRY POINT: pkg/kubelet/pleg/generic.go (20.8 KB) — https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/pleg/generic.go The Pod Lifecycle Event Generator: one file, one loop (relist), one clear idea — periodically poll the container runtime, diff against the last known state, and emit ContainerStarted/ContainerDied events so the kubelet does not have to poll per pod. It is the beating heart of the kubelet reduced to a comprehensible size, it explains the PLEG is not healthy error every operator eventually meets, and it is preceded by a 2.7 KB interface file (pleg/pleg.go) that frames it perfectly.

Ordered approachable → hard:

# Item Teaches Difficulty
1 contributors/devel/sig-node/kubelet.md (9.6 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-node/kubelet.md SIG-Node's own orientation to kubelet architecture and its sub-managers. The map. Read first. [A]
2 contributors/devel/sig-node/container-runtime-interface.md (6.4 KB) — https://github.com/kubernetes/community/blob/main/contributors/devel/sig-node/container-runtime-interface.md CRI: the RuntimeService/ImageService split, sandbox (pause) vs container, and the versioning policy. Short and clear. [A]
3 staging/src/k8s.io/cri-api/README.md (15.7 KB) + staging/src/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto The CRI contract as a protobuf file — RunPodSandbox, CreateContainer, StartContainer, ListPodSandbox, ImageFsInfo. Reading the proto is far easier than reading the Go that consumes it, and it makes crictl output legible. [A]
4 node/pod-lifecycle-event-generator.md — https://github.com/kubernetes/design-proposals-archive/blob/main/node/pod-lifecycle-event-generator.md The PLEG design doc. Why per-pod polling did not scale and what relist replaced. The prose for the entry point. [A]
5 pkg/kubelet/pleg/pleg.go (2.7 KB) then pkg/kubelet/pleg/generic.go (20.8 KB) ⭐ Entry point — see above. [A]/[B]
6 KEP-3386: Kubelet Evented PLEG for Better Performance (implementable, v1.36) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/3386-kubelet-evented-pleg Runtime-pushed CRI events replacing polling, with relist kept as a safety net. Read with pkg/kubelet/pleg/evented.go. Perfect follow-on to #5. [B]
7 node/resource-qos.md — https://github.com/kubernetes/design-proposals-archive/blob/main/node/resource-qos.md The QoS design doc: how requests/limits produce Guaranteed / Burstable / BestEffort, and the eviction and OOM-score consequences. [A]
8 pkg/apis/core/v1/helper/qos/qos.go (4.6 KB) The QoS classification algorithm in 4.6 KB. GetPodQOS — read it and QoS is permanently demystified. Ideal early-phase file. [A]
9 pkg/kubelet/qos/policy.go OOM score adjustment per QoS class — the mechanism by which the kernel, not Kubernetes, kills your BestEffort pod first. Tiny. Directly relevant to factory's deliberate memory pressure. [A]
10 node/kubelet-eviction.md — https://github.com/kubernetes/design-proposals-archive/blob/main/node/kubelet-eviction.md The eviction design doc: signals (memory.available, nodefs.available, imagefs.available, pid.available), hard vs soft thresholds, grace periods, evictionMinimumReclaim, and the victim-ranking rules. Read before the code. [B]
11 pkg/kubelet/eviction/{types.go (7.3 KB), eviction_manager.go (27.4 KB)} The eviction manager: synchronize(), threshold evaluation, and pod ranking. types.go first — it names every concept. Well-structured code; genuinely readable after #10. [C]
12 pkg/kubelet/eviction/{helpers.go (56.8 KB), defaults_linux.go} The threshold parsing/ranking helpers and — in defaults_linux.go — the actual default eviction thresholds. Look up the defaults; treat helpers.go as reference. [D] (targeted [C])
13 pkg/kubelet/eviction/memory_threshold_notifier.go + threshold_notifier_linux.go cgroup memory pressure notification via eventfd — how the kubelet reacts faster than its housekeeping interval. Small and satisfying. [C]
14 KEP-4205: Expose PSI Metrics (implemented, v1.36) and KEP-5394: PSI based Node Conditions (implementable) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/4205-psi-metric · https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/5394-psi-node-conditions Pressure Stall Information as a first-class node signal. Very relevant to a deliberately-contended homelab. [C]
15 node/pod-resource-management.md — https://github.com/kubernetes/design-proposals-archive/blob/main/node/pod-resource-management.md The cgroup hierarchy design: kubepods → QoS-class cgroup → pod cgroup → container, and how cgroupsPerQOS enforces class-level limits. The prose behind the next item. [B]
16 pkg/kubelet/cm/{cgroup_manager_linux.go (16.4 KB), qos_container_manager_linux.go} cgroups v2 in practice: libcontainer cgroup manager use, unified-vs-v1 handling, and QoS cgroup construction. Pair with reading /sys/fs/cgroup/kubepods.slice/ on a live node — that pairing is the lab. [C]
17 KEP-2254: cgroups v2 (implementable, v1.25) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2254-cgroup-v2 The v2 migration: unified hierarchy, memory.max/memory.high, cpu.max, and the conversion of v1 settings. [B]
18 KEP-4569: Move cgroup v1 in maintenance mode (implemented, v1.31) and KEP-5573: Remove cgroup v1 support (implementable, v1.35) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/4569-cgroup-v1-maintenance-mode · https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/5573-remove-cgroup-v1 Currency: teach cgroups v2 only. Debian 13 "trixie" is v2-by-default anyway, so the homelab is already on the right side of this. [B]
19 KEP-2570: Memory QoS (implementable, v1.37) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2570-memory-qos memory.min/memory.high throttling instead of straight OOM-kill — a v2-only capability. [C]
20 node/node-allocatable.md — https://github.com/kubernetes/design-proposals-archive/blob/main/node/node-allocatable.md capacity − kube-reserved − system-reserved − eviction-hard = allocatable. Directly load-bearing for a 9.9 GB host: explains where the RAM went. Code: pkg/kubelet/cm/node_container_manager_linux.go. [A]
21 pkg/kubelet/config/{sources.go, file.go (6.4 KB), config.go} Static pods and pod-source merging: three sources (file, http, apiserver) reconciled into one stream, and why a static pod has a mirror pod. file.go is 6.4 KB — a great small read, and the mechanism every kubeadm control plane depends on. [B]
22 pkg/kubelet/lifecycle/{interfaces.go, predicate.go} Node-level admission: the kubelet's own last-chance check (GeneralPredicates, resource fit) after the scheduler already decided. The origin of OutOfmemory/OutOfcpu pod failures and the reason a pod can be rejected by the node. Small; conceptually important. [B]
23 pkg/kubelet/status/status_manager.go How pod status reaches the apiserver, with version bookkeeping to avoid stale overwrites. The write side of "what kubectl get pod shows you". [C]
24 pkg/kubelet/prober/{prober_manager.go, worker.go} Liveness/readiness/startup probes as per-container goroutines. worker.go holds the success/failure-threshold state machine. Readable and immediately practical. [B]
25 pkg/kubelet/kubelet_node_status.go + pkg/kubelet/util/nodelease.go + staging/src/k8s.io/component-helpers/apimachinery/lease/controller.go (11.2 KB) Node status and heartbeats/leases. Read the lease/controller.go file first — it is small and shows the modern cheap heartbeat; then see in kubelet_node_status.go how full status updates became infrequent. [C]
26 KEP-589: Efficient Node Heartbeat (implemented) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/589-efficient-node-heartbeats Why Lease objects exist: full NodeStatus writes every 10 s were an etcd write-amplification disaster. Explains the node-status-update-frequency vs lease-duration split and, with the nodelifecycle controller, the true node-failure detection latency. [B]
27 pkg/kubelet/pod_workers.go (78.2 KB) The per-pod goroutine that serialises sync/terminate/terminated transitions. Conceptually vital, physically hostile. Read only the type comments at the top — they are an excellent summary — then move on. [D]
28 pkg/kubelet/kuberuntime/{kuberuntime_manager.go (107.2 KB), kuberuntime_sandbox.go, kuberuntime_container.go} Where pod spec becomes CRI calls: computePodActions (the diff that decides what to create/kill) is the function worth reading. Reference-only otherwise. [D]
29 pkg/kubelet/kubelet.go (155.9 KB) The kubelet itself: syncLoop/syncLoopIteration and HandlePodAdditions. Never assign linearly. Read syncLoopIteration alone — ~100 lines that show the channel-multiplexing core — and get the rest from doc #1. [D]
30 KEP-753: Sidecar Containers (implemented, v1.33) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/753-sidecar-containers Restartable init containers: startup/shutdown ordering guarantees. A well-written KEP about a subtle lifecycle change. [B]
31 KEP-1287: In-place Update of Pod Resources (implemented, v1.35) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/1287-in-place-update-pod-resources Resizing without restart: resizePolicy, status.resources, and the resize conditions. Recently GA-ish and highly relevant on a RAM-tight host. Code: plugin/pkg/admission/podresize/. [C]
32 KEP-2000: Graceful Node Shutdown (implementable, v1.21) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2000-graceful-node-shutdown systemd inhibitor locks and priority-ordered pod termination on shutdown. Natural chaos-drill pairing with a Proxmox guest reboot. [C]
33 KEP-2221: Removing dockershim from kubelet (implemented, v1.24) — https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2221-remove-dockershim and KEP-2040: Kubelet CRI support (implementable, v1.23) The historical context that explains why so much online kubelet material is wrong, and why containerd/CRI-O are the only options now. [B]
34 pkg/kubelet/cm/cpumanager/{cpu_manager.go, policy_static.go} + KEP-3570: CPU Manager (implemented) and KEP-693: Node Topology Manager (implemented) CPU pinning and NUMA alignment. Optional — mostly irrelevant on a 6-core i5, but policy_static.go is a clean read if the learner is curious. [D]
35 contributors/devel/sig-node/kubelet-cri-networking.md (3.4 KB) How the kubelet delegates pod networking to CRI, which delegates to CNI — the seam between Areas 5 and 7. Short and clarifying. [B]

Cross-area synthesis: three end-to-end traces

The corpus above is organised by subsystem, but mastery is about the seams. Three traces, each stitching several areas, that make good phase capstones:

  1. kubectl run nginx → running container. kubectl/pkg/cmd/… → endpoints/filters/* → handlers/create.go → admission chain → registry/generic/registry/store.go → storage/etcd3/store.go → etcd Txn → watch cache → scheduler informer → schedule_one.go → Binding → kubelet config/apiserver.go → pod_workers.go → kuberuntime_manager.computePodActions → CRI → CNI. Areas 1+2+3+7+5. Assign only after all areas have been entered, but state the trace early as the thing being built toward.
  2. A pod dies and a Service stops sending it traffic. PLEG relist → status manager → apiserver → EndpointSlice reconciler → kube-proxy endpointschangetracker → syncProxyRules. Areas 7+4+5. Shorter, and a superb ~Phase-mid exercise because every hop is observable with kubectl and nft list ruleset.
  3. A PVC gets bound and mounted. PVC created → pv_controller.syncClaim (or delayed by volumebinding plugin) → csi-provisioner CreateVolume → attach/detach controller → VolumeAttachment → kubelet volume manager → NodeStageVolume/NodePublishVolume. Areas 6+3+4.

Verification notes and caveats

Path refactors that invalidate most existing third-party material — worth stating explicitly in the curriculum so the learner does not trust stale blog posts:

  • Scheduler queue: pkg/scheduler/internal/queue/ → pkg/scheduler/backend/queue/.
  • Scheduler framework: pkg/scheduler/framework/v1alpha1/ → pkg/scheduler/framework/ (no version segment).
  • Delayed volume binding: pkg/controller/volume/scheduling/ no longer exists → pkg/scheduler/framework/plugins/volumebinding/.
  • Watch cache: apiserver/pkg/storage/cacher.go → apiserver/pkg/storage/cacher/ (a package, split across cacher.go, watch_cache.go, delegator.go).
  • etcd: mvcc/ → server/storage/mvcc/; the Raft library was extracted from etcd-io/etcd to its own repo etcd-io/raft.
  • contributors/devel/ and the API conventions doc are in kubernetes/community, not kubernetes/kubernetes — a very common miscitation. contributors/design-proposals/ in that repo is now a stub README; the real corpus is the separate kubernetes/design-proposals-archive repo.
  • kube-proxy has three backends now (iptables, ipvs, nftables); pkg/proxy/userspace is gone.

Could not fully verify:

  • Gateway API GEP statuses. GEP-713 (Memorandum), GEP-1364 (Standard) and GEP-1016 (Standard) were read from source; GEP-2648/2649 titles were confirmed but their status fields were not cleanly extracted from metadata.yaml. Treat those two statuses as unconfirmed. Titles are exact.
  • kubernetes-csi/docs (the CSI sidecar documentation site) was confirmed to exist as a repo but its individual page paths were not enumerated; cite the site root https://kubernetes-csi.github.io/docs/ rather than deep links.
  • etcd doc version. k/k master vendors go.etcd.io/etcd/* v3.7.0, and the website has both v3.7 and v3.6 doc trees. Live 200 responses were confirmed for the v3.6 URLs used above; the v3.7 equivalents exist in the website repo but were not individually curl-checked. Prefer v3.7 URLs if the learner is on etcd 3.7, and expect these URLs to shift as versions roll.
  • Cilium docs are .rst rendered at docs.cilium.io; the in-repo paths were verified but the rendered URLs were not. Read them on GitHub or at docs.cilium.io/en/stable/network/ebpf/.
  • KEP status: fields (implemented/implementable/provisional/replaced) are as recorded in each kep.yaml today and lag reality slightly — e.g. KEP-268 preemption is long since GA but its kep.yaml still reads implementable. Trust the content, not the status field, for maturity.