Kubernetes över flera kontinenter: k3s och k8s med hög tillgänglighet i datacenter världen över

Publicerad den 13 min läsning

Kubernetes över USA, Europa och Asien där en hel kontinent får falla bort: varför etcd inte klarar långa avstånd, ett k3s-kluster per region, GitOps med Flux, geo-DNS-failover, data över regiongränser och skillnaderna mot kubeadm.

Kubernetes är standardvalet när applikationer ska vara feltåliga och skala automatiskt. Den uppenbara idén att sträcka ut ett enda Kubernetes-kluster över servrar i USA, Europa och Asien stupar dock på en detalj: etcd, databasen där Kubernetes lagrar hela sitt tillstånd. Den här artikeln visar hur Kubernetes över flera kontinenter ändå fungerar, och det så att en hel kontinent får falla bort: med ett kluster per region, en gemensam utrullning via GitOps och en geo-DNS som skickar användarna till närmaste fungerande region.

Vi bygger arkitekturen med k3s, den slimmade och fullt certifierade Kubernetes-distributionen som installeras på några minuter, och visar i slutet vad som ändras med en klassisk Kubernetes-installation via kubeadm. Grunderna om tillgänglighet, kvorum och failover över flera platser beskrivs utförligt i artikeln Docker Swarm över tre kontinenter; här handlar det om det som är annorlunda med Kubernetes.

Ett kluster över alla kontinenter eller ett kluster per region?

För Kubernetes över flera kontinenter är ett kluster per region rätt arkitektur, inte ett enda kluster över alla kontinenter. Varje kluster körs för sig, alla rullas ut från samma Git-repository och en geo-DNS med hälsokontroller fördelar användarna. Faller en region bort tar de andra över, utan att ett gemensamt klustertillstånd behöver samordnas över havet.

Varför etcd inte klarar långa avstånd

Kubernetes lagrar varje tillstånd, varje konfiguration och varje ändring i etcd, en nyckel-värde-databas med Raft-konsensus. Varje skrivoperation måste bekräftas av en majoritet av alla etcd-medlemmar. Som standard arbetar etcd med ett heartbeat-intervall på 100 millisekunder och en timeout för ledarval på en sekund; mellan Europa, Nordamerika och Asien ligger paketens gångtid på 80 till 250 millisekunder. Du kan höja tiderna, men då blir varje skrivoperation i klustret långsam, från schemaläggningen av en pod till lagringen av en Secret. k3s-dokumentationen är entydig på den här punkten: inbyggd etcd stöds inte i kluster som är utspridda över flera nätverk, och alla servrar ska stå på samma plats. Även Kubernetes egen konstruktion utgår från att ett kluster täcker flera zoner inom en region, inte flera kontinenter.

De tre mönstren jämförda

MönsterSå fungerar detBedömning
Ett kluster över alla kontinenterKontrollplan och etcd fördelade över flera kontinenterRekommenderas inte: långsamma skrivoperationer, instabil etcd, stöds inte av k3s med inbyggd etcd
Kontrollplan i en region, arbetsnoder världen överServrar på en plats, agenter på andra kontinenterFungerar tekniskt, men faller kontrollplanets region bort kan ingenting längre schemaläggas om någonstans i världen
Ett kluster per regionTre oberoende kluster, gemensamt utrullade via GitOps, med geo-DNS framförRekommenderas: varje region klarar att de andra faller bort, och fel stannar inom en region

Upplägget ”ett kluster per region” har en andra, ofta underskattad fördel: ett fel i kontrollplanet, en felaktig ändring i klustret eller en uppgradering som går snett drabbar alltid bara en region. Användarna i de andra regionerna märker ingenting av det.

k3s eller k8s?

Båda är äkta Kubernetes med samma API, samma manifest och samma verktyg. Skillnaden ligger i uppbyggnaden och i arbetsinsatsen:

