Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

Nazywam się Wiktor Jagofarow i zajmuję się rozwijaniem platformy Kubernetes w firmie DomKlik jako lider techniczny zespołu ds. rozwoju w zespole Ops (operacje). Chciałbym opowiedzieć o struktury naszych procesów Dev Ops, o szczególnych cechach eksploatacji jednego z największych klastrów k8s w Rosji oraz o praktykach DevOps/SRE, które stosuje nasz zespół.

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

Zespół Ops

Obecnie w zespole Ops pracuje 15 osób. Trzy z nich odpowiadają za biuro, dwie pracują w innym strefie czasowej i są dostępne, w tym również w nocy. Dzięki temu zawsze ktoś z Ops jest przy monitorze i gotowy do reakcji na incydent o dowolnej złożoności. Nie mamy nocnych dyżurów, co chroni naszą psychikę i pozwala wszystkim się wyspać oraz spędzać czas wolny nie tylko przed komputerem.

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

Wszyscy mamy różne kompetencje: sieciowcy, DBA, specjaliści od stosu ELK, administratorzy/deweloperzy Kubernetes, specjaliści od monitorowania, wirtualizacji, sprzętu itp. Łączy nas jedno — każdy może w jakimś stopniu zastąpić kogoś innego: na przykład, wprowadzić nowe węzły do klastra k8s, zaktualizować PostgreSQL, napisać pipeline CI/CD + Ansible, zautomatyzować coś w Pythonie/Bash/Go, podłączyć sprzęt w centrum danych. Silne kompetencje w danej dziedzinie nie przeszkadzają w zmianie kierunku działalności i rozpoczęciu nauki w innej dziedzinie. Na przykład, zatrudniłem się w firmie jako specjalista ds. PostgreSQL, a teraz moim głównym obszarem odpowiedzialności są klastry Kubernetes. W zespole jakikolwiek rozwój jest mile widziany, a poczucie wspólnoty jest bardzo rozwinięte.

Zresztą rekrutujemy. Wymagania wobec kandydatów są dość standardowe. Osobiście ważne jest dla mnie, aby osoba wpasowała się w zespół, była niekonfliktowa, ale także potrafiła bronić swojego zdania, chciała się rozwijać i nie bała się robić czegoś nowego, proponowała swoje pomysły. Umiejętności programowania w językach skryptowych są również konieczne, tak samo jak znajomość podstaw Linuxa i angielskiego. Angielski jest potrzebny, aby osoba w przypadku problemu mogła znaleźć rozwiązanie w ciągu 10 sekund, a nie 10 minut. Specjaliści z głęboką wiedzą o Linuxie są teraz bardzo rzadkością: to śmieszne, ale dwóch na trzech kandydatów nie potrafi odpowiedzieć na pytanie „Czym jest Load Average? Z czego się składa?”, a pytanie „Jak zebrać zrzut pamięci z programu w C” uważają za coś z świata superbohaterów… albo dinozaurów. Musimy się z tym pogodzić, ponieważ zwykle ludzie mają dobrze rozwinięte inne kompetencje, a „linuksa” ich nauczymy. Odpowiedź na pytanie „po co to wszystko wiedzieć inżynierowi DevOps w dzisiejszym świecie chmur” musimy zostawić poza zakresem artykułu, ale w kilku słowach: wszystko to jest potrzebne.

Zespół Tools

Zespół Tools odgrywa znaczącą rolę w automatyzacji. Ich głównym zadaniem jest tworzenie wygodnych narzędzi graficznych i CLI dla programistów. Na przykład nasze wewnętrzne narzędzie Confer pozwala na dosłownie kilka kliknięć zainstalować aplikację w Kubernetes, skonfigurować zasoby, klucze z vault itd. Wcześniej używano Jenkins + Helm 2, ale musieliśmy opracować własne narzędzie, aby wyeliminować kopiowanie i wprowadzić jednorodność w cyklu życia oprogramowania.

Zespół Ops nie pisze pipeline'ów za programistów, ale może doradzić w każdej kwestii dotyczącej ich pisania (niektórzy nadal korzystają z Helm 3).

DevOps

Jeśli chodzi o DevOps, widzimy go w ten sposób:

