☸️ Kubernetes Architecture — Deep Dive: Control Plane, Pod Lifecycle, CNI, CSI, HPA, Operator Pattern

Panduan komprehensif arsitektur Kubernetes dari control plane sampai data plane. Mencakup komponen control plane (kube-apiserver, etcd, scheduler, controller-manager), node & kubelet internals, pod lifecycle & scheduling algorithm, networking dengan CNI (Calico, Cilium, Flannel), storage dengan CSI, auto-scaling (HPA/VPA/KEDA), operator pattern, dan failure modes di tiap layer. Bukan catatan security — itu sudah ada di container-kubernetes-security-deepdive. Catatan ini adalah fondasi arsitektur yang wajib dikuasai sebelum baca security notes.

Posisi di Vault

Ini adalah fondasi platform untuk semua catatan yang bergantung pada K8s. Baca ini dulu sebelum container-kubernetes-security-deepdive (security hardening), cloud-infrastructure (Level 4: Container Orchestration), cloud-security-posture-management (CSPM & K8s posture), cicd-guide (CI/CD di K8s), dan observability-stack-prometheus-grafana (monitoring K8s dengan Prometheus Operator).


Daftar Isi


Arsitektur Control Plane

Diagram Arsitektur

┌──────────────────── Control Plane ────────────────────┐
│                                                        │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐ │
│  │ kube-apiserver │  │ kube-scheduler│  │controller-  │ │
│  │ (REST API)    │  │ (bind pod)   │  │ manager      │ │
│  └──────┬───────┘  └──────────────┘  └──────────────┘ │
│         │                                               │
│  ┌──────▼───────┐                                       │
│  │    etcd       │  ← source of truth                   │
│  │  (RAFT DB)   │                                       │
│  └──────────────┘                                       │
└────────────────────────────────────────────────────────┘
           │
           ▼ (kubelet on each node)
┌──────────────────── Data Plane ───────────────────────┐
│  ┌──────────┐  ┌──────────┐  ┌──────────┐            │
│  │ Pod      │  │ Pod      │  │ Pod      │            │
│  │ (c1, c2) │  │ (c1)     │  │ (c1,c2,c3)│           │
│  └──────────┘  └──────────┘  └──────────┘            │
│  ┌──── kubelet + kube-proxy on each node ──────────┐ │
│  │  iptables/IPVS rules for Service routing        │ │
│  └─────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────┘

Komponen Control Plane

KomponenFungsiHigh Availability
kube-apiserverGatekeeper — semua komunikasi lewat REST API di port 6443. Validasi, autentikasi, otorisasi, admission controlMultiple instance (active-active) di belakang LB. Setiap instance handle request independen
etcdDistributed key-value store — satu-satunya source of truth. Simpan semua state cluster: Pod, ConfigMap, Secret, Deployment, dllQuorum-based (3, 5, 7 node). RAFT consensus. Wajib backup reguler
kube-schedulerAssign pod ke node yg cocok. Dua fase: Filter (eliminasi node yang ga cocok) → Score (ranking node)Leader election (1 active, N standby). Hanya 1 scheduler aktif karena stateful decision
kube-controller-managerController loop untuk resource bawaan: Deployment, ReplicaSet, Node, Endpoint, ServiceAccount, NamespaceLeader election (1 active per controller)

Flow Detail: kubectl apply -f deployment.yaml

1. kubectl → POST /apis/apps/v1/.../deployments → kube-apiserver
2. API Server:
   a. Authentikasi (client cert / token / OIDC)
   b. Otorisasi (RBAC: can create deployments?)
   c. Admission Control (MutatingWebhook → validate resource → ValidatingWebhook)
   d. Validasi schema (apakah spec valid?)
   e. Simpan ke etcd
3. Deployment Controller (dalam controller-manager):
   a. Watch: detect Deployment baru di etcd
   b. Reconcile: current state ≠ desired state
   c. Buat ReplicaSet object (via API Server → etcd)
4. ReplicaSet Controller:
   a. Watch: detect ReplicaSet baru
   b. Hitung: butuh N pod, current = 0
   c. Buat Pod spec (via API Server → etcd)
5. Scheduler:
   a. Watch: detect Pod tanpa node assignment (spec.nodeName = "")
   b. Filter: eliminasi node yang gak cocok
   c. Score: ranking node yang cocok
   d. Bind: update Pod dengan nodeName (via API Server → etcd)
