Object Create Path
What happens between kubectl apply and a running Pod? The manifest travels to the API and lands in ETCD, and then a chain of watchers takes over: the Deployment controller creates a ReplicaSet, the ReplicaSet controller creates a Pod, the Scheduler assigns that Pod a Node, and the Kubelet there starts it. Every handoff after the write is one component reacting to a change on its own watch rather than a call, until the Kubelet drives the Runtime over CRI.
Play the animation 7 steps, animated, best on a wide screen
Object Create Path, step by step
-
You run kubectl apply -f deploy.yaml. The client serializes the manifest as JSON and POSTs it to /apis/apps/v1/namespaces/default/deployments on the API. On an object that already exists the client sends a three-way merge PATCH instead, and Server-side Apply is the same PATCH under its own content type.
Play from step 1 -
The API authenticates the caller from your kubeconfig, checks RBAC, runs admission and schema validation, then writes the new Deployment my-app to ETCD. ETCD commits the write via Raft quorum at rv=842.
Play from step 2 -
ETCD acks the committed write back to the API at rv=842, and the API returns HTTP 201 Created to the kubectl client. The Deployment now exists in cluster state, but no Pods have been created yet.
Play from step 3 -
The Deployment controller, inside the controller-manager, sees my-app via its watch on the API and creates a ReplicaSet (my-app-7d4). The ReplicaSet controller sees THAT on a watch of its own and creates a Pod (my-app-7d4-x2k9p) with no nodeName yet. Nobody calls anybody.
Play from step 4 -
The Scheduler picks up my-app-7d4-x2k9p, filters candidate Nodes (taints, resources, affinity), scores the survivors on free resources and topology spread, then posts a Binding that pins the Pod to Node-1. That write goes through the API into ETCD like the first one.
Play from step 5 -
The Kubelet on Node-1 has a filtered watch on /api/v1/pods?fieldSelector=spec.nodeName=Node-1. The API streams my-app-7d4-x2k9p down that watch to Node-1, where the Kubelet picks it up.
Play from step 6 -
The Kubelet drives the Runtime over CRI, one call at a time: first a Pod sandbox, which gets the Pod its network namespace and IP, then the nginx:1.27 image, then the container starting inside that sandbox. The Pod my-app-7d4-x2k9p is Running on Node-1.
Play from step 7