Zespoły Dev piszą kod, wdrażają go przez Confer w dev -> qa/stage -> prod. Odpowiedzialność za to, aby kod nie zawieszał się i nie generował błędów, spoczywa na zespołach Dev i Ops. W ciągu dnia na incydent związany ze swoim aplikacją powinien reagować w pierwszej kolejności dyżurny z zespołu Ops, a w czasie wieczornym i nocnym dyżurny admin (Ops) powinien obudzić dyżurnego programistę, jeśli ma pewność, że problem nie leży w infrastrukturze. Wszystkie metryki i alerty w monitoringu pojawiają się automatycznie lub półautomatycznie.

Obszar odpowiedzialności Ops zaczyna się w momencie wdrożenia aplikacji w produkcji, ale odpowiedzialność Dev się na tym nie kończy — pracujemy nad tym razem i jesteśmy w jednej łódce.

Programiści konsultują administratorów, gdy potrzebna jest pomoc przy pisaniu mikroserwisu dla adminów (na przykład backend w Go + HTML5), a administratorzy doradzają programistom w sprawach związanych z infrastrukturą lub pytaniach dotyczących k8s.

Przy okazji, w ogóle nie mamy monolitu, tylko mikroserwisy. Ich liczba oscyluje obecnie między 900 a 1000 w produkcyjnym klastrze k8s, jeśli mierzyć pod względem ilości. deploymentsLiczba podów waha się między 1700 a 2000. Podów w klastrze produkcyjnym jest obecnie około 2000.

Nie mogę podać dokładnych liczb, ponieważ monitorujemy niepotrzebne mikroserwisy i usuwamy je w trybie półautomatycznym. Śledzenie niepotrzebnych bytów w k8s wspomaga nam useless-operator, co znacząco oszczędza zasoby i pieniądze.

Zarządzanie zasobami

Monitoring

Fundamentem w eksploatacji dużego klastra staje się odpowiednio zbudowany i informacyjny system monitorowania. Na razie nie znaleźliśmy uniwersalnego rozwiązania, które pokryłoby 100% wszystkich "życzeń" dotyczących monitorowania, dlatego okresowo tworzymy różne niestandardowe rozwiązania w tej dziedzinie.

  • Zabbix. Stary, dobry system monitorowania, który jest przeznaczony przede wszystkim do śledzenia ogólnego stanu infrastruktury. Informuje nas, kiedy węzeł umiera z powodu CPU, pamięci, dysków, sieci i tym podobnych. Nic nadzwyczajnego, ale mamy również osobny DaemonSet z agentami, za pomocą których na przykład monitorujemy stan DNS w klastrze: sprawdzamy opóźnione pody coredns, kontrolujemy dostępność zewnętrznych hostów. Można by się zastanawiać, po co się w to bawić, ale przy dużych wolumenach ruchu ten komponent jest poważnym punktem awarii. Już wcześniej mówiłem W ten sposób, https jest skonfigurowane, teraz wchodzimy do folderu ./bin i uruchamiamy startup.sh, a po uruchomieniu serwera przechodzimy do instalatora webowego, jak radziłem sobie z wydajnością DNS w klastrze.
  • Operator Prometheus. Zestaw różnych eksporterów daje szeroki przegląd wszystkich komponentów klastra. Następnie wizualizujemy to wszystko na dużych pulpitach nawigacyjnych w Grafanie, a do powiadomień używamy alertmanager.

Kolejnym przydatnym narzędziem dla nas stał się list-ingress. Napisaliśmy go po tym, jak kilkukrotnie spotkaliśmy się z sytuacją, w której jeden zespół blokował ścieżki Ingress innego zespołu, co prowadziło do błędów 50x. Teraz przed wdrożeniem na produkcję deweloperzy sprawdzają, czy nikogo nie urazi, a dla mojego zespołu to dobre narzędzie do wstępnej diagnostyki problemów z Ingressami. Ciekawe, że pierwotnie został stworzony dla administratorów i wyglądał dość „topornie”, ale po tym, jak narzędzie zyskało popularność w zespołach deweloperskich, przeszedł znaczną transformację i przestał wyglądać jak „admin stworzył interfejs dla administratorów”. Wkrótce zrezygnujemy z tego narzędzia, a takie sytuacje będą weryfikowane jeszcze przed wdrożeniem pipeline’a.

Zasoby zespołów w „Kube”

Zanim przejdziemy do przykładów, warto wyjaśnić, jak u nas działa przydzielanie zasobów dla mikroserwisów.

