Przyp. tłum.: na początku sierpnia Red Hat publicznie ogłosił rozwiązanie problemów z dostępnością, które występowały w poprzednich miesiącach u użytkowników jego usługi (jego podstawą jest rejestr dla obrazów kontenerów, który firma przejęła wraz z zakupem CoreOS). Bez względu na Twoje zainteresowanie tą usługą, sam proces, przez który przeszli inżynierowie SRE firmy w celu diagnozowania i usuwania przyczyn awarii, jest pouczający.

19 maja, wczesnym rankiem (według letniego czasu wschodnioamerykańskiego, EDT), usługa quay.io uległa awarii. Incydent dotknął zarówno użytkowników quay.io, jak i projekty Open Source, które korzystają z quay.io jako platformy do budowy i dystrybucji oprogramowania. Red Hat ceni zaufanie zarówno jednych, jak i drugich.
Zespół inżynierów SRE natychmiast przystąpił do pracy, starając się jak najszybciej ustabilizować działanie usługi Quay. Jednak w trakcie tych działań klienci stracili możliwość przesyłania nowych obrazów, a jedynie od czasu do czasu mogli pobierać istniejące. Z nieznanych powodów baza danych quay.io blokowała się po skalowaniu usługi do pełnej mocy.
«Co się zmieniło?» — to pierwsze pytanie, które w takich przypadkach zazwyczaj się stawia. Zauważyliśmy, że krótko przed problemem klaster OpenShift Dedicated (na którym działa quay.io) zaczął aktualizację do wersji 4.3.19. Ponieważ quay.io działa na Red Hat OpenShift Dedicated (OSD), regularne aktualizacje były codziennością i nigdy nie prowadziły do problemów. Co więcej, w ciągu ostatnich sześciu miesięcy kilka razy aktualizowaliśmy klastry Quay bez żadnych przerw w działaniu.
Podczas gdy próbowaliśmy przywrócić działanie usługi, inni inżynierowie zaczęli przygotowywać nowy klaster OSD z wcześniejszą wersją oprogramowania, aby w razie potrzeby uruchomić wszystko na nim.
Analiza przyczyn
Głównym objawem awarii była lawina dziesiątek tysięcy połączeń z bazą danych, co sprawiło, że instancja MySQL stała się de facto niezdolna do działania. Utrudniało to diagnostykę problemu. Ustaliliśmy limit maksymalnej liczby połączeń od klientów, aby pomóc zespołowi SRE ocenić problem. Nie zauważono żadnych nietypowych ruchów do bazy danych: w rzeczywistości większość zapytań dotyczyła odczytu, a jedynie nieliczne — zapisu.
Próbowaliśmy zidentyfikować wzór w ruchu bazy danych, który mógłby spowodować tę lawinę. Jednak nie udało się znaleźć żadnych wzorców w logach. Oczekując na gotowość nowego klastra z OSD 4.3.18, kontynuowaliśmy próby uruchomienia podów quay.io. Za każdym razem, gdy klaster osiągał pełną moc, baza danych zawieszała się. Oznaczało to, że konieczne było ponowne uruchomienie instancji RDS, oprócz wszystkich podów quay.io.
Do wieczora ustabilizowaliśmy usługę w trybie tylko do odczytu i wyłączyliśmy maksymalnie nieistotne funkcje (na przykład zbieranie śmieci w przestrzeni nazw), aby zmniejszyć obciążenie bazy danych. Zawieszenia ustały, ale przyczyna wciąż nie została znaleziona. Nowy klaster OSD był gotowy, przenieśliśmy usługę, połączyliśmy ruch i kontynuowaliśmy monitorowanie.
Quay.io stabilnie działało na nowym klastrze OSD, więc wróciliśmy do logów bazy danych, ale nie byliśmy w stanie znaleźć korelacji wyjaśniającej blokady. Inżynierowie OpenShift współpracowali z nami, próbując zrozumieć, czy zmiany w Red Hat OpenShift 4.3.19 mogły przyczynić się do problemów z Quay. Jednak niczego nie odkryto, a nie udało się odtworzyć problemu w warunkach laboratoryjnych.
Druga awaria
28 maja, tuż przed południem czasu EDT, quay.io ponownie się zawiesił z tymi samymi objawami: działanie bazy danych zostało zablokowane. I znowu skupiliśmy wszystkie siły na dochodzeniu. Przede wszystkim konieczne było przywrócenie działania usługi. Jednak tym razem ponowne uruchomienie RDS i restart podów quay.io nie przyniosły rezultatu: kolejna lawina połączeń zalała bazę. Ale dlaczego?Quay jest napisane w Pythonie, a każdy pod działa jako jednolity kontener monolityczny. W kontenerze jednocześnie wykonywanych jest wiele równoległych zadań. Używamy biblioteki
gevent do pod gunicorn do obsługi zapytań www. Kiedy Quay otrzymuje zapytanie (przez nasze własne API lub przez API Dockera), przypisywany jest mu worker gevent. Zwykle ten worker powinien skontaktować się z bazą danych. Po pierwszym awarii odkryliśmy, że workery gevent łączyły się z bazą danych, używając ustawień domyślnych.
Biorąc pod uwagę znaczne liczby podów Quay oraz tysiące przychodzących zapytań na sekundę, duża liczba połączeń z bazą danych teoretycznie mogła przeciążyć instancję MySQL. Dzięki monitorowaniu wiadomo było, że Quay średnio przetwarza 5 tysięcy zapytań na sekundę. Zbliżona była także liczba połączeń z bazą danych. 5 tysięcy połączeń mieściło się w możliwościach naszej instancji RDS (czego nie można powiedzieć o dziesiątkach tysięcy). Z jakiegoś powodu pojawiały się nieoczekiwane wzrosty liczby połączeń,jednak nie zauważaliśmy żadnej korelacji z przychodzącymi zapytaniami.
Tym razem zdecydowaliśmy się znaleźć i usunąć źródło problemu, zamiast ograniczać się do ponownego uruchomienia. W kodzie źródłowym Quay wprowadzono zmiany, które ograniczały liczbę połączeń z bazą danych dla każdego worker'a gevent. Ta liczba stała się parametrem w konfiguracji: możliwe stało się zmienianie jej „w locie”, bez potrzeby budowania nowego obrazu kontenera. Aby dowiedzieć się, jaką liczbę połączeń można rzeczywiście obsłużyć, przeprowadzono kilka testów w środowisku stagingowym, w których zadawano różne wartości, aby sprawdzić, jak wpłynie to na scenariusze testów obciążeniowych. Ostatecznie odkryto, że Quay zaczyna generować błędy 502, gdy liczba połączeń przekroczy 10 tysięcy.
Natychmiast wdrożyliśmy tę nową wersję w produkcji i zaczęliśmy monitorować wykres połączeń z bazą danych. W przeszłości baza blokowała się mniej więcej po 20 minutach. Po 30 minutach bez problemów mieliśmy nadzieję, a po godzinie — pewność. Przywróciliśmy ruch zapisu na stronie i przystąpiliśmy do analizy postmortem.
Sukcesem w obejściu problemu, który prowadził do zablokowania, nie ustaliliśmy jego prawdziwych przyczyn,Potwierdzono, że nie ma on związku z żadnymi zmianami w OpenShift 4.3.19, ponieważ to samo zdarzyło się w wersji 4.3.18, która wcześniej działała z Quay bez żadnych problemów.
W klastrze niewątpliwie skrywało się coś jeszcze.
Szczegółowa analiza
Quay.io przez sześć lat korzystał z domyślnych ustawień do podłączenia do bazy danych bez żadnych problemów. Co się zmieniło? Jasne jest, że w tym czasie ruch na quay.io nieustannie rósł. W naszym przypadku wyglądało to tak, jakby osiągnięto pewien próg, który stał się impulsem do lawiny połączeń. Kontynuowaliśmy analizowanie logów bazy danych po drugim awarii, ale nie znaleźliśmy żadnych wzorców ani oczywistych powiązań.
W międzyczasie zespół SRE pracował nad ulepszeniami w zakresie obserwowalności zapytań w Quay oraz ogólnego stanu usługi. Wdrożono nowe metryki i panele monitorowania, pokazujące, które części Quay cieszą się największym zainteresowaniem ze strony klientów.
Quay.io działało normalnie do 9 czerwca. Rano (czasu EDT) ponownie byliśmy świadkami znacznego wzrostu liczby połączeń z bazą danych. Tym razem nie doszło do przestoju, ponieważ nowy parametr ograniczał ich liczbę i nie pozwalał na przekroczenie przepustowości MySQL. Jednak przez około pół godziny wielu użytkowników zgłaszało spowolnienie działania quay.io. Szybko zebraliśmy wszystkie dostępne dane, korzystając z dodanych narzędzi do monitorowania. Nagle zaczęła się ujawniać pewna zasada.
Tuż przed nagłym wzrostem liczby połączeń duża liczba zapytań wpłynęła do App Registry API. App Registry to mało znana funkcja quay.io. Umożliwia przechowywanie takich rzeczy jak wykresy Helm i kontenery z bogatymi metadanymi. Większość użytkowników quay.io nie korzysta z tej funkcji, jednak intensywnie wykorzystuje ją Red Hat OpenShift. OperatorHub w OpenShift przechowuje wszystkie operatory w App Registry. Ci operatorzy stanowią podstawę ekosystemu obciążeń OpenShift oraz modelu operacyjnego (w ramach operacji „drugiego dnia”, Day 2), ukierunkowanego na partnerów.
Każdy klaster OpenShift 4 wykorzystuje operatory z wbudowanego OperatorHub, aby publikować katalog operatorów dostępnych do instalacji i dostarczać aktualizacje dla już zainstalowanych. Wraz z rosnącą popularnością OpenShift 4 wzrosła również liczba klastrów na całym świecie. Każdy z tych klastrów ładuje zawartość operatorów, aby uruchomić wbudowany OperatorHub, wykorzystując App Registry w quay.io jako backend. W poszukiwaniu źródła problemu przegapiliśmy to, że wraz z rosnącą popularnością OpenShift zwiększało się również obciążenie jednej z rzadko używanych funkcji quay.io..
Przeprowadziliśmy analizę ruchu zapytań App Registry i zajrzeliśmy do kodu rejestru. Od razu ujawnili się niedociągnięcia, przez które zapytania do bazy danych były formułowane w sposób nieoptymalny. Przy niskim obciążeniu nie sprawiały żadnych problemów, ale przy jego wzroście stawały się źródłem kłopotów. App Registry miało dwa problematyczne punkty końcowe, które słabo reagowały na wzrost obciążenia: pierwszy zwracał listę wszystkich pakietów w repozytorium, drugi - wszystkie blob'y dla pakietu.
Usuwanie przyczyn
Przez cały następny tydzień zajmowaliśmy się optymalizacją kodu samego App Registry i jego otoczenia. Przeredagowywane były wyraźnie nieskuteczne zapytania SQL, usunięto zbędne wywołania komendy (uruchamiała się przy każdym pobieraniu blob'ów), dodano cachowanie wszędzie tam, gdzie to możliwe. Następnie przeprowadzono rozbudowane testy wydajności i porównano prędkość działania App Registry przed i po zmianach. tar Zapytania API, które wcześniej zajmowały do pół minuty, teraz wykonywały się w milisekundach.
. W następnym tygodniu wdrożyliśmy zmiany w środowisku produkcyjnym i od tego czasu quay.io działa stabilnie. W tym czasie zaobserwowano kilka gwałtownych wzrostów ruchu na punkcie końcowym App Registry, ale wprowadzone usprawnienia zapobiegły zakłóceniom w pracy bazy danych.Czego się nauczyliśmy?
Jasne jest, że każdy serwis stara się unikać przestojów. W naszym przypadku wierzymy, że ostatnie awarie pomogły uczynić quay.io lepszym. Wyciągnęliśmy kilka głównych lekcji, którymi chcemy się podzielić:
Dane na temat tego, kto i jak korzysta z Twojego serwisu, nigdy nie są zbędne.
- . Ponieważ Quay «po prostu działał», nigdy nie mieliśmy potrzeby tracić czasu na optymalizację ruchu i zarządzanie obciążeniem. To wszystko stworzyło fałszywe poczucie bezpieczeństwa, że serwis może skalować się w nieskończoność.Kiedy serwis się awariuje,
- przywrócenie jego działania staje się najwyższym priorytetem. przywrócenie jego działania to priorytet. Ponieważ Quay nadal cierpiał na zablokowaną bazę danych podczas pierwszej awarii, nasze standardowe procedury nie przyniosły zamierzonego efektu i nie mogliśmy przywrócić działania usługi za ich pomocą. Doprowadziło to do sytuacji, w której musieliśmy poświęcić czas na analizę i zbieranie danych w nadziei na znalezienie przyczyny — zamiast kierować wszystkie wysiłki na przywrócenie sprawności.
- Oceń wpływ każdej z funkcji usługi. Klienci rzadko korzystali z App Registry, więc nie był on priorytetem dla naszego zespołu. Kiedy niektóre funkcje produktu są rzadko używane, ich błędy pojawiają się rzadko, a programiści przestają śledzić kod. Łatwo jest stać się ofiarą złudzenia, że tak powinno być — aż nagle ta funkcja nieoczekiwanie staje się centrum dużego incydentu.
Co dalej?
Prace nad zapewnieniem stabilności usługi nigdy się nie kończą i nieustannie ją poprawiamy. Ruch na quay.io nadal rośnie i zdajemy sobie sprawę, że musimy zrobić wszystko, co w naszej mocy, aby zasłużyć na zaufanie klientów. Dlatego obecnie pracujemy nad następującymi zadaniami:
- Wdrożenie replik baz danych tylko do odczytu, aby pomóc usłudze obsługiwać odpowiedni ruch w przypadku problemów z głównym wystąpieniem RDS.
- Aktualizacja wystąpienia RDS. Obecna wersja sama w sobie nie jest problemem. Raczej chcemy po prostu usunąć fałszywy ślad (którym podążyliśmy podczas awarii); utrzymanie oprogramowania w aktualnym stanie pozwoli wyeliminować jeszcze jeden czynnik w przypadku przyszłych awarii.
- Dodatkowe buforowanie w całym klastrze. Nadal poszukujemy obszarów, w których buforowanie może zmniejszyć obciążenie bazy danych.
- Dodanie zapory aplikacji internetowych (WAF), aby zobaczyć, kto i dlaczego łączy się z quay.io.
- Począwszy od następnej wersji, klastry Red Hat OpenShift rezygnują z App Registry na rzecz katalogów operatorów (Operator Catalogs) opartych na obrazach kontenerów dostępnych na quay.io.
- Długoterminowym zastąpieniem App Registry może być wsparcie specyfikacji artefaktów Open Container Initiative (OCI). Obecnie jest to realizowane w postaci natywnej funkcjonalności Quay i będzie dostępne dla użytkowników, gdy specyfikacja zostanie ostatecznie zatwierdzona.
Wszystko, co wymienione powyżej, jest częścią trwających inwestycji Red Hat w quay.io, podczas gdy przechodzimy od małego zespołu „start-upowego” do dojrzałej platformy zarządzanej przez SRE. Wiemy, że wielu naszych klientów polega na quay.io w swojej codziennej pracy (w tym Red Hat!) i staramy się być jak najbardziej otwarci na temat niedawnych awarii i trwających wysiłków, aby stać się lepszymi.
P.S. od tłumacza
Przeczytaj także na naszym blogu:
- «»;
- «»;
- «».
Źródło: habr.com
