End-to-End Request Flow
High-Level Flow
1 — User creates a Pod (kubectl apply)
POST /api/v1/namespaces/{ns}/pods request
to the API server.
-
AuthenticationThe API server verifies the caller's identity via client certificates, bearer tokens, or webhook authenticators.pkg/kubeapiserver/authenticator/config.go
-
Authorization (RBAC / webhook)The request verb+resource+namespace is checked against RBAC policies or external webhook authorizers.pkg/kubeapiserver/authorizer/config.go
-
Admission ControlMutating and validating admission webhooks (plus built-in plugins like LimitRanger, ResourceQuota) run before the object is persisted.pkg/admission/plugin/namespace/lifecycle/admission.go
-
etcd WriteThe validated Pod object is serialized and stored in etcd. The API server returns 201 Created to the client.pkg/registry/core/pod/storage/storage.go
2 — Scheduler picks a node
spec.nodeName == "").
When a new pod appears it enters the scheduling queue.
-
Queue — pod enters ActiveQThe scheduling queue prioritizes pods. The scheduling goroutine blocks onschedule_one.go L67–96 ScheduleOne()
NextPod()until a pod is dequeued. -
Filter phase — feasible nodesFilter plugins (NodeAffinity, NodeUnschedulable, PodTopologySpread, etc.) prune infeasible nodes.schedule_one.go L175–198 schedulingCycle()
-
Score phase — rank nodesScore plugins assign numeric scores to each feasible node. The node with the highest sum wins.
-
Bind — write nodeName to API serverThe scheduler writes aschedule_one.go L150–170 runBindingCycle()
Bindingobject (or PATCH on the Pod) settingspec.nodeName. This triggers the kubelet.
3 — Kubelet runs the Pod
spec.nodeName == thisNode. When a pod lands
it enters the pod-worker pipeline.
-
syncLoop — multiplex sourcesMerges updates from API server watch, static pod files, and HTTP into a singlekubelet.go L2630 syncLoop()
configChchannel. -
Pod workers — concurrent SyncPod()A per-pod goroutine callskubelet.go L2029 SyncPod()
SyncPod()which mounts volumes, pulls images, and drives the CRI to create/start containers. -
CRI call — container runtimeThe Container Runtime Interface (containerd, CRI-O) creates the sandbox and containers via gRPC.
-
PLEG — lifecycle eventsThe Pod Lifecycle Event Generator polls the runtime and fires events (ContainerStarted, ContainerDied) back into the sync loop.
4 — Controllers maintain desired state
-
Shared informers — efficient watchAll controllers share a single API server watch stream per resource type. Objects are cached locally in a thread-safe store.
-
Work queue — rate-limited reconcileEvent handlers enqueue changed object keys. Worker goroutines dequeue and call the reconcile function with backoff.
-
ReplicaSet controller exampleCounts running pods. If count < replicas, creates new pods via API server. If count > replicas, deletes excess pods.pkg/controller/replicaset/replica_set.go
Components
kube-apiserver control plane
Central REST gateway. Validates, stores, and serves all Kubernetes objects. Every other component talks only to the API server — never directly to each other.
Explore API Server flow →kube-scheduler control plane
Watches unscheduled pods and assigns them to nodes using
a plugin-based filter/score pipeline. Writes the result
as a Binding back to the API server.
kubelet node
Node agent. Runs one per node. Watches pods assigned to its node and drives the container runtime (CRI) to match actual state to desired state.
Explore Kubelet flow →kube-controller-manager control plane
Hosts dozens of controllers (ReplicaSet, Deployment, Node lifecycle, ServiceAccount, …). Each runs an independent reconcile loop to maintain resource invariants.
Explore Controller Manager flow →