Kubernetes basics
Kubernetes basics
Started at Google in 2014, built on Borg (2003) and Omega (2013), donated to the CNCF in 2015.
The one big idea
Desired state vs current state. You declare what you want; controllers compare it with reality and act until the two match. Everything else is a variation on this loop.
graph LR
U[You: manifest] --> A[API server]
A --> E[(etcd - desired state)]
C[Controller] --> A
C --> C
C -->|create / delete| K[kubelet on node]
K -->|reports current state| A
Architecture
graph TB
subgraph control01 [Control plane]
API[kube-apiserver]
ETCD[(etcd)]
SCH[kube-scheduler]
CM[kube-controller-manager]
end
subgraph worker0X [Worker node]
KL[kubelet]
KP[kube-proxy]
CRI[containerd]
end
API --- ETCD
SCH --- API
CM --- API
KL --- API
KP --- API
KL --- CRI
| Component | Job |
|---|---|
| kube-apiserver | the only door to the cluster; REST + validation |
| etcd | stores the desired state |
| kube-scheduler | picks a node for each new Pod |
| kube-controller-manager | runs the reconciliation loops |
| kubelet | runs and watches containers on its node |
| kube-proxy | implements Service networking on its node |
| containerd | the container runtime (CRI) |
Pluggable by standard
- CRI - runtime. Docker is not a CRI runtime and has not been supported since 1.24; this cluster runs containerd.
- CNI - networking plugin.
- CSI - storage drivers. This cluster has none, which is why the storage lab builds PersistentVolumes by hand.
Imperative vs declarative
kubectl run web01 --image nginx # imperative: an action
kubectl apply -f pod.yaml # declarative: a desired state
Imperative is for exploring. Everything that must survive gets versioned as YAML
and applied. Only apply is idempotent.
The API is REST
| Verb | HTTP | kubectl |
|---|---|---|
| Create | POST | kubectl create -f |
| Read | GET | kubectl get / describe |
| Update | PUT/PATCH | kubectl apply -f / edit |
| Delete | DELETE | kubectl delete |