What happens when you run kubectl apply
Sunil Tiwari · Oct 12, 2026 · 2 min read
From a YAML file to running containers: the API server, etcd, controllers, the scheduler and the kubelet.
You type kubectl apply -f deployment.yaml and, seconds later, pods are running. In between, six components cooperate without ever calling each other directly. They all just watch the API server.
The manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels: { app: web }
template:
metadata:
labels: { app: web }
spec:
containers:
- name: web
image: nginx:1.27
ports: [{ containerPort: 80 }]Step by step
- kubectl validates the file, computes a diff and sends it to the API server.
- The API server authenticates you, runs admission controllers and writes the Deployment to etcd.
- The Deployment controller notices it and creates a ReplicaSet.
- The ReplicaSet controller creates 3 Pod objects with no node assigned.
- The scheduler picks a node for each pod (resources, affinity, taints) and writes the binding.
- The kubelet on that node sees a pod bound to it, pulls the image and starts the container via the runtime.
sequenceDiagram participant K as kubectl participant A as API server participant E as etcd participant C as Controllers participant S as Scheduler participant L as Kubelet K->>A: apply Deployment A->>E: persist C-->>A: watch: new Deployment C->>A: create ReplicaSet + 3 Pods S-->>A: watch: unscheduled Pods S->>A: bind Pod → node-2 L-->>A: watch: Pod on node-2 L->>L: pull image, start container L->>A: status: Running
The key idea: reconciliation
Every controller runs the same loop: compare desired state (in etcd) with actual state, then act to close the gap. That is why deleting a pod just makes a new one appear.
Nothing in Kubernetes calls anything else. Everything watches the API server and reconciles.
Check it yourself
kubectl apply -f deployment.yaml
kubectl get events --sort-by=.metadata.creationTimestamp
kubectl get pods -o wide -w