kubectl apply -f deployment.yaml converts the YAML to JSON and sends it as an HTTPS request to the API server — kubectl itself has no cluster logic; it's purely a REST client.
The API server authenticates the request (client cert, token, or OIDC) and then checks RBAC — does this identity have permission to create/update Deployments in this namespace? A denial stops everything right here.
AuthN/ZBefore persisting anything, admission webhooks/controllers can mutate the object (inject a sidecar, default values) or validate it (reject a Deployment missing resource limits, for example) — this is where policy enforcement (OPA/Gatekeeper, etc.) lives.
AdmissionThe API server persists the Deployment object to etcd, the cluster's key-value store. This is the single source of truth for desired cluster state — nothing in Kubernetes is "real" until it's here. No Pod exists yet at this point.
CheckpointThe Deployment controller (running in the control plane, watching the API server) notices the new Deployment and creates a ReplicaSet, which in turn creates Pod objects — again, only object definitions in etcd so far, nothing running.
ControllerThe scheduler watches for Pods with no assigned node, filters candidate nodes (enough CPU/memory, matching nodeSelector/taints), scores the survivors, and writes the chosen node name into the Pod's spec via the API server.
ScheduleEvery node runs a kubelet that continuously watches the API server for Pods assigned to its own node. It sees the new assignment and begins actually creating the container — this is the first point any real container work happens.
kubeletkubelet talks to the local container runtime (containerd, CRI-O) over the CRI (Container Runtime Interface). If the image isn't already cached on the node, it's pulled from the registry now — often the slowest single step in the whole sequence.
PullThe runtime creates and starts the container's namespaces/cgroups and launches the entrypoint process. kubelet reports the Pod phase as Running — but "Running" is not the same as "Ready."
StartIf a readinessProbe is defined, kubelet polls it (HTTP/TCP/exec). Only once it succeeds does the Endpoints controller add this Pod's IP to any matching Service's endpoint list — a Running-but-not-Ready Pod receives zero traffic.
ReadinessOnce the Pod is an active Endpoint, kube-proxy's rules on every node route matching Service traffic to it. Only now — 10 steps after you ran the command — is the new Pod actually serving real requests.
Serve| Term | Meaning |
|---|---|
| API Server | The single entry point for all cluster reads/writes — everything else watches it |
| etcd | Distributed key-value store holding the cluster's entire desired/actual state |
| Admission Controller | Webhook/plugin that mutates or validates objects before they're persisted |
| Controller | A watch-and-reconcile loop (Deployment, ReplicaSet, etc.) driving actual toward desired state |
| Scheduler | Assigns unscheduled Pods to a node based on resource fit and constraints |
| kubelet | Per-node agent that watches for Pod assignments and manages the actual containers |
| CRI | Container Runtime Interface — how kubelet talks to containerd/CRI-O |
| Readiness Probe | Health check gating whether a Pod receives traffic via a Service |
| Endpoints | The controller-maintained list of ready Pod IPs backing a Service |
| RBAC | Role-Based Access Control — governs who can do what against the API server |