6. Kubelet di node target:
   a. Watch: detect Pod baru dengan nodeName = namanya
   b. Validasi: apakah Pod spec valid?
   c. Pull image: dari registry
   d. Setup volume: CSI/emptyDir/hostPath
   e. Setup network: CNI plugin assign IP
   f. Start container: via CRI (containerd)
   g. Health check: liveness & readiness probe mulai jalan

Semua ini terjadi dalam < 5 detik untuk pod sederhana (tanpa image pull).

Node & Kubelet

Komponen Node

KomponenFungsiPort
kubeletPrimary node agent. Register node ke cluster, manage pod lifecycle, jalankan health check (liveness/readiness/startup probe), report node status ke API server10250 (kubelet API)
kube-proxyNetwork proxy per node. Maintain iptables/IPVS rules untuk Service → Pod routing. Bisa dalam mode: userspace, iptables, IPVS, atau kernelspace (eBPF)10256 (health check)
container runtimecontainerd (default sejak K8s 1.24), CRI-O, atau Docker (via cri-dockerm). Implementasi CRI (Container Runtime Interface)Unix socket
cAdvisor (built-in kubelet)Resource metrics: CPU, memory, disk, network per containerEmbedded in kubelet

Node Conditions

ConditionArtiPenyebab Umum
ReadyKubelet sehat, pod bisa di-scheduleNormal
DiskPressureDisk space/nodefs/inodes < thresholdLog gak di-rotate, image sampah, PV penuh
MemoryPressureRAM available < kubelet eviction thresholdMemory leak di workload
PIDPressureTerlalu banyak proses ( > kernel.pid_max )Fork bomb, process leak
NetworkUnavailableNetwork plugin bermasalahCNI pod crash, misconfig

Kubelet Eviction

Ketika node dalam tekanan resource, kubelet evict (terminate) pod berdasarkan QoS class:

  1. BestEffort (tanpa request/limit) — di-evict duluan
  2. Burstable (request < limit) — di-evict jika melebihi request
  3. Guaranteed (request == limit) — di-evict paling akhir (hanya jika node benar2 OOM)

Pod Lifecycle & Scheduling

Pod Phases

           ┌──────────┐
           │ Pending  │
           └────┬─────┘
                │ scheduler assign node
                ▼
          ┌──────────┐
          │ Running  │ ← container started, probes passing
          └────┬─────┘
               │
      ┌────────┴────────┐
      ▼                 ▼
┌──────────┐     ┌──────────┐
│Succeeded │     │  Failed  │
│(batch)   │     │(error)   │
└──────────┘     └──────────┘

Unknown: kubelet lost contact (> node-monitor-period + node-monitor-grace-period)

Init Containers

Jalankan setup task sebelum app container start. Urutan eksekusi sequential.

initContainers:
  - name: init-db
    image: busybox
    command: ["sh", "-c", "until nc -z db-service 5432; do sleep 1; done"]
  - name: init-config
    image: busybox
    command: ["sh", "-c", "cp /config-template/* /config/"]

Scheduling Algorithm Detail

Filtering (Predicates)

Semua predicate harus LULUS — if any fails, node dieliminasi:

  • PodFitsResources — CPU/Mem request ≤ node allocatable
  • PodFitsHost — nodeSelector cocok
  • PodToleratesNodeTaints — pod tolerates taints, atau node tidak punya taint
  • CheckNodeUnschedulable — node tidak di-cordon
  • CheckVolumeBinding — PVC bisa di-mount di node ini
  • NodeAffinity — required affinity rules cocok
  • PodTopologySpread — spread constraints terpenuhi

Scoring (Priorities)

Setiap node yang lulus filtering diberi skor 0-100:

  • LeastRequestedPriority — prefer node dengan resource paling longgar (spread load)
  • MostRequestedPriority — prefer node dengan resource paling penuh (binpack)
  • BalancedResourceAllocation — prefer node dengan resource balance (CPU = Mem)
  • NodeAffinityPriority — preferred affinity rules
  • TaintTolerationPriority — prefer node dengan tolerable taints

Default strategy: spread load across nodes (LeastRequestedPriority menang).

Pod Disruption Budgets

Garansi jumlah minimum pod tetap running saat voluntary disruption (drain, update):

apiVersion: policy/v1
kind: PodDisruptionBudget
spec:
  minAvailable: 2 # atau maxUnavailable: 1
  selector:
    matchLabels:
      app: myapp

Networking — CNI

Model Jaringan K8s (3 Aturan Emas)

  1. Setiap pod punya IP unik (dalam cluster)
  2. Semua pod bisa komunikasi dengan pod lain tanpa NAT
  3. Agent (kubelet/scheduler) bisa komunikasi dengan semua pod