Aby zrozumieć, jakie zespoły i w jakich ilościach wykorzystują swoje zasoby (procesor, pamięć, lokalny SSD), przydzielamy każdemu zespołowi jego własny namespace w „Kube” i ograniczamy maksymalne możliwości pod względem procesora, pamięci i dysku, wcześniej omawiając potrzeby zespołów. W konsekwencji jeden zespół, w ogólnym przypadku, nie zablokuje dla wdrożenia całego klastra, przydzielając sobie tysiące rdzeni i terabajty pamięci. Dostępy do namespace’u są wydawane przez AD (używamy RBAC). Namespace’y i ich limity są dodawane poprzez pull request do repozytorium GIT, a następnie za pomocą pipeline’a Ansible wszystko automatycznie się wdraża.

Przykład przydzielania zasobów dla zespołu:

namespaces:

  chat-team:
    pods: 23
    limits:
      cpu: 11
      memory: 20Gi
    requests:
      cpu: 11
      memory: 20Gi

Requests i limity

W „Kube” Request — to liczba gwarantowanych zarezerwowanych zasobów dla pod (jeden lub więcej kontenerów Docker) w klastrze. Limit — to niegwarantowany maksimum. Często można zobaczyć na wykresach, jak jakiś zespół przydzielił sobie zbyt wiele requests dla wszystkich swoich aplikacji i nie może wdrożyć aplikacji w „Kube”, ponieważ w ich namespace wszystkie requesty zostały już „wydane”.

Poprawnym wyjściem z takiej sytuacji jest obserwowanie rzeczywistego zużycia zasobów i porównanie go z zadanym poziomem (Request).

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów
Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

Na zrzutach ekranu powyżej widać, że „zadane” (Requested) CPU zbliżają się do rzeczywistej liczby wątków, a Limity mogą przekraczać rzeczywistą liczbę wątków procesorów centralnych =)

Teraz szczegółowo przyjrzymy się jakiemuś namespace'owi (wybrałem namespace kube-system — systemowy namespace dla komponentów samego „Kuba”) i zobaczymy stosunek rzeczywiście wykorzystanego czasu CPU i pamięci do żądanej:

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

Oczywiście, że pamięci i CPU zarezerwowane dla usług systemowych jest znacznie więcej, niż jest to rzeczywiście używane. W przypadku kube-system jest to uzasadnione: zdarzało się, że nginx ingress controller czy nodelocaldns w szczycie sięgały na maksymalny limit CPU i konsumowały bardzo dużo RAM-u, dlatego taki zapas jest uzasadniony. Ponadto, nie możemy polegać na wykresach z ostatnich 3 godzin: warto widzieć historyczne metryki przez dłuższy okres czasu.

Opracowano system „zalecenia”. Na przykład, tutaj można zobaczyć, które zasoby najlepiej by było „podnieść limity” (górna dopuszczalna granica), aby uniknąć „tłumienia” (throttling): momentu, kiedy już zużyto CPU lub pamięć w przydzielonym mu czasie i czeka na „odmrożenie”:

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

A oto podów, którym należałoby ograniczyć apetyt:

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

O tłumienie + monitorowanie zasobów można napisać niejedną artykuł, dlatego proszę zadawać pytania w komentarzach. W kilku słowach mogę powiedzieć, że zadanie automatyzacji podobnych metryk jest dość złożone i wymaga dużo czasu oraz gimnastyki z „okiennymi” funkcjami i „CTE” Prometheus / VictoriaMetrics (te terminy są w cudzysłowie, ponieważ w PromQL prawie nie ma nic podobnego, więc trzeba tworzyć skomplikowane zapytania na kilka ekranów tekstu i zajmować się ich optymalizacją).

W rezultacie, programiści mają narzędzia do monitorowania swoich namespace'ów w „Kubie”, i mogą sami decydować, gdzie i o jakiej porze można „przyciąć” zasoby, a jakim podom można oddać cały CPU na całą noc.

Metodologie

W firmie, jak teraz modnie, trzymamy się praktyk DevOps-owych i SRE- praktyk. Kiedy w firmie jest 1000 mikroserwisów, około 350 programistów i 15 administratorów na całą infrastrukturę, trzeba „być modnym”: za wszystkimi tymi „buzzwordami” kryje się ostra potrzeba automatyzacji wszystkiego i wszędzie, a administratorzy nie powinni być wąskim gardłem w procesach.

Jako Ops, dostarczamy różne metryki i pulpitów dla programistów, związanych z czasem odpowiedzi usług i ich błędami.

