Kubernetes — Structure#

Layout pattern#

Custom Monorepo — Staging + cmd/pkg hybrid

Kubernetes does not follow the standard Go module layout. It uses a home-grown staging monorepo pattern: 34 independently publishable k8s.io/* sub-libraries live under staging/src/k8s.io/ and are replace-directed in go.mod to local paths. The main module’s implementation lives in pkg/ (no internal/), entry points are in cmd/, and admission/auth plugins live in plugin/pkg/. Import boundaries are enforced not by Go’s internal/ mechanism but by the custom cmd/import-boss tool and .import-restrictions files scattered through staging/.

Directory map#

kubernetes/
├── api/              — OpenAPI spec JSON files, API discovery docs, API validation rules
├── build/            — Docker build infrastructure (server-image, pause container, build-image scripts)
├── CHANGELOG/        — Per-release changelogs
├── cluster/          — Cloud provider scripts (GCE), add-on configs, kubemark cluster support
├── cmd/              — All binary entry points (core components + codegen tools + dev tooling)
│   ├── kube-apiserver/
│   ├── kube-controller-manager/
│   ├── kube-scheduler/
│   ├── kubelet/
│   ├── kube-proxy/
│   ├── kubectl/
│   ├── kubectl-convert/
│   ├── kubeadm/
│   ├── cloud-controller-manager/
│   ├── kubemark/
│   ├── gendocs/ genkubedocs/ genman/ genyaml/ genswaggertypedocs/ genfeaturegates/
│   └── import-boss/ importverifier/ dependencycheck/ dependencyverifier/ clicheck/ ...
├── docs/             — User-facing documentation stubs
├── hack/             — Shell scripts: build, verify, codegen, test runners; make-rules library
├── LICENSES/         — Third-party and vendor license files
├── pkg/              — Core implementation (~842 Go package directories, no internal/)
│   ├── admission/    — Admission controller framework interfaces
│   ├── api/          — Internal API type helpers and validation
│   ├── apis/         — Internal type definitions for all API groups (versioned subdirs)
│   ├── auth/         — Authentication and authorization helpers
│   ├── controller/   — All ~40 built-in controllers (deployments, replicasets, jobs, etc.)
│   ├── controlplane/ — API server control-plane setup and wiring
│   ├── features/     — Feature gate constant definitions
│   ├── generated/    — Generated deepcopy functions and OpenAPI schema
│   ├── kubeapiserver/— API server configuration helpers
│   ├── kubectl/      — kubectl implementation helpers
│   ├── kubelet/      — Kubelet (largest sub-tree; CRI, volume, pod lifecycle)
│   ├── proxy/        — kube-proxy iptables/ipvs implementations
│   ├── quota/        — Resource quota evaluation framework
│   ├── registry/     — API resource storage strategies (etcd REST storage)
│   ├── scheduler/    — Scheduler framework, plugins, and algorithm profiles
│   ├── volume/       — Volume plugin system (in-tree and CSI bridge)
│   └── ...           — probe, printers, routes, security, serviceaccount, util, windows
├── plugin/
│   └── pkg/
│       ├── admission/— Built-in admission plugins (ResourceQuota, LimitRanger, etc.)
│       └── auth/     — Built-in authorization modules
├── staging/
│   └── src/k8s.io/   — 34 sub-modules published independently (see below)
├── test/             — e2e, integration, conformance, fuzz, and node test suites
├── third_party/      — Vendored code included directly (not via go mod)
└── vendor/           — Vendored all external dependencies

Entry points#

All cmd/ entry points follow a consistent <name>.go → app/server.go → app/options/ pattern. The top-level file is a thin main() wrapper that delegates to the app sub-package.

Core control-plane components#

BinaryEntry fileRole
kube-apiservercmd/kube-apiserver/apiserver.goThe central REST API server; all cluster state passes through here
kube-controller-managercmd/kube-controller-manager/controller-manager.goRuns all built-in reconciliation controllers in one process
kube-schedulercmd/kube-scheduler/scheduler.goAssigns pods to nodes using a plugin-based scheduling framework
cloud-controller-managercmd/cloud-controller-manager/main.goCloud-provider-specific control loops (separate from core CCM)

Node components#

BinaryEntry fileRole
kubeletcmd/kubelet/kubelet.goNode agent: manages pod lifecycle, CRI, volumes, health checks
kube-proxycmd/kube-proxy/proxy.goNetwork proxy: maintains iptables/ipvs rules for Service VIPs

User-facing tools#

BinaryEntry fileRole
kubectlcmd/kubectl/kubectl.goPrimary CLI for interacting with the cluster
kubectl-convertcmd/kubectl-convert/kubectl plugin for converting API objects between versions
kubeadmcmd/kubeadm/kubeadm.goCluster bootstrap and upgrade tooling

Scale testing#

BinaryRole
kubemarkHollow node simulator for scale-testing the control plane

Code generation tools (developer tooling only, not shipped)#

gendocs, genkubedocs, genman, genyaml, genswaggertypedocs, genfeaturegates — generate documentation artifacts. import-boss, importverifier, dependencycheck, dependencyverifier, clicheck, fieldnamedocscheck, preferredimports — CI verification tools.

Package organization#

Staging sub-modules (staging/src/k8s.io/)#

These are the foundation libraries. They are developed in-tree but published as independent modules via a periodic sync script. Key modules:

ModuleRole
k8s.io/apiVersioned API type definitions (core, apps, batch, rbac, …)
k8s.io/apimachineryRuntime machinery: runtime.Object, ObjectMeta, scheme, codec
k8s.io/apiserverGeneric API server framework (REST storage, admission, auth, RBAC)
k8s.io/apiextensions-apiserverCRD API server extension
k8s.io/client-goOfficial Go client: typed, dynamic, informers, work queues
k8s.io/kubectlkubectl command library (reusable outside the main binary)
k8s.io/controller-managerShared controller manager infrastructure
k8s.io/kube-schedulerScheduler framework interfaces and extension points
k8s.io/component-baseShared component infrastructure: logs, metrics, feature gates, version
k8s.io/cloud-providerCloud provider interface definitions
k8s.io/cri-apiContainer Runtime Interface (CRI) protobuf definitions
k8s.io/code-generatorCodegen tools: deepcopy-gen, register-gen, informer-gen, etc.
k8s.io/kmsKMS encryption provider API
k8s.io/dynamic-resource-allocationDRA (structured parameters) framework
k8s.io/sample-controllerReference implementation of a custom controller

Internal packages (pkg/)#

No internal/ directory exists at the repo root; access control is enforced by import-boss. The pkg/ tree holds ~842 package directories — the bulk of the Kubernetes implementation. Notable clusters:

  • pkg/controller/ — ~40 controllers, each in its own subdirectory (deployment, replicaset, job, daemonset, statefulset, endpoint, namespace, node, serviceaccount, …)
  • pkg/kubelet/ — Largest single sub-tree; contains CRI client wiring, pod lifecycle, volume management, eviction, QoS, PLEG (Pod Lifecycle Event Generator)
  • pkg/scheduler/framework/ — Plugin framework with defined extension points (Filter, Score, Reserve, Bind, …)
  • pkg/registry/ — Etcd-backed REST storage for each API resource group
  • pkg/volume/ — In-tree volume plugins and CSI bridge

Public packages (plugin/pkg/)#

Admission plugins and authorization modules that depend on pkg/ but are logically separate from it. Houses built-in admission plugins like ResourceQuota, LimitRanger, PodSecurity, ServiceAccount, and authorization plugins like RBAC and Node.

Layering#

The dependency graph flows strictly bottom-up:

staging/src/k8s.io/{api,apimachinery}   ← no k8s deps; pure types + primitives
         ↓
staging/src/k8s.io/{apiserver,client-go,component-base}   ← use api+apimachinery
         ↓
pkg/{apis,registry,controller,scheduler,kubelet,…}   ← use staging libs
         ↓
plugin/pkg/{admission,auth}   ← use pkg/
         ↓
cmd/*/app/   ← wire everything together; only layer allowed to import broadly