Egenskapk3sk8s med kubeadm
InstallationEtt kommando, en binärfilContainer-runtime, kubeadm, kubelet och nätverksplugin sätts upp var för sig
Resurser för en servernodMinst 2 kärnor och 2 GB RAMBetydligt mer, beroende på komponenterna
IngårIngress-controller (Traefik), nätverk (Flannel), provisioner för lagring, lastbalanserare för tjänsterBara kärnan, allt annat väljer du själv
Hög tillgänglighetInbyggd etcd med tre servrarTre kontrollplansnoder med lastbalanserare framför API:et
Passar förDe flesta applikationer, små team, en enda nod per regionTeam som vill bestämma varje komponent själva

För arkitekturen med ett kluster per region rekommenderar vi k3s: att driva tre kluster är bara behagligt om vart och ett av dem är enkelt. Har du redan erfarenhet av kubeadm tar du över arkitekturen oförändrad, och avsnittet om kubeadm längre ned visar skillnaderna.

Arkitekturen: tre regioner, tre kluster, en ingång

ByggstenUppgiftVilket bortfall den fångar upp
Ett k3s-kluster per regionKör applikationen nära användarnaBortfall av en hel region
Tre servrar per region (utbyggnadssteg)Håller etcd och kontrollplanet högtillgängliga inom regionenBortfall av enskilda servrar i en region
Git-repository och Flux per klusterVarje kluster hämtar själv sitt önskade tillstånd från GitIngen central driftsättningsserver som felpunkt
Ingress med certifikat via DNS-utmaningTar emot användarnas förfrågningarCertifikaten fungerar oberoende av DNS-omkopplingen
Geo-DNS med hälsokontrollerSkickar användare till närmaste fungerande regionRegioner som inte går att nå
Replikerad datalagring och backuperHåller data i flera regionerDataförlust när en region faller bort

Startnivå och utbyggnad

Startnivån är tre servrar, en vardera i USA, Europa och Asien, var och en som ett eget enkelnodskluster. Faller en server bort faller dess region bort, och geo-DNS-tjänsten skickar regionens användare till grannregionen. Redan den här nivån är utformad för att klara att en hel kontinent faller bort. I utbyggnaden får varje region tre servrar på samma plats, och då klarar också varje region på egen hand att en server faller bort, utan att några användare behöver omdirigeras.

Vilka KernelHost-platser som passar

KernelHost driver servrar i maincubes-datacentret i Frankfurt am Main och erbjuder virtuella servrar på ytterligare platser i Europa, Nordamerika och Asien-Stillahavsområdet, bland annat tre platser i USA, Kanada, London, Strasbourg, Warszawa, Helsingfors, Singapore, Japan, Sydney och Mumbai. Den fullständiga listan finns på sidan Serverplatser. Exemplet i den här artikeln använder Frankfurt am Main för Europa, USA:s östkust för Nordamerika och Singapore för Asien.

Guide: Kubernetes med k3s i tre regioner

Exemplet använder tre servrar med Debian 12 eller 13: k3s-eu, k3s-us och k3s-asia. De publika adresserna kommer från dokumentationsnätet 203.0.113.0/24 och domänen är example.com. Ersätt båda med dina egna värden.

Steg 1: förbered servrar i tre regioner

Beställ tre servrar i tre regioner, var och en med minst 2 vCPU och 4 GB RAM, så att även din applikation får plats bredvid k3s. Genomför den grundläggande härdningen från checklistan för nya rootservrar och ge servrarna beskrivande värdnamn. etcd drar märkbar nytta av snabba SSD:er, och NVMe-lagringen i KernelHost-servrarna uppfyller det kravet.

Steg 2: installera k3s

På var och en av de tre servrarna installerar du k3s med ett kommando. Varje server blir därmed ett komplett Kubernetes-kluster med en nod:

curl -sfL https://get.k3s.io | sh -
kubectl get nodes

Efter ungefär en minut visar kubectl get nodes noden som Ready. Med i paketet finns Traefik som ingress-controller, Flannel som nätverk och en provisioner för lokala volymer.

Steg 3: bygg ut till tre servrar per region

