Behöver ett Kubernetes-kluster på två platser tre etcd-röstare?
Tre kontrollplansnoder över två VPN-platser förlorar fortfarande kvorum när den större platsen slocknar. Räkna de verkliga etcd-röstarna och välj det avbrott du överlever.
Tre kontrollplans-VM:er känns som tre chanser att överleva en dålig natt. De är det inte, och avståndet mellan de två övertygelserna är det som förvandlar en prydlig tre-nodsdesign till ett kluster som slutar ta emot skrivningar när en byggnad tappar strömmen. En VPN-länk mellan platserna gör maskinerna nåbara för varandra och döljer problemet i stället för att lösa det. Röster räknas per etcd-medlem, och två av dessa medlemmar kan fortfarande sitta bakom en enda switch, en enda UPS och en enda uplänk.
Tre kontrollplansnoder, en feldomän
Du kör kubectl get nodes, ser tre kontrollplansposter och registrerar klustret som högt tillgängligt. Den siffran beskriver planerbar kapacitet, inte överlevnad. I kubeadm utan extern etcd är varje kontrollplansnod också värd för en medlem, så tre noder ger dig faktiskt tre röstare. Om dessa röstare misslyckas oberoende är en separat fråga som nodlistan inte kan svara på.
Två VM:er på en hypervisor, två rack på en strömförsörjning, två uplänkar från en ISP: varje par är en enda domän med två värdnamn. Skriv ned placeringen och markera vad varje röstare delar — hypervisor, PDU, switch högst upp i racket, lagringsarray, NAT-enhet, VPN-koncentrator. Ta sedan bort varje delat objekt på papperet och räkna om rösterna som återstår. Ett kluster som förlorar två röstare på grund av en enda misslyckad värd har hela tiden varit ett kluster med en röstare; ingen hade ställt frågan till det ännu.
Vad en delning på två platser kan och inte kan överleva
När tre röstare placeras två och en över två platser behåller den större sidan kvorum när den andra platsen försvinner, och sidan med en röstare aldrig. Den asymmetrin är aritmetik, inte trimning. Varje majoritetsbaserat etcd-kluster utspritt exakt över två oberoende platser misslyckas i testet "förlora vilken som helst plats och fortsätt att committa", eftersom båda sidor samtidigt måste hålla mer än hälften av rösterna.
Tabellen nedan är det snabbaste sättet att se vilka fel du faktiskt har köpt. Läs varje rad så här: om hela den här raden försvinner i natt, kan de överlevande fortfarande committa en skrivning?
| What disappears | Voters left | Writes still commit |
|---|---|---|
| Site B, holding voter 3 | 2 of 3 | Yes |
| Site A, holding voters 1 and 2 | 1 of 3 | No |
| One hypervisor carrying any two voters | 1 of 3 | No |
| The inter-site VPN only | 2 of 3 on one side | Only on the majority side |
Varför tunneln aldrig lägger till en röst
En VPN är transport, inte en medlem. Den kan göra en avlägsen röstare nåbar och den kan förvandla en partition till något som ser ut som en långsam timeout, och det är hela dess bidrag till kvorum. Det den lägger till är kostnad, eftersom varje commit måste korsa länken och etcd betalar den rundturen på skrivningar som rör raft-loggen. En väg som fladdrar förvandlar replikering till nya försök och val.
Partitioner är där människor förväntar sig magi, så var precis om dem. Om länken faller medan den gamle ledaren sitter på sidan med en röstare kan den sidan inte committa och ledaren avgår när valtimeouten löper ut, medan sidan med två röstare väljer en ersättare. etcd-guiden om fellägen beskriver beteendet rakt ut: fortsatt tjänst på majoritetssidan, inget andra skrivbart kluster på den isolerade sidan.
Bestäm vilket avbrott du köper
Två plus en är en legitim design när plats A är den primära och du accepterar att förlusten av den innebär förlust av kontrollplansskrivningar tills någon agerar. Det som gör det till en brist är att lämna det beslutet implicit. Skriv det i runbooken: vilken plats din kontrollplan överlever, och vad en operatör gör när den andra platsen slocknar klockan 03:00.
Om kravet i stället är "vilken som helst plats får misslyckas" måste placeringen hålla majoritet på varje plats, och tre röstare över två platser kan inte göra det. Du lägger antingen till en verkligt oberoende tredje domän — en liten region hos en annan leverantör fungerar om vägen dit är stabil — eller delar upp i två kluster med separat etcd och accepterar driftkostnaden för den delningen. Ingen genväg med ett vittne undviker detta: etcd har ingen lättviktsarbitermedlem, så en tredje röstare är en fullvärdig medlem med egna krav på disk, minne och nätverk. Att rita en ruta märkt vittne på diagrammet skapar inte ett vittne.
Kvorum är inte samma sak som tjänst
etcd-kvorum håller API-servern i stånd att ta emot skrivningar, och det är allt det håller. Lastbalanserarens hälsokontroller, ingress, CNI-nåbarhet genom tunneln, volymanslutningszoner och applikationsreplikering behöver var och en sitt eget svar. Ett kluster kan hålla en ren majoritet och ändå inte erbjuda något användbart till användarna.
Bekräfta sedan det medlemskap du tror att du har, eftersom diagram driver:
kubectl -n kube-system get pods -l component=etcd -o wide
kubectl get endpoints kube-apiserver -n default
etcdctl member list -w table
Jämför medlemslistan med placeringsritningen. Om två medlemmar löser ut till samma värd eller samma rack är det ritningen som är fel och inte klustret, och att ändra storlek runt en felaktig topologi köper bara en dyrare version av samma avbrott.
Innan du godkänner någon design med tre röstare, svara på fyra frågor: hur många röstare förlorar strömmen tillsammans, vilken platsförlust lämnar fortfarande en majoritet, var sitter ledaren när tunneln faller, och vad kan den överlevande platsen fortfarande göra. Ett "inte säker" på någon av dem betyder att klustret ännu inte är högt tillgängligt. Det är tre maskiner som har haft tur.