Toen ik voor het eerst een “productie” Kubernetes cluster opzette, had ik één control plane node. Het werkte prima totdat het niet meer werkte — een kapotte disk haalde het hele cluster neer. Elke pod, elke service, alles. Die dag leerde me wat “single point of failure” echt betekent.
Kubernetes High Availability is niet optioneel voor productie. Maar er is een keuze die veel mensen in verwarring brengt: draai je etcd op je control plane nodes (stacked), of op aparte dedicated nodes (external)? Laat me beide benaderingen uitleggen.
Wat is etcd en Waarom Doet Het Ertoe?
etcd is Kubernetes’ brein. Het is een gedistribueerde key-value store die alle cluster state bevat: pod definities, secrets, configmaps, service accounts — alles. Als je kubectl apply doet, eindigt het in etcd.
Als etcd sterft, is je cluster hersendood. De API server kan niet functioneren, controllers kunnen geen state reconcilen, niets werkt. Daarom bepaalt etcd beschikbaarheid direct de cluster beschikbaarheid.
etcd gebruikt het Raft consensus algoritme, dat een quorum (meerderheid) van nodes vereist om te functioneren. Met 3 etcd nodes kun je er 1 verliezen. Met 5 kun je er 2 verliezen. Verlies quorum, en etcd wordt read-only totdat nodes herstellen.
Stacked etcd: De Simpele Aanpak
In een stacked topologie draait etcd op elke control plane node naast de API server, controller manager en scheduler.
flowchart TD
subgraph stacked["Stacked etcd Topologie"]
subgraph CP1["Control Plane Node 1"]
API1["API Server"]
Ctrl1["Controller"]
Sched1["Scheduler"]
etcd1["etcd"]
end
subgraph CP2["Control Plane Node 2"]
API2["API Server"]
Ctrl2["Controller"]
Sched2["Scheduler"]
etcd2["etcd"]
end
subgraph CP3["Control Plane Node 3"]
API3["API Server"]
Ctrl3["Controller"]
Sched3["Scheduler"]
etcd3["etcd"]
end
end
Voordelen van Stacked etcd
Eenvoud: Minder nodes om te beheren. Drie nodes geven je een volledig HA control plane met etcd quorum.
Kosten: De helft van de infrastructuur vergeleken met external etcd. Voor homelabs en kleinere deployments telt dit.
Makkelijker setup: kubeadm, k3s en de meeste installers defaulten naar stacked omdat het simpeler is. kubeadm init met --control-plane-endpoint en je bent klaar.
Gekoppelde lifecycle: Control plane en etcd schalen samen. Voeg een control plane node toe, krijg automatisch een etcd member.
Nadelen van Stacked etcd
Gekoppelde failure: Als een node sterft, verlies je zowel een control plane component ALS een etcd member. De blast radius is groter.
Resource contention: etcd is gevoelig voor disk latency. Als je API server de disk hamert tijdens een grote list operatie, kan etcd heartbeats missen en leader election triggeren.
Schaal beperkingen: Je wilt misschien 5 API servers maar slechts 3 etcd members (of andersom). Stacked topologie dwingt ze te matchen.
External etcd: De Ontkoppelde Aanpak
External etcd draait op dedicated nodes, volledig gescheiden van het control plane.
flowchart TD
subgraph external["External etcd Topologie"]
subgraph etcd_cluster["etcd Cluster"]
E1["etcd Node 1"]
E2["etcd Node 2"]
E3["etcd Node 3"]
end
etcd_cluster --> control_plane
subgraph control_plane["Control Plane Nodes"]
subgraph CP1["Control Plane 1"]
API1["API Server<br/>Controller<br/>Scheduler"]
end
subgraph CP2["Control Plane 2"]
API2["API Server<br/>Controller<br/>Scheduler"]
end
subgraph CP3["Control Plane 3"]
API3["API Server<br/>Controller<br/>Scheduler"]
end
end
end
Voordelen van External etcd
Geïsoleerde failures: Een control plane node die sterft beïnvloedt etcd quorum niet. Een etcd node die sterft beïnvloedt API server beschikbaarheid niet.
Onafhankelijke schaling: Draai 3 etcd members en 5 API servers, of wat je workload ook nodig heeft.
Geoptimaliseerde resources: Dediceer snelle SSDs aan etcd nodes. Geef API servers meer RAM. Elk component krijgt wat het nodig heeft.
Makkelijker etcd onderhoud: Backup, restore en upgrade etcd zonder het control plane aan te raken.
Nadelen van External etcd
Complexiteit: Meer nodes, meer bewegende delen, meer netwerkpaden om te beveiligen.
Kosten: Dubbel het aantal nodes voor de control plane tier.
Netwerk afhankelijkheid: Het API server naar etcd pad wordt kritiek. Netwerkproblemen daartussen breken alles.
Setup overhead: kubeadm vereist handmatige etcd cluster setup voor het initialiseren van het control plane.
Wanneer Welke Gebruiken
Kies Stacked etcd Wanneer:
- Kleine tot medium clusters: Onder 100 nodes is stacked meestal prima
- Homelab of development: Minder nodes betekent minder stroom, minder kosten
- Team eenvoud: Je team heeft niet veel ervaring met etcd operations
- Managed Kubernetes: EKS, GKE, AKS regelen dit toch voor je
Kies External etcd Wanneer:
- Grote clusters: 100+ nodes betekent meer API server load, meer etcd writes
- Strikte SLAs: Wanneer je gekoppelde failures niet kunt veroorloven
- Gemixte workloads: Je moet control plane en etcd onafhankelijk schalen
- etcd expertise: Je team weet hoe etcd clusters te opereren
Stacked HA Opzetten met kubeadm
Hier is de praktische setup voor stacked HA:
# Op eerste control plane node
kubeadm init \
--control-plane-endpoint "loadbalancer.example.com:6443" \
--upload-certs
# Bewaar de join commands voor andere control planes
# Join extra control plane nodes
kubeadm join loadbalancer.example.com:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane \
--certificate-key <cert-key>
De sleutel is --control-plane-endpoint — dit moet naar een load balancer voor je API servers wijzen, niet een enkel node IP.
External etcd Opzetten
Voor external etcd bootstrap je eerst het etcd cluster:
# Op elke etcd node, configureer etcd
cat > /etc/etcd/etcd.conf.yaml << EOF
name: etcd-1
data-dir: /var/lib/etcd
initial-cluster-state: new
initial-cluster: etcd-1=https://10.0.0.1:2380,etcd-2=https://10.0.0.2:2380,etcd-3=https://10.0.0.3:2380
listen-peer-urls: https://10.0.0.1:2380
listen-client-urls: https://10.0.0.1:2379,https://127.0.0.1:2379
advertise-client-urls: https://10.0.0.1:2379
initial-advertise-peer-urls: https://10.0.0.1:2380
client-transport-security:
cert-file: /etc/etcd/pki/server.crt
key-file: /etc/etcd/pki/server.key
trusted-ca-file: /etc/etcd/pki/ca.crt
peer-transport-security:
cert-file: /etc/etcd/pki/peer.crt
key-file: /etc/etcd/pki/peer.key
trusted-ca-file: /etc/etcd/pki/ca.crt
EOF
Wijs dan kubeadm naar het externe cluster:
# kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
etcd:
external:
endpoints:
- https://10.0.0.1:2379
- https://10.0.0.2:2379
- https://10.0.0.3:2379
caFile: /etc/kubernetes/pki/etcd/ca.crt
certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
Wat Over K3s?
K3s defaultt naar embedded etcd (stacked) met een simpelere setup:
# Eerste server
curl -sfL https://get.k3s.io | sh -s - server --cluster-init
# Extra servers
curl -sfL https://get.k3s.io | sh -s - server \
--server https://first-server:6443 \
--token <token>
K3s ondersteunt ook externe databases (MySQL, PostgreSQL) als etcd alternatief, wat handig kan zijn als je die databases al draait.
Mijn Aanbeveling
Voor de meeste use cases, begin met stacked etcd. Het is simpeler, goedkoper, en voor clusters onder 100 nodes met redelijke workloads werkt het prima.
Ga naar external etcd wanneer je:
- etcd performance problemen ervaart
- Onafhankelijke schaling nodig hebt
- Strikte beschikbaarheidseisen hebt die de complexiteit rechtvaardigen
Ik draai stacked etcd in mijn homelab op drie control plane nodes. Het heeft node failures, netwerkproblemen en de occasionele “oeps ik reboottte de verkeerde server” overleefd. Stacked betekent niet fragiel — het betekent gekoppeld.
Het belangrijkste is niet stacked vs external. Het is minstens drie control plane nodes met etcd hebben. Eén node is geen HA. Twee nodes is erger dan één (je hebt majority quorum nodig, en 2/2 - 1 = 1, wat betekent dat je geen nodes kunt verliezen).
Drie nodes. Dat is het minimum voor echte HA.
Kubernetes HA gaat over failures overleven, niet voorkomen. Failures zullen gebeuren. De vraag is of je cluster ze overleeft.