Ska en region i sig bli högtillgänglig placerar du tre servrar på samma plats. Den första servern startar den inbyggda etcd-databasen, och de två andra ansluter med en gemensam token. etcd kräver ett udda antal servrar, och med tre servrar klarar regionen att en server faller bort:

curl -sfL https://get.k3s.io | K3S_TOKEN=HEMLIG_TOKEN sh -s - server \
    --cluster-init \
    --tls-san=api.eu.example.com
curl -sfL https://get.k3s.io | K3S_TOKEN=HEMLIG_TOKEN sh -s - server \
    --server https://203.0.113.21:6443 \
    --tls-san=api.eu.example.com

Alla servrar i en region behöver samma inställningar för nätverksintervall och funktioner. Mellan dem måste portarna 2379 till 2380/TCP för etcd, 6443/TCP för API:et, 10250/TCP för kubelet och 8472/UDP för Flannel-nätet vara öppna, medan de förblir spärrade utåt. Denna token är en hemlighet: den som känner till den kan ansluta egna servrar till klustret.

Steg 4: sätt upp åtkomst till alla tre kluster

k3s lägger åtkomstuppgifterna i /etc/rancher/k3s/k3s.yaml. Kopiera filen från varje kluster till din arbetsdator, ersätt 127.0.0.1 i den med serverns adress och döp kontexterna efter regionen:

kubectl config rename-context default eu
kubectl config use-context eu
kubectl --context us get nodes

API:et på port 6443 är den mest kraftfulla vägen in i klustret. Tillåt åtkomsten i brandväggen bara från din egen adress eller från ett VPN, aldrig för hela internet. Filen k3s.yaml innehåller ett administratörscertifikat och ska förvaras lika omsorgsfullt som ett rootlösenord.

Steg 5: GitOps med Flux i varje kluster

För att alla tre regionerna ska köra samma applikation i samma version ligger det önskade tillståndet i ett Git-repository, och i varje kluster körs Flux, som på egen hand upprättar det tillståndet. Varje kluster hämtar alltså sin konfiguration själv; någon central driftsättningsserver som skulle kunna gå ner finns inte. Ett beprövat upplägg för repositoryt:

apps/
  web/            gemensamma manifest för applikationen
clusters/
  eu/             inställningar och version för Europa
  us/             inställningar och version för Nordamerika
  asia/           inställningar och version för Asien
flux bootstrap git --url=ssh://git@git.example.com/infra/fleet.git --branch=main --path=clusters/eu

Samma kommando kör du med --path=clusters/us och --path=clusters/asia i respektive kontext. Eftersom varje region har en egen katalog kan du rulla ut en ny version i en region och först därefter i de andra.

Steg 6: beskriv applikationen så att den tål avbrott

Inom en region ser tre saker till att applikationen klarar underhåll och serveravbrott: flera repliker som fördelas på olika noder, kontroller som upptäcker felande poddar och en budget som förhindrar att ett underhåll tar bort alla poddar samtidigt:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels:
              app: web
      containers:
        - name: web
          image: registry.example.com/web:1.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            periodSeconds: 10
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: web
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: web

Readiness-kontrollen tar bort en pod från trafiken så länge den inte svarar, och liveness-kontrollen startar om den när den hänger sig. I ett enkelnodskluster har fördelningen på flera noder ännu ingen effekt; den slår till automatiskt så snart regionen har tre servrar.

Steg 7: ingress och certifikat

Ingången sköts av Traefik, som redan ingår. Eftersom alla tre regionerna betjänar samma domän hämtar du TLS-certifikaten med cert-manager via DNS-utmaningen: den fungerar i varje region, oavsett vart DNS-posten pekar för tillfället. HTTP-utmaningen misslyckas däremot i varje region som posten just då inte pekar på. Arbetar du utan Kubernetes-ingress hittar du grunderna i artikeln Sätt upp nginx som omvänd proxy.

Steg 8: sätt upp geo-DNS med failover

