Aktualizacja klastra Kubernetes bez przestojów

Aktualizacja klastra Kubernetes bez przestojów

Proces aktualizacji klastra Kubernetes

W pewnym momencie podczas korzystania z klastra Kubernetes istnieje potrzeba aktualizacji działających węzłów. Może to obejmować aktualizacje pakietów, aktualizacje jądra lub wdrożenie nowych obrazów maszyn wirtualnych. W terminologii Kubernetes nazywa się to „Dobrowolne zakłócanie”.

Ten post jest częścią serii składającej się z 4 postów:

  1. Ten post.
  2. Prawidłowe zamknięcie podów w klastrze Kubernetes
  3. Opóźnione zakończenie poda po jego usunięciu
  4. Jak uniknąć przestojów klastra Kubernetes za pomocą PodDisruptionBudgets

(w przybliżeniu spodziewaj się tłumaczeń pozostałych artykułów z serii w najbliższej przyszłości)

W tym artykule opiszemy wszystkie narzędzia, które udostępnia Kubernetes, aby osiągnąć zerowy przestój węzłów działających w Twoim klastrze.

Definicja problemu

Na początku przyjmiemy podejście naiwne, zidentyfikujemy problemy i ocenimy potencjalne ryzyko związane z tym podejściem oraz zbudujemy wiedzę, aby rozwiązać każdy z problemów, jakie napotykamy w trakcie cyklu. Rezultatem jest konfiguracja korzystająca z haków cyklu życia, sond gotowości i budżetów na zakłócenia podów, aby osiągnąć nasz cel zerowych przestojów.

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, w którym działa aplikacja, a za nią znajdują się dwa pody Service:

Aktualizacja klastra Kubernetes bez przestojów

Zacznijmy od dwóch podów z Nginx i usługą działającą w naszych dwóch węzłach klastra Kubernetes.

Chcemy zaktualizować wersję jądra dwóch węzłów roboczych w naszym klastrze. Jak to zrobić? Prostym rozwiązaniem byłoby uruchomienie nowych węzłów ze zaktualizowaną konfiguracją, a następnie zamknięcie starych węzłów podczas uruchamiania nowych. Chociaż to zadziała, będzie kilka problemów z tym podejściem:

  • Gdy wyłączysz stare węzły, działające na nich pody również zostaną wyłączone. Co się stanie, jeśli zasobniki będą musiały zostać wyczyszczone w celu płynnego zamknięcia systemu? System wirtualizacji, którego używasz, może nie czekać na zakończenie procesu czyszczenia.
  • Co się stanie, jeśli wyłączysz wszystkie węzły jednocześnie? Będziesz mieć przyzwoite przestoje, podczas gdy kapsuły będą przenosić się do nowych węzłów.

Potrzebujemy sposobu na płynną migrację podów ze starych węzłów, zapewniając jednocześnie, że żaden z naszych procesów roboczych nie będzie uruchomiony podczas wprowadzania zmian w węźle. Albo kiedy dokonujemy całkowitej wymiany klastra jak w przykładzie (czyli podmieniamy obrazy VM) chcemy przenieść działające aplikacje ze starych węzłów na nowe. W obu przypadkach chcemy uniemożliwić nowym podom planowanie w starych węzłach, a następnie wykluczyć z nich wszystkie działające pody. Aby osiągnąć te cele, możemy użyć polecenia kubectl drain.

Redystrybucja wszystkich podów z węzła

Operacja opróżniania umożliwia redystrybucję wszystkich zasobników z węzła. Podczas wykonywania drenażu węzeł jest oznaczony jako niezaplanowany (flaga NoSchedule). Zapobiegnie to pojawianiu się na nim nowych strąków. Następnie drenaż zaczyna eksmitować pody z węzła, zamyka kontenery aktualnie uruchomione w węźle, wysyłając sygnał TERM pojemniki w strąku.

Chociaż kubectl drain świetnie poradzi sobie z eksmisją kapsuł, istnieją dwa inne czynniki, które mogą spowodować niepowodzenie operacji opróżniania:

  • Twoja aplikacja musi mieć możliwość bezpiecznego zakończenia po przesłaniu TERM sygnał. Kiedy pody zostaną eksmitowane, Kubernetes wysyła sygnał TERM kontenerów i czeka, aż się zatrzymają przez określony czas, po czym, jeśli się nie zatrzymają, następuje ich przymusowe zakończenie. W każdym razie, jeśli Twój kontener nie odbierze sygnału poprawnie, nadal możesz błędnie wygasić pody, jeśli aktualnie działają (na przykład trwa transakcja w bazie danych).
  • Stracisz wszystkie zasobniki zawierające Twoją aplikację. Może nie być dostępna, gdy w nowych węzłach zostaną uruchomione nowe kontenery lub jeśli Twoje pody zostaną wdrożone bez kontrolerów, mogą w ogóle nie zostać ponownie uruchomione.

Unikanie przestojów

Aby zminimalizować przestoje spowodowane dobrowolnymi zakłóceniami, takimi jak operacja opróżniania węzła, Kubernetes udostępnia następujące opcje obsługi awarii:

W pozostałej części serii będziemy używać tych funkcji Kubernetes, aby złagodzić wpływ migracji podów. Aby ułatwić podążanie za główną ideą, wykorzystamy powyższy przykład 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: 80

Ta konfiguracja jest minimalnym przykładem Deployment, który zarządza podami nginx w klastrze. Ponadto konfiguracja opisuje zasób Service, którego można użyć do uzyskania dostępu do zasobników Nginx w klastrze.

W trakcie cyklu będziemy iteracyjnie rozszerzać tę konfigurację, tak aby ostatecznie obejmowała wszystkie możliwości, jakie zapewnia Kubernetes w celu skrócenia przestojów.

Aby zapoznać się z w pełni wdrożoną i przetestowaną wersją aktualizacji klastra Kubernetes zapewniających zerowe przestoje w AWS i poza nią, odwiedź stronę Gruntwork.io.

Przeczytaj także inne artykuły na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz