This is the first post in my CKA notes. I wanted to understand what really happens between typing a command and seeing a pod in Running. Here’s the path for a simple Deployment:
kubectl apply -f deployment.yaml
1. kubectl talks to the API server
kubectl reads your kubeconfig, finds the cluster address and your credentials, and sends an HTTPS request to the kube-apiserver. Everything in Kubernetes goes through the API server. Nothing talks to etcd directly.
2. Authentication, authorization, admission
The API server checks three things in order:
- Authentication: who are you? (client certificate, token, OIDC…)
- Authorization: are you allowed to do this? Usually RBAC: can this user create deployments in this namespace?
- Admission: admission controllers can modify the object (mutating) or reject it (validating). This is where policies like Pod Security Admission live.
This is the first place where security happens in Kubernetes, which is why RBAC and admission control show up so much in DevSecOps work.
3. The object is stored in etcd
Once accepted, the Deployment is saved in etcd, the cluster’s key-value store. At this point nothing is running yet. Kubernetes only stored your desired state.
4. Controllers do the work
The controller manager runs control loops that watch the API server. The Deployment controller sees the new Deployment and creates a ReplicaSet. The ReplicaSet controller sees it needs, say, 3 pods and creates 3 Pod objects. Still nothing is running: the pods have no node yet.
5. The scheduler picks a node
The kube-scheduler watches for pods without a node. It filters out nodes that can’t run the pod (not enough CPU or memory, taints, node selectors) and scores the rest. Then it writes its decision back to the API server: this pod goes on node-2.
6. The kubelet starts the containers
The kubelet on node-2 sees a pod assigned to it. It asks the container runtime (usually containerd) through the CRI to pull the image and start the containers, sets up networking through the CNI plugin, and reports the pod status back to the API server.
The pattern
Every component watches the API server and moves the real state closer to the desired state. That’s the whole idea of Kubernetes: you declare what you want, and controllers keep reconciling until it’s true.
kubectl get events --sort-by=.metadata.creationTimestamp
Run that right after an apply and you can watch these steps happen in order.