En DNS-tjänst med geo-routing och hälsokontroller skickar användare från Europa till Frankfurt am Main, från Amerika till USA:s östkust och från Asien till Singapore, och kontrollerar med 30 till 60 sekunders intervall om ingången i varje region svarar. Faller en region bort lämnar tjänsten inte längre ut dess adress. Sätt TTL för posterna till 60 sekunder, så är en omställning oftast klar efter en till två minuter. Vill du sköta posterna inifrån klustret kan du använda external-dns för det.

Steg 9: rulla ut region för region och testa ett bortfall

En ny version för du först in i en regions katalog, observerar sedan regionen i några minuter och för därefter in versionen även för de andra. På så sätt når ett fel som ingen kontroll upptäcker högst en region. Ett regionbortfall övar du genom att stoppa k3s på regionens server, och du kontrollerar samtidigt om geo-DNS-tjänsten tar bort regionen ur sina svar och om grannregionen bär lasten:

systemctl stop k3s
systemctl start k3s

I en region med tre servrar övar du dessutom underhåll av en enskild server. kubectl drain flyttar poddarna med hänsyn till budgeten från steg 6, och kubectl uncordon tar servern i drift igen:

kubectl drain k3s-eu-2 --ignore-daemonsets --delete-emptydir-data
kubectl uncordon k3s-eu-2

Data över regiongränser

Kubernetes fördelar poddar, inte data. En PersistentVolume från den medföljande provisionern ligger på exakt en nod, och mellan klustren finns från början ingen gemensam datalagring alls. För allt som har med data att göra gäller därför samma sak som för varje kluster över flera platser:

  • Databaser replikerar sig själva. Ett beprövat upplägg är en primär instans i en region med repliker i de andra; databasoperatorer som CloudNativePG för PostgreSQL stöder sådana repliker även över klustergränser. Mellan kontinenter sker replikeringen asynkront, så i ett skarpt läge kan de sista sekundernas skrivoperationer saknas. För förlustfri skrivning världen över finns databaser för flera regioner, som CockroachDB eller YugabyteDB.
  • Filer och uppladdningar hör hemma i en S3-kompatibel objektlagring med replikering till en andra region.
  • Sessioner ligger i en replikerad databas eller en replikerad cache, eller så använder applikationen signerade tokens.
  • Backuper är fortfarande ett måste, eftersom replikering sprider fel precis som den sprider korrekta data. För Kubernetes-objekt och volymer passar Velero; grunderna finns i backupstrategin för servrar.

Kubernetes med kubeadm i stället för k3s

Med kubeadm förblir arkitekturen densamma: ett kluster per region, GitOps, geo-DNS. Det som skiljer sig är hur varje kluster byggs upp. Du installerar en container-runtime som containerd samt kubeadm, kubelet och kubectl på alla noder, placerar en lastbalanserare eller en virtuell adress framför regionens API, till exempel med kube-vip, och initierar den första kontrollplansnoden:

kubeadm init --control-plane-endpoint "api.eu.example.com:6443" --upload-certs

Utdatan innehåller två anslutningskommandon: ett med --control-plane --certificate-key för de två ytterligare kontrollplansnoderna och ett för arbetsnoder. Därefter installerar du ett nätverksplugin som Calico eller Cilium och en ingress-controller, som k3s redan har med sig. Det extra arbetet lönar sig om du måste välja enskilda komponenter medvetet eller hålla dig nära upstream-versionen.

Varför KernelHost för Kubernetes över flera kontinenter

KravVarför det spelar rollHos KernelHost
Platser på flera kontinenterEtt kluster per region kräver servrar i varje regionFrankfurt am Main plus platser i Europa, Nordamerika och Asien-Stillahavsområdet från en och samma leverantör
Obegränsad trafikImage-nedladdningar, databasreplikering och backuper ger konstant trafikVPS med obegränsad trafik utan volymtak
Snabb lagringetcd reagerar känsligt på långsamma diskarNVMe-SSD:er i RAID
DDoS-skyddVarje ingress är publikt nåbarIngår på varje plats, på huvudplatsen Frankfurt am Main med 3,2 Tbps Arbor-realtidsfiltrering, utan null-routing
Full rootåtkomstk3s, brandvägg och kernelinställningar kräver full kontrollPå varje KVM-rootserver och dedikerad server
Ingen avtalsbindningNoder och testkluster kommer och gårPrePaid, ingen bindningstid, ingen startavgift
AutomatiseringNya noder ska kunna skapas med skriptBeställning och styrning via KernelHost API

En översikt över alla molnpaket och en kostnadsjämförelse med de stora molnleverantörerna hittar du på sidan Hyra molnserver.

Vanliga misstag och hur du undviker dem

  • etcd utsträckt över kontinenter. Följden blir långsamma skrivoperationer och instabila ledarval, och med k3s och inbyggd etcd stöds det inte. Lösning: ett kluster per region.
  • Två servrar i en region. etcd behöver en majoritet, och två servrar klarar inte ett enda bortfall. Lösning: en eller tre.
  • API:et öppet för hela internet. Port 6443 är huvudnyckeln till klustret. Lösning: bara från den egna adressen eller via VPN.
  • Central driftsättningsserver. Går den ner kan ingenting längre rullas ut. Lösning: Flux i varje kluster, som själv hämtar från Git.
  • Uppdatering i alla regioner samtidigt. Ett fel drabbar då alla användare. Lösning: region för region via katalogerna i repositoryt.
  • Certifikat via HTTP-utmaning. I regioner som DNS-posten just då inte pekar på misslyckas förnyelsen. Lösning: DNS-utmaning.
  • Databas på en lokal volym utan replikering. Faller noden bort är datan oåtkomlig. Lösning: replikering via en databasoperator.
  • Inga probes och ingen budget. Felande poddar fortsätter att få trafik, och underhåll tar alla poddar ur drift samtidigt. Lösning: readiness- och liveness-kontroll plus PodDisruptionBudget.

Kort sammanfattning

  • För Kubernetes över flera kontinenter är ett kluster per region rätt; ett enda kluster över alla kontinenter stupar på etcd:s latens.
  • Startnivån är tre servrar, en vardera i USA, Europa och Asien; redan den nivån klarar att en hel kontinent faller bort.
  • I utbyggnaden får varje region tre servrar på samma plats, och då klarar varje region även att enskilda servrar faller bort.
  • Flux i varje kluster rullar ut applikationen från samma Git-repository, region för region.
  • Geo-DNS med hälsokontroller och kort TTL skickar användare till närmaste fungerande region, och certifikaten hämtas via DNS-utmaning.
  • Kubernetes fördelar poddar, inte data: databaser behöver egen replikering, och backuper är fortfarande ett måste.
  • k3s är för den här arkitekturen oftast ett bättre val än kubeadm, eftersom tre enkla kluster är lättare att driva än tre komplexa.

Vanliga frågor