CNI Plugin Architecture

Pod -> veth pair -> cni0/eth0 (bridge) -> node routing table -> overlay tunnel -> destination node

CNI Plugin Comparison

PluginData PlaneOverheadNetworkPolicyFitur KunciBest For
FlannelVXLANRendah❌ TidakSimple, VXLAN/ host-gwDev/lab, small cluster
CalicoBGP / eBPFRendah-Sedang✅ YaNetworkPolicy, wireguard encryption, no overlayProduction on-prem, hybrid
CiliumeBPFSangat Rendah✅ Ya (L3-L7)Hubble observability, service mesh L7 policy, cluster meshModern production, security-sensitive
WeaveFast datapathRendah✅ YaEncrypt otomatis, simpleSmall-mid cluster
OVN-K8sOVSSedang✅ YaDistribusi OpenShift, multi-tenantEnterprise OpenShift
kube-routerBGPRendah✅ YaAll-in-one (CNI + network policy + service proxy)Sederhana, all-in-one

Service Types

TypeAksesUse Case
ClusterIPInternal cluster onlyInternal microservices
NodePortExternal via node IP:portDev/test, direct access
LoadBalancerExternal via cloud LBProduction HTTP services
ExternalNameDNS CNAME aliasIntegrasi external service
Headless (ClusterIP: None)DNS-based pod discoveryStatefulSet, database

Storage — CSI

Volume Types

TypeLifespanUse Case
emptyDirSama dengan podCache, temporary workspace
hostPathSama dengan nodeLog access, device access (single node)
configMap/secretSama dengan podKonfigurasi, credential
PersistentVolume (PV)Terpisah dari podDatabase, persistent data
StorageClassDynamic provisioningAuto-create PV saat PVC request

CSI Flow

Pod spec → PVC → StorageClass → CSI Driver → Cloud API → Volume → Attach → Mount → Pod ready

Auto-scaling — HPA / VPA / KEDA

MekanismeMetrikTriggerScaleCooldown
HPA (Horizontal)CPU, Memory, Custom Metrics, External MetricsTarget utilization > thresholdTambah/kurang replica podDefault 3-5 menit
VPA (Vertical)Resource usage historyRequest/limit jauh dari actual usageUpdate CPU/Mem request & limit24 jam (rekomendasi)
KEDA (Event-driven)Queue length (Kafka, RabbitMQ, SQS), cron, Prometheus, customExternal event sourceTambah/kurang replica (deploy, statefulset, job)Configurable

HPA Formula

desiredReplicas = ceil[currentReplicas * (currentMetricValue / desiredMetricValue)]

VPA Modes

  • Off — hanya rekomendasi, tidak auto-apply
  • Auto — update pod (evict + recreate dengan request/limit baru)
  • Initial — apply hanya saat pod pertama kali dibuat
  • Recreate — sama dengan Auto tapi evict pod (bisa disruptif)

Operator Pattern

Operator = Custom Controller + Custom Resource Definition (CRD) — manusia yang mengoperasikan aplikasi dalam kode.

Komponen Operator

  1. CRD — define custom resource (e.g., PostgresCluster, RedisFailover)
  2. Controller — watch CRD + reconcile (compare current vs desired state)
  3. RBAC — permission untuk manage resource terkait

Contoh: Prometheus Operator

User buat ServiceMonitor CR → Operator detect → Operator buat/mutate Prometheus config → Prometheus scrape target baru

Operator Maturity Level

LevelKemampuanContoh
L1Basic installHelm install
L2Seamless upgradeOperator upgrade CR
L3Full lifecycleBackup, restore, failure recovery
L4Deep insightsMetrics, alerts, logging
L5Auto-pilotHorizontal scaling, auto-tuning, anomaly detection

Failure Modes

LayerFailure ModeSymptomMitigation
etcdQuorum loss (leader election failed)API server read-only3+ node etcd, regular backup
API ServerAdmission webhook timeoutAll API calls slowTimeout config, webhook HA
SchedulerFailed to bind podPod stuck in PendingMultiple scheduler replicas
KubeletDead node (NotReady)Pod stuck in TerminatingPodDisruptionBudget, node auto-repair
CNIIP exhaustionPod CrashLoopBackOffIPAM planning, secondary CIDR
CSIVolume attach timeoutPod ContainerCreating > 5 minCSI driver HA, storage backend health
HPAMetrics pipeline broken (metrics-server/cAdvisor down)No auto-scalePod default resource, PDB

Koneksi ke Vault