Witamy w serii krótkich przewodników po Kubernetes. To regularna rubryka z najciekawszymi pytaniami, które otrzymujemy online i podczas naszych szkoleń. Odpowiada ekspert od Kubernetes.
Dzisiejszy ekspert — Daniel Polencic (). Daniel pracuje jako instruktor i programista w .
Jeśli chcesz otrzymać odpowiedź na swoje pytanie w następnej publikacji, lub na .
Przegapiłeś poprzednie posty? .
Jak połączyć klastry Kubernetes w różnych data center?
Krótko: , a także polecam przeczytać o i .
Bardzo często infrastruktura jest replikowana i rozdzielana na różne regiony, szczególnie w kontrolowanych środowiskach.
Jeśli jeden region jest niedostępny, ruch jest przekierowywany do innego, aby uniknąć przestojów.
Z Kubernetes można używać podobnej strategii i rozdzielać obciążenia robocze na różne regiony.
Możesz mieć jeden lub kilka klastrów na zespół, region, środowisko lub kombinację tych elementów.
Twoje klastry mogą być hostowane w różnych chmurach i w lokalnym środowisku.
Ale jak zaplanować infrastrukturę dla takiego geograficznego rozrzutu?
Czy należy stworzyć jeden duży klaster w kilku chmurach w jednej sieci?
Czy może lepiej utworzyć wiele małych klastrów i znalezienie sposobu na ich kontrolowanie i synchronizowanie?
Jeden klaster nadrzędny
Utworzenie jednego klastra w jednej sieci nie jest takie proste.
Wyobraź sobie, że masz awarię i utraconą łączność między segmentami klastra.
Jeśli masz jednego mastera, połowa zasobów nie może otrzymać nowych poleceń, ponieważ nie uda im się połączyć z masterem.
A przy tym masz stare tabele routingu (kube-proxy nie może załadować nowych) i żadnych dodatkowych podów (kubelet nie może żądać aktualizacji).
Co gorsza, jeśli Kubernetes nie widzi węzła, oznacza go jako utracony i rozdziela brakujące pody pomiędzy istniejącymi węzłami.
W rezultacie masz dwa razy więcej podów.
Jeśli utworzysz po jednym masterze w każdym regionie, będą problemy z algorytmem osiągania konsensusu w bazie danych etcd.przyp. red. — W rzeczywistości baza danych etcd nie musi znajdować się na serwerach master. Można ją uruchomić na osobnej grupie serwerów w jednym regionie. Wprawdzie w takim przypadku powstaje punkt awarii klastra. Ale działa szybko.)
etcd używa , aby uzgodnić wartość, zanim zapisze ją na dysku.
To znaczy, że większość instancji musi osiągnąć konsensus, zanim stan będzie można zapisać w etcd.
Jeśli opóźnienie między instancjami etcd nagle wzrasta, jak w przypadku trzech instancji etcd w różnych regionach, zajmuje to dużo czasu, aby uzgodnić wartość i zapisać ją na dysku.
To ma również wpływ na kontrolery Kubernetes.
Menadżer kontrolerów potrzebuje więcej czasu, aby dowiedzieć się o zmianie i zapisać odpowiedź w bazie danych.
A ponieważ kontrolerów jest więcej niż jeden, powstaje reakcja łańcuchowa, a cały klaster zaczyna działać bardzo wolno..
etcd jest tak wrażliwy na opóźnienia, że .
Obecnie nie ma dobrych przykładów dużej sieci dla jednego klastra.
Głównie społeczność deweloperów i grupa SIG-cluster starają się zrozumieć, jak orkiestracja klastrów działa podobnie jak orkiestracja kontenerów w Kubernetes.
Opcja 1: federacja klastrów z kubefed
Oficjalna odpowiedź od SIG-cluster to .
Po raz pierwszy próbowano zarządzać kolekcją klastrów jako jednym obiektem przy użyciu narzędzia kube federation.
Początek był obiecujący, ale ostatecznie kube federation nie zdobył popularności, ponieważ nie obsługiwał wszystkich zasobów.
Obsługiwał zbiory zewnętrzne i usługi, ale na przykład nie StatefulSets.
Ponadto konfiguracja federacji była przekazywana w postaci adnotacji i nie różniła się elastycznością.
Wyobraź sobie, jak można opisać podział replik dla każdego klastra w federacji za pomocą tylko jednych adnotacji.
Powstał kompletny bałagan.
SIG-cluster wykonał dużą pracę po wersji kubefed v1 i postanowił podejść do problemu z innej strony.
Zamiast adnotacji zdecydowali się na wydanie kontrolera, który zostaje zainstalowany na klastrach. Można go konfigurować za pomocą niestandardowych definicji zasobów (Custom Resource Definition, CRD).
Dla każdego zasobu, który wejdzie do federacji, masz do dyspozycji niestandardową definicję CRD składającą się z trzech sekcji:
- standardowa definicja zasobu, na przykład deployment;
- sekcja
placement, w której określasz, jak zasób będzie rozdzielany w federacji; - sekcja
override, w której dla konkretnego zasobu można nadpisać wagę i parametry z placement.
Oto przykład skonsolidowanego dostarczenia z sekcjami placement i override.
apiVersion: types.federation.k8s.io/v1alpha1
kind: FederatedDeployment
metadata:
name: test-deployment
namespace: test-namespace
spec:
template:
metadata:
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
placement:
clusterNames:
- cluster2
- cluster1
overrides:
- clusterName: cluster2
clusterOverrides:
- path: spec.replicas
value: 5Jak widać, dostarczenie jest rozdzielone na dwa klastry: cluster1 i cluster2.
Pierwszy klaster dostarcza trzy repliki, a w drugim określono wartość 5.
Jeśli potrzebujesz większej kontroli nad liczbą replik, kubefed2 zapewnia nowy obiekt ReplicaSchedulingPreference, w którym repliki można rozdzielać w oparciu o wagę:
apiVersion: scheduling.federation.k8s.io/v1alpha1
kind: ReplicaSchedulingPreference
metadata:
name: test-deployment
namespace: test-ns
spec:
targetKind: FederatedDeployment
totalReplicas: 9
clusters:
A:
weight: 1
B:
weight: 2Struktura CRD i API jeszcze nie są całkowicie gotowe, a w oficjalnym repozytorium projektu trwają intensywne prace.
Śledź kubefed2, ale pamiętaj, że na razie nie nadaje się do środowiska produkcyjnego.
Dowiedz się więcej o kubefed2 z na blogu o Kubernetes oraz w .
Opcja 2: konsolidacja klastrów w stylu Booking.com
Deweloperzy Booking.com nie zajmowali się kubefed v2, ale wymyślili Shipper — operatora do dostarczania w wielu klastrach, w różnych regionach i w różnych chmurach.
jest w pewnym sensie podobny do kubefed2.
Oba narzędzia pozwalają skonfigurować strategię wdrażania w wielu klastrach (jakie klastry są używane i ile mają replik).
Ale zadaniem Shipper jest zredukowanie ryzyka błędów podczas dostarczania.
W Shipper można określić szereg kroków, które opisują podział replik między poprzednim a bieżącym wdrożeniem oraz objętość nadchodzącego ruchu.
Gdy wysyłasz zasób do klastra, kontroler Shipper stopniowo wdraża tę zmianę we wszystkich połączonych klastrach.
A Shipper jest bardzo ograniczony.
Na przykład, przyjmuje pakiety Helm jako dane wejściowe. i nie wspiera zasobów vanilla.
Ogólnie rzecz biorąc, Shipper działa w następujący sposób.
Zamiast standardowej dostawy, należy stworzyć zasób aplikacji, który zawiera Helm chart:
apiVersion: shipper.booking.com/v1alpha1
kind: Application
metadata:
name: super-server
spec:
revisionHistoryLimit: 3
template:
chart:
name: nginx
repoUrl: https://storage.googleapis.com/shipper-demo
version: 0.0.1
clusterRequirements:
regions:
- name: local
strategy:
steps:
- capacity:
contender: 1
incumbent: 100
name: staging
traffic:
contender: 0
incumbent: 100
- capacity:
contender: 100
incumbent: 0
name: full on
traffic:
contender: 100
incumbent: 0
values:
replicaCount: 3Shipper to niezła opcja do zarządzania wieloma klastrami, ale jego bliskie powiązanie z Helm tylko przeszkadza.
A co jeśli wszyscy przejdziemy z Helma na lub ?
Dowiedz się więcej o Shipper i jego filozofii w .
Jeśli chcesz pogrzebać w kodzie, .
Opcja 3: „magiczne” połączenie klastrów
Kubefed v2 i Shipper współpracują z federacją klastrów, oferując klastrom nowe zasoby za pomocą niestandardowego określenia zasobów.
Ale co jeśli nie chcesz przepisywać wszystkich dostaw, StatefulSets, DaemonSets itd. w celu połączenia?
Jak włączyć istniejący klaster do federacji, nie zmieniając YAML?
, który zajmuje się obciążeniami harmonogramu w klastrach.
Ale zamiast wymyślać nowy sposób interakcji z klastrem i opakowywać zasoby w niestandardowe definicje, multi-cluster-scheduler wprowadza się do standardowego cyklu życia Kubernetes i przechwytuje wszystkie wywołania, które tworzą pody.
Każdy tworzony pod jest natychmiast zastępowany pustakiem.
multi-cluster-scheduler wykorzystuje , aby przechwycić wywołanie i stworzyć bezczynny pod-pustak.
Początkowy pod przechodzi przez jeszcze jeden cykl harmonogramowania, gdzie po przeszukaniu całej federacji podejmuje się decyzję o lokalizacji.
W końcu pod trafia do docelowego klastra.
W rezultacie masz dodatkowy pod, który nic nie robi, tylko zajmuje miejsce.
Zaletą jest to, że nie musiałeś pisać nowych zasobów do łączenia dostaw.
Każdy zasób twórczy dla poda jest automatycznie gotowy do połączenia.
To interesujące, ponieważ nagle pojawiają się dostawy rozdzielone pomiędzy kilka regionów, a ty nawet tego nie zauważasz. Jednak to dość ryzykowne, bo wszystko opiera się na magii.
Ale jeśli Shipper stara się głównie złagodzić skutki dostaw, multi-cluster-scheduler pełni bardziej ogólne zadania i być może lepiej nadaje się do zadań pakietowych.
Nie ma zaawansowanego mechanizmu stopniowych dostaw.
Więcej o multi-cluster-scheduler można dowiedzieć się na .
Jeśli chcesz przeczytać o multi-cluster-scheduler w akcji, Admiralty ma — procesami roboczymi, zdarzeniami, CI i CD Kubernetes.
Inne narzędzia i rozwiązania
Łączenie i zarządzanie wieloma klastrami to trudne zadanie, nie ma uniwersalnego rozwiązania.
Jeśli chcesz dokładniej zbadać ten temat, oto kilka zasobów:
- — narzędzie łączące sieci overlay różnych klastrów Kubernetes.
- Sieć detaliczna Target używa .
- Spróbuj użyć IPV6 oraz .
- Można użyć service mesh, na przykład .
- Cilium, wtyczka interfejsu sieci kontenerów, oferuje , która umożliwia łączenie kilku klastrów.
To wszystko na dzisiaj.
Dziękujemy, że dotarłeś do końca!
Jeśli wiesz, jak skuteczniej połączyć kilka klastrów, .
Dodamy twój sposób do linków.
Szczególne podziękowania dla Chrisa Nesbitta-Smitha () i Vincenta de Smeta () (inżyniera ds. niezawodności w ) za przeczytanie artykułu i podzielenie się przydatnymi informacjami na temat działania federacji.
Źródło: habr.com
