
Proces aktualizacji dla twojego klastra Kubernetes
W pewnym momencie korzystania z klastra Kubernetes pojawia się potrzeba aktualizacji działających węzłów. Może to obejmować aktualizacje pakietów, aktualizację jądra lub wdrażanie nowych obrazów maszyn wirtualnych. W terminologii Kubernetes nazywa się to .
Ten post jest częścią cyklu składającego się z 4 postów:
- Ten post.
- Prawidłowe zakończenie pracy podów w klastrze Kubernetes
- Opóźnione zakończenie poda przy jego usunięciu
- Jak uniknąć przestojów w działaniu klastra Kubernetes za pomocą PodDisruptionBudgets
(przyp. red. tłumaczenia pozostałych artykułów cyklu spodziewaj się wkrótce)
W tym artykule opiszemy wszystkie narzędzia, które Kubernetes oferuje, aby uzyskać zerowy czas przestoju dla działających węzłów w twoim klastrze.
Określenie problemu
Na początku zastosujemy naiwną metodę, aby zidentyfikować problemy i ocenić potencjalne ryzyka tego podejścia, a także zbierać wiedzę w celu rozwiązania każdego z problemów, które napotkamy w trakcie całego cyklu. W rezultacie uzyskamy konfigurację, w której wykorzystywane będą lifecycle hooks, readiness probes i budżety zakłóceń podów w celu osiągnięcia naszego zerowego czasu przestoju.
Aby rozpocząć naszą podróż, weźmy konkretny przykład. Załóżmy, że mamy klaster Kubernetes składający się z dwóch węzłów, na którym działa aplikacja z dwoma podami, które znajdują się za Service:

Zaczniemy od dwóch podów z Nginx i usługi uruchomionych na naszych dwóch węzłach klastra Kubernetes.
Chcemy zaktualizować wersję jądra dwóch roboczych węzłów w naszym klastrze. Jak to zrobimy? Prostym rozwiązaniem byłoby uruchomienie nowych węzłów z zaktualizowaną konfiguracją, a następnie wyłączenie starych węzłów, jednocześnie uruchamiając nowe. Chociaż to zadziała, pojawi się kilka problemów z takim podejściem:
- Gdy wyłączysz stare węzły, uruchomione na nich pody również zostaną wyłączone. Co jeśli pody muszą być oczyszczone przed prawidłowym odłączeniem? System wirtualizacji, którego używasz, może nie zaczekać na zakończenie procesu czyszczenia.
- Co jeśli wyłączysz wszystkie węzły jednocześnie? Doświadczysz znacznych przestojów, dopóki pody nie przeniosą się na nowe węzły.
Potrzebujemy sposobu na poprawną migrację podów ze starych węzłów i musimy mieć pewność, że żaden z naszych procesów roboczych nie jest uruchomiony, gdy wprowadzamy zmiany dla węzła. Lub gdy dokonujemy całkowitej wymiany klastra, jak w przykładzie (to znaczy, wymieniamy obrazy VM), chcemy przenieść działające aplikacje ze starych węzłów na nowe. W obu przypadkach chcemy zapobiec planowaniu nowych podów na starych węzłach, a następnie usunąć wszystkie uruchomione pody. Aby osiągnąć te cele, możemy użyć polecenia kubectl drain.
Przenoszenie wszystkich podów z węzła
Operacja drain pozwala przenieść wszystkie pody z węzła. W trakcie wykonywania drain węzeł jest oznaczany jako unschedulable (flaga NoSchedule). To zapobiega pojawianiu się na nim nowych podów. Następnie drain zaczyna usuwać pody z węzła, kończy pracę kontenerów, które obecnie są uruchomione na węźle, wysyłając sygnał TERM do kontenerów w podzie.
Choć kubectl drain Pomimo że operacja ta radzi sobie dobrze z usuwaniem podów, są jeszcze dwa czynniki, które mogą być przyczyną niepowodzenia operacji drain:
- Twoja aplikacja musi potrafić poprawnie kończyć działanie po otrzymaniu
TERMsygnału. Kiedy pody są usuwane, Kubernetes wysyła sygnałTERMdo kontenerów i czeka, aż zatrzymają się przez określony czas, po czym, jeśli nie zatrzymają się, wymusza ich zakończenie. W każdym przypadku, jeśli Twój kontener nie zareaguje poprawnie na sygnał, nadal możesz niepoprawnie wyłączyć pody, jeśli w danym momencie działają (na przykład, jeśli trwa transakcja w bazie danych). - Tracisz wszystkie pody, w których znajduje się Twoja aplikacja. Może być niedostępna w momencie uruchamiania nowych kontenerów na nowych węzłach lub, jeśli Twoje pody są wdrażane bez kontrolerów, mogą w ogóle się nie uruchomić.
Unikamy przestojów
Aby zminimalizować czas przestoju podczas dobrowolnych zakłóceń, takich jak operacja drain dla węzła, Kubernetes oferuje następujące opcje zarządzania błędami:
W innych częściach cyklu będziemy używać tych funkcji Kubernetes, aby złagodzić skutki przenoszenia podów. Aby ułatwić śledzenie głównej myśli, będziemy korzystać z naszego powyższego przykładu z następującą konfiguracją zasobów:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
targetPort: 80
port: 80Ta konfiguracja jest minimalnym przykładem Deployment, który zarządza podami nginx w klastrze. Ponadto konfiguracja opisuje zasób Service, który można wykorzystać do uzyskania dostępu do podów nginx w klastrze.
W trakcie całego cyklu będziemy iteracyjnie rozwijać tę konfigurację, aby ostatecznie zawierała wszystkie możliwości oferowane przez Kubernetes w celu minimalizacji przestojów.
Aby uzyskać w pełni wdrożoną i przetestowaną wersję aktualizacji klastra Kubernetes o zerowym czasie przestoju na AWS i innych zasobach, odwiedź .
Przeczytaj również inne artykuły na naszym blogu:
Źródło: habr.com
