Kubernetes na wielu kontynentach: wysoka dostępność k3s i k8s w centrach danych na całym świecie
Kubernetes w USA, Europie i Azji, w którym może paść cały kontynent: dlaczego etcd nie znosi dużych odległości, jeden klaster k3s na region, GitOps przez Flux, failover przez Geo-DNS, dane w wielu regionach i różnice wobec kubeadm.
Kubernetes to standard, gdy aplikacje mają być odporne na awarie i skalować się automatycznie. Nasuwający się pomysł, by rozciągnąć jeden klaster Kubernetes na serwery w USA, Europie i Azji, rozbija się jednak o jeden szczegół: o etcd, bazę danych, w której Kubernetes przechowuje cały swój stan. Ten artykuł pokazuje, jak mimo to uruchomić Kubernetes na wielu kontynentach, i to tak, że może paść cały kontynent: z jednym klastrem na region, wspólnym wdrażaniem przez GitOps i usługą Geo-DNS, która kieruje użytkowników do najbliższego sprawnego regionu.
Architekturę budujemy na k3s, lekkiej, w pełni certyfikowanej dystrybucji Kubernetes, którą instaluje się w kilka minut, a na końcu pokazujemy, co się zmienia, gdy klasyczny Kubernetes instalujesz przez kubeadm. Podstawy dostępności, kworum i failoveru w wielu lokalizacjach szczegółowo opisuje artykuł Docker Swarm na trzech kontynentach; tutaj skupiamy się na tym, czym różni się Kubernetes.
Jeden klaster na wszystkie kontynenty czy jeden klaster na region?
Gdy Kubernetes ma działać na wielu kontynentach, właściwą architekturą jest jeden klaster na region, a nie jeden klaster obejmujący wszystkie kontynenty. Każdy klaster działa samodzielnie, wszystkie są wdrażane z tego samego repozytorium Git, a Geo-DNS z health checkami rozdziela użytkowników. Gdy jeden region padnie, jego rolę przejmują pozostałe i nie trzeba przy tym uzgadniać wspólnego stanu klastra przez ocean.
Dlaczego etcd nie znosi dużych odległości
Kubernetes zapisuje każdy stan, każdą konfigurację i każdą zmianę w etcd, magazynie typu klucz-wartość z konsensusem Raft. Każdy zapis wymaga potwierdzenia przez większość wszystkich członków etcd. Domyślnie etcd pracuje z heartbeatem co 100 milisekund i timeoutem wyborów wynoszącym jedną sekundę; między Europą, Ameryką Północną i Azją czasy przesyłu pakietów wynoszą od 80 do 250 milisekund. Te wartości można zwiększyć, ale wtedy każdy zapis w klastrze staje się powolny, od zaplanowania poda po zapisanie sekretu. Dokumentacja k3s jest w tym miejscu jednoznaczna: wbudowany etcd nie jest obsługiwany w klastrach rozproszonych na wiele sieci, a wszystkie serwery powinny stać w tej samej lokalizacji. Również sam Kubernetes jest zaprojektowany tak, by jeden klaster obejmował kilka stref w obrębie jednego regionu, a nie kilka kontynentów.
Porównanie trzech wzorców
| Wzorzec | Jak to działa | Ocena |
| Jeden klaster na wszystkie kontynenty | Warstwa sterowania i etcd rozłożone na kilka kontynentów | Niezalecany: powolne zapisy, niestabilny etcd, w k3s z wbudowanym etcd nieobsługiwany |
| Warstwa sterowania w jednym regionie, węzły robocze na całym świecie | Serwery w jednej lokalizacji, agenty na innych kontynentach | Technicznie działa, ale gdy padnie region z warstwą sterowania, na całym świecie nie da się już niczego ponownie zaplanować |
| Jeden klaster na region | Trzy niezależne klastry, wdrażane wspólnie przez GitOps, z Geo-DNS przed nimi | Zalecany: każdy region przetrwa awarię pozostałych, a błędy pozostają ograniczone do jednego regionu |
Podejście „jeden klaster na region” ma drugą, często niedocenianą zaletę: błąd w warstwie sterowania, wadliwa zmiana w klastrze albo nieudana aktualizacja zawsze dotyka tylko jednego regionu. Użytkownicy pozostałych regionów niczego nie zauważą.
k3s czy k8s?
Oba to prawdziwy Kubernetes z tym samym API, tymi samymi manifestami i tymi samymi narzędziami. Różnica tkwi w budowie i nakładzie pracy:
| Cecha | k3s | k8s z kubeadm |
| Instalacja | Jedno polecenie, jeden plik binarny | Środowisko uruchomieniowe kontenerów, kubeadm, kubelet i wtyczkę sieciową konfigurujesz osobno |
| Zasoby dla węzła serwerowego | Co najmniej 2 rdzenie i 2 GB RAM | Wyraźnie więcej, zależnie od komponentów |
| W zestawie | Kontroler Ingress (Traefik), sieć (Flannel), provisioner pamięci masowej, load balancer usług | Tylko podstawowe komponenty, wszystko inne wybierasz samodzielnie |
| Wysoka dostępność | Wbudowany etcd z trzema serwerami | Trzy węzły control plane z load balancerem przed API |
| Odpowiedni dla | Większości aplikacji, małych zespołów, konfiguracji z jednym węzłem na region | Zespołów, które chcą samodzielnie dobierać każdy komponent |
Do architektury z jednym klastrem na region polecamy k3s: utrzymywanie trzech klastrów jest wygodne tylko wtedy, gdy każdy z nich jest prosty. Kto ma już doświadczenie z kubeadm, przejmie tę architekturę bez zmian, a różnice pokazuje sekcja o kubeadm poniżej.
Architektura: trzy regiony, trzy klastry, jeden punkt wejścia
| Składnik | Zadanie | Przed jaką awarią chroni |
| Jeden klaster k3s na region | Uruchamia aplikację blisko użytkowników | Awaria całego regionu |
| Trzy serwery na region (etap rozbudowy) | Utrzymuje wysoką dostępność etcd i warstwy sterowania w obrębie regionu | Awaria pojedynczych serwerów w regionie |
| Repozytorium Git i Flux w każdym klastrze | Każdy klaster sam pobiera swój stan docelowy z Gita | Brak centralnego serwera wdrożeniowego jako punktu awarii |
| Ingress z certyfikatami przez weryfikację DNS | Przyjmuje żądania użytkowników | Certyfikaty działają niezależnie od przełączeń DNS |
| Geo-DNS z health checkami | Kieruje użytkowników do najbliższego sprawnego regionu | Nieosiągalne regiony |
| Replikowane przechowywanie danych i kopie zapasowe | Przechowuje dane w kilku regionach | Utrata danych przy awarii regionu |
Start i rozbudowa
Punktem wyjścia są trzy serwery, po jednym w USA, w Europie i w Azji, każdy jako osobny klaster jednowęzłowy. Gdy padnie serwer, pada jego region, a Geo-DNS kieruje użytkowników tego regionu do regionu sąsiedniego. Już ten etap jest zaprojektowany z myślą o awarii całego kontynentu. W ramach rozbudowy każdy region dostaje trzy serwery w tej samej lokalizacji; wtedy także każdy region z osobna przetrwa awarię jednego serwera bez konieczności przekierowywania użytkowników.
Które lokalizacje KernelHost się nadają
KernelHost prowadzi serwery w centrum danych maincubes we Frankfurcie nad Menem i oferuje serwery wirtualne w kolejnych lokalizacjach w Europie, Ameryce Północnej oraz w regionie Azji i Pacyfiku. Wśród nich są trzy lokalizacje w USA, a także Kanada, Londyn, Strasburg, Warszawa, Helsinki, Singapur, Japonia, Sydney i Mumbai. Pełna lista znajduje się na stronie Lokalizacje serwerów. Przykład w tym artykule wykorzystuje Frankfurt nad Menem dla Europy, wschodnie wybrzeże USA dla Ameryki Północnej i Singapur dla Azji.
Instrukcja: Kubernetes na k3s w trzech regionach
Przykład wykorzystuje trzy serwery z Debianem 12 lub 13: k3s-eu, k3s-us i k3s-asia. Adresy publiczne pochodzą z sieci przeznaczonej do dokumentacji 203.0.113.0/24, a domena to example.com. Zastąp jedno i drugie własnymi wartościami.
Krok 1: Przygotowanie serwerów w trzech regionach
Zamów trzy serwery w trzech regionach, co najmniej z 2 vCPU i 4 GB RAM, żeby obok k3s zmieściła się też twoja aplikacja. Wprowadź podstawowe zabezpieczenia z listy kontrolnej dla nowych serwerów root i nadaj serwerom czytelne nazwy hostów. etcd wyraźnie zyskuje na szybkich dyskach SSD, a pamięć NVMe serwerów KernelHost spełnia ten warunek.
Krok 2: Instalacja k3s
Na każdym z trzech serwerów instalujesz k3s jednym poleceniem. Dzięki temu każdy serwer staje się kompletnym klastrem Kubernetes z jednym węzłem:
curl -sfL https://get.k3s.io | sh -
kubectl get nodes
Po mniej więcej minucie kubectl get nodes zgłasza węzeł jako Ready. W zestawie są Traefik jako kontroler Ingress, Flannel jako sieć oraz provisioner lokalnych wolumenów.
Krok 3: Rozbudowa do trzech serwerów na region
Jeśli sam region ma zapewniać wysoką dostępność, umieść trzy serwery w tej samej lokalizacji. Pierwszy serwer uruchamia wbudowany etcd, a dwa pozostałe dołączają za pomocą wspólnego tokena. etcd wymaga nieparzystej liczby serwerów; przy trzech serwerach region zniesie awarię jednego z nich:
curl -sfL https://get.k3s.io | K3S_TOKEN=TAJNY_TOKEN sh -s - server \
--cluster-init \
--tls-san=api.eu.example.com
curl -sfL https://get.k3s.io | K3S_TOKEN=TAJNY_TOKEN sh -s - server \
--server https://203.0.113.21:6443 \
--tls-san=api.eu.example.com
Wszystkie serwery jednego regionu potrzebują tych samych ustawień zakresów sieci i funkcji. Między nimi muszą być otwarte porty od 2379 do 2380/TCP dla etcd, 6443/TCP dla API, 10250/TCP dla kubeleta i 8472/UDP dla sieci Flannel, a na zewnątrz pozostają one zablokowane. Token jest tajny: kto go zna, może dołączyć do klastra własne serwery.
Krok 4: Konfiguracja dostępu do wszystkich trzech klastrów
k3s zapisuje dane dostępowe w /etc/rancher/k3s/k3s.yaml. Skopiuj ten plik z każdego klastra na swój komputer roboczy, zastąp w nim 127.0.0.1 adresem serwera i nazwij konteksty według regionów:
kubectl config rename-context default eu
kubectl config use-context eu
kubectl --context us get nodes
API na porcie 6443 to najpotężniejsza droga dostępu do klastra. Zezwól na nią w firewallu tylko z własnego adresu lub przez VPN, nigdy dla całego internetu. Plik k3s.yaml zawiera certyfikat administratora i trzeba go przechowywać równie starannie jak hasło roota.
Krok 5: GitOps przez Flux w każdym klastrze
Aby wszystkie trzy regiony uruchamiały tę samą aplikację w tej samej wersji, stan docelowy leży w repozytorium Git, a w każdym klastrze działa Flux, który samodzielnie doprowadza klaster do tego stanu. Każdy klaster sam pobiera więc swoją konfigurację; nie ma centralnego serwera wdrożeniowego, który mógłby ulec awarii. Sprawdzona struktura repozytorium:
apps/
web/ wspólne manifesty aplikacji
clusters/
eu/ ustawienia i wersja dla Europy
us/ ustawienia i wersja dla Ameryki Północnej
asia/ ustawienia i wersja dla Azji
flux bootstrap git --url=ssh://git@git.example.com/infra/fleet.git --branch=main --path=clusters/eu
To samo polecenie wykonujesz z --path=clusters/us i --path=clusters/asia w odpowiednim kontekście. Ponieważ każdy region ma własny katalog, nową wersję możesz wdrożyć najpierw w jednym regionie, a dopiero potem w pozostałych.
Krok 6: Opis aplikacji odpornej na awarie
W obrębie regionu o to, by aplikacja przetrwała prace serwisowe i awarie serwerów, dbają trzy rzeczy: kilka replik rozłożonych na różne węzły, sondy wykrywające niesprawne pody oraz budżet, który nie pozwala, by prace serwisowe usunęły wszystkie pody jednocześnie:
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
Sonda readiness wyłącza pod z ruchu, dopóki ten nie odpowiada, a sonda liveness uruchamia go ponownie, gdy się zawiesi. W klastrze jednowęzłowym rozkładanie na kilka węzłów jeszcze nie działa; zaczyna działać automatycznie, gdy tylko region ma trzy serwery.
Krok 7: Ingress i certyfikaty
Rolę punktu wejścia pełni dołączony Traefik. Ponieważ wszystkie trzy regiony obsługują tę samą domenę, certyfikaty TLS uzyskujesz przez cert-manager, korzystając z weryfikacji DNS: działa ona w każdym regionie, niezależnie od tego, dokąd akurat wskazuje rekord DNS. Weryfikacja HTTP zawodzi natomiast w każdym regionie, na który rekord akurat nie wskazuje. Jeśli pracujesz bez Ingress w Kubernetes, podstawy znajdziesz w artykule Konfiguracja nginx jako reverse proxy.
Krok 8: Konfiguracja Geo-DNS z failoverem
Usługa DNS z geo-routingiem i health checkami kieruje użytkowników z Europy do Frankfurtu nad Menem, z Ameryki na wschodnie wybrzeże USA i z Azji do Singapuru. W odstępach od 30 do 60 sekund sprawdza przy tym, czy punkt wejścia każdego regionu odpowiada. Gdy region padnie, usługa przestaje zwracać jego adres. Ustaw TTL rekordów na 60 sekund, a przełączenie zakończy się zwykle po upływie jednej do dwóch minut. Jeśli chcesz zarządzać rekordami z poziomu klastra, możesz wykorzystać do tego external-dns.
Krok 9: Wdrażanie region po regionie i test awarii
Nową wersję wpisujesz najpierw w katalogu jednego regionu, przez kilka minut obserwujesz ten region, a potem przenosisz wersję do pozostałych. Dzięki temu błąd, którego nie wykryje żadna kontrola, dotrze najwyżej do jednego regionu. Awarię regionu przećwiczysz, zatrzymując k3s na jego serwerze; sprawdzasz przy tym, czy Geo-DNS usuwa region z odpowiedzi i czy sąsiedni region przejmuje obciążenie:
systemctl stop k3s
systemctl start k3s
W regionie z trzema serwerami przećwicz dodatkowo prace serwisowe na pojedynczym serwerze. kubectl drain przenosi pody z uwzględnieniem budżetu z kroku 6, a kubectl uncordon przywraca serwer do pracy:
kubectl drain k3s-eu-2 --ignore-daemonsets --delete-emptydir-data
kubectl uncordon k3s-eu-2
Dane w wielu regionach
Kubernetes rozkłada pody, nie dane. PersistentVolume z dołączonego provisionera leży na dokładnie jednym węźle, a między klastrami domyślnie nie ma w ogóle wspólnego przechowywania danych. Dlatego dla wszystkiego, co przechowuje dane, obowiązuje to samo, co w każdym klastrze obejmującym wiele lokalizacji:
- Bazy danych replikują się same. Sprawdza się instancja główna w jednym regionie z replikami w pozostałych; operatory baz danych, takie jak CloudNativePG dla PostgreSQL, obsługują takie repliki również ponad granicami klastrów. Między kontynentami replikacja działa asynchronicznie, więc w razie awarii może zabraknąć zapisów z ostatnich sekund. Do bezstratnego zapisu na całym świecie istnieją bazy danych przeznaczone dla wielu regionów, takie jak CockroachDB lub YugabyteDB.
- Pliki i uploady powinny trafiać do magazynu obiektowego zgodnego z S3 z replikacją do drugiego regionu.
- Sesje przechowuje się w replikowanej bazie danych lub replikowanej pamięci podręcznej albo aplikacja korzysta z podpisanych tokenów.
- Kopie zapasowe pozostają obowiązkowe, bo replikacja rozprowadza błędy tak samo jak poprawne dane. Do obiektów Kubernetes i wolumenów nadaje się Velero, a podstawy znajdziesz w artykule o strategii backupu serwera.
Kubernetes z kubeadm zamiast k3s
Z kubeadm architektura pozostaje taka sama: jeden klaster na region, GitOps, Geo-DNS. Inaczej wygląda budowa każdego klastra. Na wszystkich węzłach instalujesz środowisko uruchomieniowe kontenerów, takie jak containerd, oraz kubeadm, kubelet i kubectl, przed API regionu stawiasz load balancer albo adres wirtualny, na przykład przez kube-vip, i inicjalizujesz pierwszy węzeł control plane:
kubeadm init --control-plane-endpoint "api.eu.example.com:6443" --upload-certs
Wynik zawiera dwa polecenia dołączenia: jedno z --control-plane --certificate-key dla dwóch kolejnych węzłów control plane i jedno dla węzłów roboczych. Następnie instalujesz wtyczkę sieciową, taką jak Calico lub Cilium, oraz kontroler Ingress, który k3s ma już w zestawie. Dodatkowy nakład pracy opłaca się, jeśli musisz świadomie dobierać poszczególne komponenty albo trzymać się blisko wersji upstream.
Dlaczego KernelHost dla Kubernetes na wielu kontynentach
| Wymaganie | Dlaczego to ważne | W KernelHost |
| Lokalizacje na wielu kontynentach | Jeden klaster na region wymaga serwerów w każdym regionie | Frankfurt nad Menem i lokalizacje w Europie, Ameryce Północnej oraz regionie Azji i Pacyfiku u jednego dostawcy |
| Nielimitowany transfer | Pobieranie obrazów, replikacja baz danych i kopie zapasowe stale generują ruch | VPS z nielimitowanym transferem bez limitu ilości danych |
| Szybka pamięć masowa | etcd jest wrażliwy na wolne nośniki danych | Dyski NVMe SSD w macierzy RAID |
| Ochrona DDoS | Każdy Ingress jest publicznie dostępny | W cenie w każdej lokalizacji, w głównej lokalizacji we Frankfurcie nad Menem z filtrowaniem Arbor 3,2 Tbps w czasie rzeczywistym, bez null-routingu |
| Pełny dostęp root | k3s, firewall i ustawienia jądra wymagają pełnej kontroli | Na każdym serwerze root KVM i serwerze dedykowanym |
| Bez zobowiązania umownego | Węzły i klastry testowe pojawiają się i znikają | PrePaid, bez minimalnego okresu umowy, bez opłaty aktywacyjnej |
| Automatyzacja | Nowe węzły mają powstawać ze skryptu | Zamawianie i zarządzanie przez KernelHost API |
Przegląd wszystkich pakietów chmurowych i porównanie kosztów z dużymi dostawcami chmury znajdziesz na stronie Serwer w chmurze.
Częste błędy i jak ich unikać
- etcd rozciągnięty na kilka kontynentów. Skutkiem są powolne zapisy i niestabilne wybory, a w k3s z wbudowanym etcd taka konfiguracja nie jest obsługiwana. Rozwiązanie: jeden klaster na region.
- Dwa serwery w jednym regionie. etcd potrzebuje większości, a dwa serwery nie zniosą żadnej awarii. Rozwiązanie: jeden albo trzy.
- API otwarte dla całego internetu. Port 6443 to klucz uniwersalny do klastra. Rozwiązanie: dostęp tylko z własnego adresu lub przez VPN.
- Centralny serwer wdrożeniowy. Gdy padnie, nie da się już niczego wdrożyć. Rozwiązanie: Flux w każdym klastrze, który sam pobiera konfigurację z Gita.
- Aktualizacja we wszystkich regionach jednocześnie. Błąd dotyka wtedy wszystkich użytkowników. Rozwiązanie: region po regionie, przez katalogi w repozytorium.
- Certyfikaty przez weryfikację HTTP. W regionach, na które rekord DNS akurat nie wskazuje, odnowienie kończy się niepowodzeniem. Rozwiązanie: weryfikacja DNS.
- Baza danych na lokalnym wolumenie bez replikacji. Gdy padnie węzeł, dane są nieosiągalne. Rozwiązanie: replikacja za pomocą operatora bazy danych.
- Brak sond i budżetu. Niesprawne pody nadal dostają ruch, a prace serwisowe odłączają od sieci wszystkie pody jednocześnie. Rozwiązanie: sondy readiness i liveness oraz PodDisruptionBudget.
Krótkie podsumowanie
- Gdy Kubernetes ma działać na wielu kontynentach, właściwy jest jeden klaster na region; pojedynczy klaster obejmujący wszystkie kontynenty rozbija się o opóźnienia etcd.
- Punktem wyjścia są trzy serwery, po jednym w USA, w Europie i w Azji; już ten etap przetrwa awarię całego kontynentu.
- W ramach rozbudowy każdy region dostaje trzy serwery w tej samej lokalizacji, dzięki czemu każdy region przetrwa także awarie pojedynczych serwerów.
- Flux w każdym klastrze wdraża aplikację z tego samego repozytorium Git, region po regionie.
- Geo-DNS z health checkami i krótkim TTL kieruje użytkowników do najbliższego sprawnego regionu, a certyfikaty uzyskuje się przez weryfikację DNS.
- Kubernetes rozkłada pody, nie dane: bazy danych potrzebują własnej replikacji, a kopie zapasowe pozostają obowiązkowe.
- Dla tej architektury k3s jest zwykle lepszym wyborem niż kubeadm, bo trzy proste klastry łatwiej utrzymać niż trzy złożone.
Najczęstsze pytania
Czy klaster Kubernetes może działać na wielu kontynentach?
Jak zbudować Kubernetes o wysokiej dostępności w wielu regionach?
Czym różni się k3s od k8s?
Ile serwerów potrzebuje klaster k3s o wysokiej dostępności?
Jakich portów potrzebuje k3s?
Jak wdrażać aplikacje w wielu klastrach Kubernetes?
Jak działa failover między regionami Kubernetes?
Jak zachować dane przy awarii regionu?
Kubernetes czy Docker Swarm na wiele kontynentów?
Które lokalizacje KernelHost nadają się do Kubernetes na wielu kontynentach?
Ile kosztuje Kubernetes na trzech kontynentach?
2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