Używamy takich metodologii jak: RED, UŻYJ i Złote sygnały, łącząc je razem. Staramy się zminimalizować liczbę pulpitów nawigacyjnych, aby z jednego spojrzenia było widać, który serwis właśnie ma problemy (na przykład kody odpowiedzi na sekundę, czas odpowiedzi w 99 percentylu) i tak dalej. Gdy tylko pojawią się nowe metryki potrzebne do wspólnych pulpitów, natychmiast je rysujemy i dodajemy.

Nie rysowałem wykresów od miesiąca. To chyba dobry znak: to oznacza, że większość 'chciejstw' została już zrealizowana. Czasami zdarzało się, że w tygodniu przynajmniej raz dziennie rysowałem jakiś nowy wykres.

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów

Otrzymany wynik jest cenny, ponieważ teraz programiści rzadko przychodzą do administratorów z pytaniami 'gdzie można zobaczyć jakąś metrykę'.

Wdrożenie Service Mesh Nie ma co się obawiać, powinno to znacznie ułatwić życie wszystkim, koledzy z działu narzędzi są już blisko wdrożenia abstrakcyjnego 'Istio zdrowego człowieka': cykl życia każdego zapytania HTTP(s) będzie widoczny w monitorowaniu, i zawsze będzie można zrozumieć 'na którym etapie wszystko się zepsuło' podczas interakcji między serwisami (i nie tylko). Subskrybujcie nowości z hubu firmy DomClick. =)

Wsparcie dla infrastruktury Kubernetes

Historycznie przyjęło się, że używamy spatchowanej wersji Kubespray — rola Ansible do wdrażania, powiększania i aktualizacji Kubernetes. W pewnym momencie z głównej gałęzi wycięto wsparcie dla instalacji non-kubeadm, a proces przejścia na kubeadm nie został zaproponowany. W rezultacie firma Southbridge stworzyła swojego forka (z wsparciem kubeadm i szybkim rozwiązaniem krytycznych problemów).

Proces aktualizacji wszystkich klastrów k8s wygląda tak:

  • Bierzemy Kubespray od Southbridge, porównujemy z naszą gałęzią, łączymy.
  • Wdrażamy aktualizację w Stress- 'Kuba'.
  • Wdrażamy aktualizację po jednej nodzie (w Ansible to 'serial: 1') w Dev- 'Kuba'.
  • Aktualizujemy Prod w sobotę wieczorem po jednej nodzie.

W przyszłości planujemy zastąpić Kubespray czymś szybszym i przejść na kubeadm.

Mamy trzy 'Kuby': Stress, Dev i Prod. Planujemy uruchomić jeszcze jeden (hot standby) Prod-'Kubę' w drugim centrum danych. Stress i Dev żyją w 'wirtualkach' (oVirt dla Stress i VMWare cloud dla Dev). Prod- 'Kuba' działa na 'gołym metalu': to identyczne węzły z 32 wątkami CPU, 64-128 GB pamięci i 300 GB SSD RAID 10 — mamy ich w sumie 50. Trzy 'cienkie' węzły są przeznaczone na 'mastery' 'Kuby': 16 GB pamięci, 12 wątków CPU. ProdDla produkcji wolimy używać 'gołego metalu' i unikamy zbędnych warstw jak

: nie potrzebujemy 'hałaśliwych sąsiadów' i czasu 'kradzieży CPU' OpenStacksteal time kradnij czasA trudność administracji wzrasta w przybliżeniu dwukrotnie w przypadku open-source OpenStack.

Dla CI/CD „Kube” i innych komponentów infrastrukturalnych używamy oddzielnego serwera GIT, Helm 3 (przeszliśmy z Helm 2 dość boleśnie, ale cieszymy się z możliwości atomic), Jenkins, Ansible i Docker. Uwielbiamy feature-branching i wdrożenia do różnych środowisk z jednego repozytorium.

Podsumowanie

Kubernetes w DomClick: jak spokojnie spać, zarządzając klasterem z 1000 mikroserwisów
Tak w skrócie wygląda proces DevOps w firmie DomKlick z perspektywy inżyniera operacyjnego. Artykuł okazał się mniej techniczny niż się spodziewałem, więc bądźcie na bieżąco z nowościami DomKlick na Habrze: będą bardziej „hardcorowe” artykuły o Kubernetes i nie tylko.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster