# Cheat sheet — Kubernetes

Dense revision sheet. Interview one-liners + `kubectl` at the bottom.

---

## The one-sentence model
**You declare desired state (spec); controllers run a reconcile loop that drives actual state
(status) toward it, forever.** Everything else is objects + control loops.

## Cluster anatomy
| Plane | Component | Job |
|---|---|---|
| **Control** | kube-apiserver | the API front door; only thing that writes etcd |
| | etcd | consistent key-value store of ALL cluster state |
| | kube-scheduler | picks a Node for each unscheduled Pod |
| | kube-controller-manager | runs the controllers (the reconcile loops) |
| **Node** | kubelet | starts/monitors Pods, runs probes, reports status |
| | kube-proxy | programs Service networking on the node |
| | container runtime | containerd — actually runs the containers |

## Workload hierarchy
```
Deployment  ──manages──►  ReplicaSet  ──manages──►  Pod  ──runs──►  container(s)
 (updates,                (keeps N                  (shared IP +
  rollout,                 identical                 storage,
  rollback)                replicas)                 ephemeral)
```
- **Rolling update:** new ReplicaSet scaled up while old scaled down; zero downtime
  (`maxSurge` / `maxUnavailable`). Rollback = flip back to the old RS.
- **Self-healing:** kill a Pod → the ReplicaSet makes a new one. Never `kubectl run` bare Pods.

## Deployment vs StatefulSet
| | Deployment | StatefulSet |
|---|---|---|
| Pods | interchangeable clones | stable identity `pod-0,1,2…` |
| Startup/scale | any order, parallel | ordered, one at a time |
| Storage | usually shared/none | own PersistentVolume per pod |
| Network | via Service | stable per-pod DNS (headless svc) |
| Repo | 22 services | **only `tom` + `conversationmgmt`** |

## Services
| Type | Reaches | 
|---|---|
| **ClusterIP** (default) | in-cluster only (repo default, hard-coded) |
| **NodePort** | a port on every node (repo: none) |
| **LoadBalancer** | external IP (repo: only `zeus` sftpgo) |
| **headless** (`clusterIP: None`) | DNS → Pod IPs (StatefulSets) |
- **Cluster DNS:** `service.namespace.svc.cluster.local`. Same idea as Course 1's Docker
  service-name resolution, cluster-wide.

## Config, health, resources
- **ConfigMap** = non-secret config; **Secret** = sensitive (base64, Opaque). Repo secrets are
  SOPS-encrypted, decrypted **in-process** (no sidecar).
- **Probes:** *startup* ("booted yet?" holds off the others) → *readiness* ("send traffic?"
  gates Service endpoints) → *liveness* ("stuck? restart"). Repo uses `grpc_health_probe`.
- **requests** = reserved (scheduling); **limits** = ceiling (CPU throttle / memory OOMKill).

## Scaling & reliability
- **HPA** — more replicas to hit a metric (CPU%). **VPA** — resize the pod. **KEDA** — scale on
  events (Kafka lag, Prometheus), even **to zero**. Repo: KEDA dominant (`ScaledObject`);
  notification scales `-consumers` on `kafka_consumergroup_lag` (threshold 7500).
- **PDB** — cap voluntarily-down pods (`maxUnavailable`/`minAvailable`); protects drains. Repo
  default `maxUnavailable: 1`.
- **Scheduling** — labels/selectors match; **affinity** attracts, **taints+tolerations** repel.
- **Termination** — SIGTERM → grace period (+ `preStop`) → SIGKILL.

## Access
- **Namespace** = partition. Repo: `{ENV}-{ORG}-backend` (e.g. `local-manabie-backend`).
- **RBAC** — Role/ClusterRole (verbs on resources) + RoleBinding (grant to subject).
- **ServiceAccount** — Pod identity; repo annotates it for GCP **Workload Identity**.

---

## Repo anchors (all from the `libs/util` library chart)
| Object | Where |
|---|---|
| everything (orchestrator) | `deployments/helm/libs/util/templates/_app.tpl:7` |
| Deployment | `…/_deployment.tpl:30` · e.g. `backend/spike` |
| StatefulSet | `…/_statefulset.tpl:4` · `backend/tom`, `backend/conversationmgmt` |
| Service (ClusterIP) | `…/_service.tpl:4` |
| KEDA ScaledObject | `…/_keda.tpl` · `notificationmgmt/…/scaledobject-consumers.yaml` |
| PDB | `…/_pdb.tpl:4` (maxUnavailable 1) |
| probes (grpc_health_probe) | `…/_workload_containers.tpl:76-142` |
| namespace `{ENV}-{ORG}-backend` | `backend/bob/skaffold.yaml:10` |

## kubectl survival kit
```
kubectl get pods -n local-manabie-backend         # list
kubectl describe pod <p> -n <ns>                   # events, why it won't start
kubectl logs <p> -n <ns> [-f] [--previous]         # container logs
kubectl rollout status/restart/undo deploy/<svc>   # deployments (sk.bash uses restart)
kubectl get deploy,sts,svc,scaledobject,pdb -n <ns># the objects this course covers
kubectl exec -it <p> -n <ns> -- sh                 # shell inside a container
```

## Interview one-liners
- **What is Kubernetes?** *"A system that runs your declared desired state via reconcile loops
  — you say 5 replicas, controllers keep 5 alive."*
- **Pod vs container?** *"A Pod is the smallest unit — one+ containers sharing an IP and
  storage, scheduled together. Usually one app container per Pod here."*
- **Deployment vs StatefulSet?** *"Deployment = interchangeable clones; StatefulSet = stable
  identity + ordered + own storage. We use StatefulSets only for tom and conversationmgmt."*
- **How does a rolling update avoid downtime?** *"New ReplicaSet scales up as the old scales
  down; readiness probes gate traffic so only ready pods receive it."*
- **Readiness vs liveness?** *"Readiness gates traffic; liveness restarts a stuck container.
  Failing readiness pulls you out of the Service, not kills you."*
- **KEDA vs HPA?** *"HPA scales on CPU/mem; KEDA scales on events (Kafka lag, Prometheus) and
  down to zero — it generates an HPA under the hood."*