Kan ett Kubernetes-kluster köras över flera kontinenter?
Tekniskt går det att fördela kontrollplanet, men det är inte att rekommendera. Kubernetes lagrar sitt tillstånd i etcd, och varje skrivoperation måste bekräftas av en majoritet av alla etcd-medlemmar. Mellan kontinenter ligger gångtiden på 80 till 250 millisekunder, och etcd arbetar som standard med ett heartbeat-intervall på 100 millisekunder. Enligt k3s-dokumentationen stöds inbyggd etcd inte över distribuerade nätverk. Rätt lösning är ett kluster per region.
Hur bygger man upp Kubernetes med hög tillgänglighet över flera regioner?
Med ett eget kluster per region, till exempel ett k3s-kluster vardera i USA, Europa och Asien. Alla kluster rullas ut via GitOps från samma Git-repository, exempelvis med Flux i varje kluster, och en geo-DNS med hälsokontroller skickar användarna till närmaste fungerande region. Faller en region bort tar de andra över, utan att ett gemensamt tillstånd behöver samordnas över havet.
Vad är skillnaden mellan k3s och k8s?
Båda är Kubernetes fullt ut, med samma API och samma manifest. k3s är en slimmad, certifierad distribution i en enda binärfil som installeras med ett kommando och har med sig ingress-controller, nätverk och provisioner för lagring; en server behöver minst 2 kärnor och 2 GB RAM. Ett k8s-kluster med kubeadm sätts ihop av enskilda komponenter, ger större valfrihet och kräver mer arbete.
Hur många servrar behöver ett högtillgängligt k3s-kluster?
Tre servernoder med inbyggd etcd, på samma plats. etcd behöver en majoritet, och tre servrar klarar därmed att en server faller bort. Två servrar ger ingen vinst, eftersom bortfallet av en av dem kostar majoriteten. För Kubernetes över flera kontinenter räcker tre enkelnodskluster som start, ett per region, eftersom geo-DNS-tjänsten fångar upp bortfallet av en hel region.
Vilka portar behöver k3s?
Kubernetes-API:et och k3s-supervisorn körs på port 6443/TCP, kubelet på 10250/TCP och Flannel-nätet på 8472/UDP med VXLAN eller 51820/UDP med WireGuard. Med flera servrar och inbyggd etcd tillkommer portarna 2379 till 2380/TCP mellan servrarna. Ingen av de här portarna ska vara öppen mot internet; API:et tillåter du bara från din egen adress eller via VPN.
Hur rullas applikationer ut till flera Kubernetes-kluster?
Via GitOps: det önskade tillståndet för alla kluster ligger i ett Git-repository, och i varje kluster körs ett verktyg som Flux, som på egen hand upprättar det tillståndet. Varje region har en egen katalog, så att en ny version kan rullas ut i en region först och i de andra efter en observationsperiod. Någon central driftsättningsserver som skulle kunna gå ner finns då inte.
Hur fungerar failover mellan Kubernetes-regionerna?
Via en DNS-tjänst med geo-routing och hälsokontroller. Den skickar användare till närmaste region och kontrollerar med 30 till 60 sekunders intervall om regionens ingress svarar. Faller en region bort lämnar tjänsten inte längre ut dess adress och leder användarna till närmaste fungerande region. Med en TTL på 60 sekunder är omställningen oftast klar efter en till två minuter.
Hur bevaras data när en region faller bort?
Kubernetes fördelar poddar, inte data. Databaser replikerar sig därför själva, till exempel PostgreSQL med operatorn CloudNativePG, som driver repliker även över klustergränser. Mellan kontinenter sker replikeringen asynkront, och i ett skarpt läge kan de sista sekundernas skrivoperationer saknas. Filer hör hemma i replikerad objektlagring, och regelbundna backuper, till exempel med Velero, är fortfarande ett måste.
Kubernetes eller Docker Swarm för flera kontinenter?
Docker Swarm kan spännas ut som ett enda kluster över tre kontinenter och är betydligt enklare att driva. Kubernetes erbjuder mer automatisering och ett större ekosystem, men över kontinenter drivs det som ett kluster per region som knyts samman via GitOps. För små team med överskådliga applikationer är Swarm ofta det pragmatiska valet, för komplexa plattformar Kubernetes.
Vilka KernelHost-platser passar för Kubernetes över flera kontinenter?
KernelHost erbjuder servrar i Frankfurt am Main och på ytterligare platser i Europa, Nordamerika och Asien-Stillahavsområdet, bland annat tre platser i USA, Kanada, London, Strasbourg, Warszawa, Helsingfors, Singapore, Japan, Sydney och Mumbai. En beprövad kombination är Frankfurt am Main, USA:s östkust och Singapore, med en eller tre servrar på samma plats i varje region.
Vad kostar Kubernetes över tre kontinenter?
Som start tre servrar, en per region, i utbyggnaden nio, plus en DNS-tjänst med hälsokontroller. k3s i sig kostar ingenting. Eftersom replikering, backuper och image-nedladdningar ger konstant trafik är paket med obegränsad trafik avgörande. Hos KernelHost körs VPS:erna med obegränsad trafik utan volymtak, PrePaid utan bindningstid och utan startavgift, så att kluster kan göras större eller mindre efter behov.

Kubernetes k3s k8s kubeadm Hög tillgänglighet Flera regioner GitOps Flux Geo-DNS Moln