This layering is enforced by .import-restrictions files processed by import-boss at CI time. Violations fail the build.

Build system#

  • Build tool: GNU Make, delegating to hack/make-rules/ shell library
  • Key targets:
    • make all — Build all binaries (cross-compiles for linux/amd64 by default)
    • make test — Run unit tests
    • make test-integration — Run integration tests (requires etcd)
    • make test-e2e-node — Run e2e node tests
    • make clean — Remove build artifacts
    • make verify — Run all verification scripts (lint, import checks, codegen drift)
    • make update — Regenerate all generated code
  • Docker: Yes, multi-stage. build/ contains:
    • build/server-image/Dockerfile — Multi-stage build producing the server container image
    • build/pause/Dockerfile — The pause container (infra container for pod network namespaces)
    • build/build-image/ — The hermetic build container used in CI
  • Codegen: Extensive. hack/ scripts drive k8s.io/code-generator to regenerate deepcopy functions, typed clients, informers, listers, conversion functions, and OpenAPI schemas. Generated files are checked in and drift is detected in CI.

Notable structural decisions#

  1. No internal/ at the root. Unlike most Go projects, Kubernetes does not use Go’s internal/ directory to restrict imports. Instead it invented import-boss: a custom tool that reads .import-restrictions JSON files and enforces allowed/forbidden import rules at CI time. This predates Go’s internal/ feature being well-established but is now a maintained design choice.

  2. Staging as in-tree monorepo. The staging/ directory is arguably the most distinctive structural decision. 34 libraries that are consumed by the entire Go ecosystem (client-go, apimachinery, apiserver, etc.) are developed in the same commit graph as the main binary. A periodic automated job (“publishing-bot”) syncs each staging module to its own GitHub repository. This allows atomic cross-module refactors while maintaining independent versioning for consumers.

  3. plugin/ as a controlled extension layer. Admission and authorization plugins that must ship with the binary but are logically distinct from core pkg/ code live in plugin/pkg/. This separation makes it easy to audit what is “core framework” vs. “policy implementation.”

  4. cmd/*/app/ pattern universally applied. Every binary, from kube-apiserver to kubeadm to codegen tools, uses the same two-level structure: a thin cmd/<name>/<name>.go with main() delegating to cmd/<name>/app/server.go. Options are always in cmd/<name>/app/options/. This consistency across 25+ binaries is non-trivial.

  5. test/ as a first-class top-level directory. Rather than collocating all tests with source, Kubernetes has a dedicated test/ directory with 353+ package directories covering e2e (cluster-level), e2e_node (per-node), integration (in-process with real etcd), conformance, fuzz, and kubemark scale tests. This reflects the project’s commitment to treating testing infrastructure as a product in itself.

  6. vendor/ is committed. All external dependencies are vendored in a committed vendor/ directory. This is a deliberate choice for reproducibility in a project where thousands of contributors work across multiple organizations. It also enables offline builds and simplifies the build container setup.