Historia wdrożenia, która wpłynęła na wszystko

Historia wdrożenia, która wpłynęła na wszystko
Wrogowie rzeczywistości do 12f-2

Pod koniec kwietnia, kiedy Biali Wędrowcy oblegali Winterfell, przydarzyło nam się coś ciekawszego; zrobiliśmy nietypowy rollout. Zasadniczo stale wprowadzamy nowe funkcje do wersji produkcyjnej (jak wszyscy inni). Ale ten był inny. Skala tego była taka, że ​​wszelkie potencjalne błędy, które moglibyśmy popełnić, miałyby wpływ na wszystkie nasze usługi i użytkowników. Dzięki temu wszystko wdrożyliśmy zgodnie z planem, w zaplanowanym i ogłoszonym okresie przestoju, bez konsekwencji dla sprzedaży. Artykuł opowiada o tym, jak nam się to udało i jak każdy może to powtórzyć w domu.

Nie będę teraz opisywał podejmowanych przez nas decyzji architektonicznych i technicznych ani nie będę opowiadał, jak to wszystko działa. To raczej notatki na marginesie o tym, jak odbył się jeden z najtrudniejszych rolloutów, który obserwowałem i w który byłem bezpośrednio zaangażowany. Nie zastrzegam sobie kompletności ani szczegółów technicznych, być może pojawią się one w innym artykule.

Tło + co to za funkcjonalność?

Budujemy platformę chmurową Rozwiązania chmurowe Mail.ru (MCS), gdzie pełnię funkcję dyrektora technicznego. A teraz nadszedł czas, aby dodać do naszej platformy IAM (zarządzanie tożsamością i dostępem), która zapewnia ujednolicone zarządzanie wszystkimi kontami użytkowników, użytkownikami, hasłami, rolami, usługami i nie tylko. Dlaczego jest potrzebny w chmurze, jest oczywistym pytaniem: wszystkie informacje o użytkowniku są w niej przechowywane.

Zwykle takie rzeczy zaczynają być budowane na samym początku każdego projektu. Ale historycznie rzecz biorąc, w MCS było trochę inaczej. MCS został zbudowany z dwóch części:

  • Openstack z własnym modułem autoryzacji Keystone,
  • Hotbox (pamięć S3) w oparciu o projekt Mail.ru Cloud,

wokół których następnie pojawiły się nowe usługi.

Zasadniczo były to dwa różne rodzaje zezwoleń. Dodatkowo wykorzystaliśmy kilka osobnych rozwiązań Mail.ru, na przykład ogólne przechowywanie haseł Mail.ru, a także samodzielnie napisany konektor openid, dzięki któremu w panelu Horizon zapewniono SSO (autoryzacja end-to-end) maszyn wirtualnych (natywny interfejs OpenStack).

Tworzenie IAM oznaczało dla nas połączenie tego wszystkiego w jeden, całkowicie nasz własny system. Jednocześnie nie stracimy po drodze żadnej funkcjonalności, ale stworzymy fundament na przyszłość, który pozwoli nam ją w przejrzysty sposób dopracować bez refaktoryzacji i skalować pod kątem funkcjonalności. Również na początku użytkownicy mieli wzór do naśladowania w zakresie dostępu do usług (centralny RBAC, kontrola dostępu oparta na rolach) i kilku innych drobiazgów.

Zadanie okazało się nietrywialne: python i perl, kilka backendów, niezależnie napisane usługi, kilka zespołów programistycznych i administratorów. A co najważniejsze, w systemie produkcji bojowej są tysiące aktywnych użytkowników. Wszystko to trzeba było napisać i, co najważniejsze, przeprowadzić bez ofiar.

Co będziemy wdrażać?

Krótko mówiąc, w około 4 miesiące przygotowaliśmy:

  • Stworzyliśmy kilka nowych demonów, które agregowały funkcje, które wcześniej działały w różnych częściach infrastruktury. Reszcie usług przepisano nowy backend w postaci tych demonów.
  • Napisaliśmy własny, centralny magazyn haseł i kluczy, dostępny dla wszystkich naszych usług, który możemy dowolnie modyfikować według potrzeb.
  • Napisaliśmy od podstaw 4 nowe backendy dla Keystone (użytkownicy, projekty, role, przypisania ról), które de facto zastąpiły jego bazę danych, a teraz pełnią funkcję pojedynczego repozytorium haseł naszych użytkowników.
  • Nauczyliśmy wszystkie nasze usługi Openstack, aby korzystały z usług zewnętrznych firm w celu uzyskania zasad, zamiast czytać je lokalnie z każdego serwera (tak, tak domyślnie działa Openstack!).

Tak duża przeróbka wymaga dużych, złożonych i, co najważniejsze, synchronicznych zmian w kilku systemach napisanych przez różne zespoły programistów. Po złożeniu cały system powinien działać.

Jak wprowadzić takie zmiany i ich nie schrzanić? Najpierw postanowiliśmy spojrzeć trochę w przyszłość.

Strategia wdrożenia

  • Możliwe byłoby wdrożenie produktu w kilku etapach, ale to wydłużyłoby czas rozwoju trzykrotnie. Dodatkowo przez jakiś czas mielibyśmy całkowitą desynchronizację danych w bazach danych. Musiałbyś napisać własne narzędzia do synchronizacji i pracować z wieloma magazynami danych przez długi czas. A to stwarza całą gamę zagrożeń.
  • Wszystko, co można było przygotować w sposób przejrzysty dla użytkownika, zostało zrobione z wyprzedzeniem. Zajęło to 2 miesiące.
  • Pozwoliliśmy sobie na kilkugodzinny przestój – tylko na operacje użytkownika w celu tworzenia i zmiany zasobów.
  • Dla pracy wszystkich już utworzonych zasobów przestoje były niedopuszczalne. Zaplanowaliśmy, że podczas rolloutu zasoby powinny działać bez przestojów i mieć wpływ na klientów.
  • Aby zmniejszyć wpływ, jaki będzie miał na naszych klientów, jeśli coś pójdzie nie tak, zdecydowaliśmy się na wdrożenie rozwiązania w niedzielę wieczorem. Mniej klientów zarządza maszynami wirtualnymi w nocy.
  • Ostrzegaliśmy wszystkich naszych klientów, że w okresie wybranym do wdrożenia zarządzanie usługami będzie niedostępne.

Dygresja: co to jest rollout?

<ostrożność, filozofia>

Każdy informatyk z łatwością odpowie, czym jest rollout. Instalujesz CI/CD i wszystko jest automatycznie dostarczane do sklepu. 🙂

Oczywiście, że to prawda. Trudność polega jednak na tym, że dzięki nowoczesnym narzędziom do automatyzacji dostarczania kodu traci się zrozumienie samego wdrożenia. Jak zapomina się o epickości wynalezienia koła, patrząc na nowoczesny transport. Wszystko jest na tyle zautomatyzowane, że często wdrożenie odbywa się bez zrozumienia całości.

A cały obraz wygląda tak. Wdrożenie składa się z czterech głównych aspektów:

  1. Dostarczenie kodu wraz z modyfikacją danych. Na przykład ich migracje.
  2. Wycofanie kodu to możliwość przywrócenia działania, jeśli coś pójdzie nie tak. Na przykład poprzez tworzenie kopii zapasowych.
  3. Czas każdej operacji wdrażania/wycofywania. Musisz zrozumieć czas wykonania dowolnej operacji w pierwszych dwóch punktach.
  4. Dotknięta funkcjonalność. Należy ocenić zarówno oczekiwane pozytywne, jak i możliwe negatywne skutki.

Aby wdrożenie przebiegło pomyślnie, należy wziąć pod uwagę wszystkie te aspekty. Zwykle oceniany jest tylko pierwszy, a w najlepszym razie drugi punkt, a następnie wdrożenie uznaje się za zakończone sukcesem. Ale trzeci i czwarty są jeszcze ważniejsze. Który użytkownik by tego chciał, gdyby wdrożenie trwało 3 godziny zamiast minuty? A może podczas wdrażania wpłynie to na coś niepotrzebnego? A może przestój jednej usługi doprowadzi do nieprzewidywalnych konsekwencji?

Akt 1..n, przygotowanie do wydania

Najpierw pomyślałem, żeby krótko opisać nasze spotkania: cały zespół, jego części, mnóstwo dyskusji przy kawie, kłótnie, testy, burze mózgów. Wtedy pomyślałem, że to niepotrzebne. Na to zawsze składają się cztery miesiące rozwoju, szczególnie gdy nie piszesz czegoś, co może być dostarczane w sposób ciągły, ale jedną dużą funkcję dla działającego systemu. Dotyczy to wszystkich usług, ale dla użytkowników nic nie powinno się zmienić poza „jednym przyciskiem w interfejsie internetowym”.

Nasze zrozumienie sposobu wdrożenia zmieniało się z każdym nowym spotkaniem i to dość znacząco. Na przykład mieliśmy zaktualizować całą naszą bazę danych rozliczeniowych. Obliczyliśmy jednak czas i zdaliśmy sobie sprawę, że nie da się tego zrobić w rozsądnym czasie wdrożenia. Podzielenie i zarchiwizowanie bazy danych rozliczeniowych zajęło nam prawie dodatkowy tydzień. A gdy oczekiwana prędkość rozmieszczania w dalszym ciągu nie była zadowalająca, zamówiliśmy dodatkowy, mocniejszy sprzęt, na który przeciągano całą bazę. To nie tak, że nie chcieliśmy tego zrobić wcześniej, ale obecna potrzeba wdrożenia nie pozostawiła nam żadnych opcji.

Kiedy ktoś z nas miał wątpliwości, czy rollout może wpłynąć na dostępność naszych maszyn wirtualnych, spędziliśmy tydzień na przeprowadzaniu testów, eksperymentów, analizie kodu i otrzymaliśmy jasne zrozumienie, że w naszej produkcji nie będzie to miało miejsca, i nawet najbardziej wątpiące osoby zgodziły się z tym.

W międzyczasie ludzie z pomocy technicznej przeprowadzili własne, niezależne eksperymenty, aby napisać instrukcje dla klientów dotyczące metod połączeń, które miały ulec zmianie po wdrożeniu. Zajmowali się UX użytkownika, przygotowywali instrukcje i udzielali osobistych konsultacji.

Zautomatyzowaliśmy wszystkie możliwe operacje wdrożeniowe. Każda operacja, nawet najprostsza, była oskryptowana i na bieżąco przeprowadzane były testy. Dyskutowali o tym, jak najlepiej wyłączyć usługę - pominąć demona lub zablokować dostęp do usługi za pomocą firewalla. Stworzyliśmy listę kontrolną zespołów na każdym etapie wdrożenia i na bieżąco ją aktualizujemy. Rysowaliśmy i stale aktualizowaliśmy wykres Gantta dla wszystkich prac wdrożeniowych wraz z harmonogramem.

A więc…

Ostatni akt przed wypuszczeniem

...czas działać.

Jak to mówią, dzieła sztuki nie można ukończyć, można jedynie dokończyć nad nim pracę. Trzeba wysilić wolę, rozumiejąc, że nie znajdziesz wszystkiego, ale wierząc, że przyjąłeś wszystkie rozsądne założenia, uwzględniłeś wszystkie możliwe przypadki, zamknąłeś wszystkie krytyczne błędy, a wszyscy uczestnicy zrobili wszystko, co mogli. Im więcej kodu wdrożysz, tym trudniej się o tym przekonać (poza tym każdy rozumie, że nie da się wszystkiego przewidzieć).

Zdecydowaliśmy, że jesteśmy gotowi do wdrożenia, gdy byliśmy przekonani, że zrobiliśmy wszystko, co w naszej mocy, aby pokryć wszelkie ryzyko dla naszych użytkowników związane z nieoczekiwanymi awariami i przestojami. Oznacza to, że wszystko może pójść nie tak, z wyjątkiem:

  1. Wpływ na (dla nas świętą, najcenniejszą) infrastrukturę użytkownika,
  2. Funkcjonalność: korzystanie z naszego serwisu po wdrożeniu powinno przebiegać tak samo jak przed nim.

Rozwijanie się

Historia wdrożenia, która wpłynęła na wszystko
Dwa rzuty, 8 nie przeszkadzają

W przypadku wszystkich żądań użytkowników bierzemy przestój na 7 godzin. W tej chwili mamy zarówno plan wdrożenia, jak i plan wycofywania.

  • Samo wdrożenie trwa około 3 godzin.
  • 2 godziny na testowanie.
  • 2 godziny – rezerwa na ewentualne wycofanie zmian.

Dla każdego działania sporządzono wykres Gantta, ile czasu zajmuje, co dzieje się sekwencyjnie, co jest wykonywane równolegle.

Historia wdrożenia, która wpłynęła na wszystko
Kawałek rolloutowego wykresu Gantta, jedna z wczesnych wersji (bez wykonania równoległego). Najcenniejsze narzędzie do synchronizacji

Wszyscy uczestnicy mają ustaloną rolę we wdrożeniu, jakie zadania wykonują i za co są odpowiedzialni. Staramy się doprowadzić każdy etap do automatyzacji, wdrożyć go, wycofać, zebrać opinie i wdrożyć ponownie.

Kronika wydarzeń

I tak w niedzielę 15 kwietnia o godzinie 29 do pracy przyszło 10 osób. Oprócz kluczowych uczestników, niektórzy przyszli po prostu wesprzeć drużynę, za co im należą się szczególne podziękowania.

Warto również wspomnieć, że nasz tester kluczy jest na wakacjach. Nie da się wdrożyć bez testów. Badamy różne opcje. Koleżanka zgadza się nas przetestować z wakacji, za co otrzymuje ogromną wdzięczność od całego zespołu.

00:00. Zatrzymywać się
Zatrzymujemy prośby użytkowników, wieszamy tabliczkę z informacją o pracach technicznych. Monitoring krzyczy, ale wszystko jest w normie. Sprawdzamy, czy nic nie spadło poza tym, co miało spaść. I zaczynamy pracę nad migracją.

Każdy ma wydrukowany plan wdrożenia punkt po punkcie, każdy wie, kto co robi i w jakim momencie. Po każdej akcji sprawdzamy terminy, aby ich nie przekroczyć i wszystko przebiega zgodnie z planem. Ci, którzy na obecnym etapie nie uczestniczą bezpośrednio w wdrożeniu, przygotowują się, uruchamiając zabawkę online (Xonotic, szarlatany typu 3), aby nie przeszkadzać swoim współpracownikom. 🙂

02:00. Rozwinięte
Miła niespodzianka - wdrożenie kończymy godzinę wcześniej, ze względu na optymalizację naszych baz danych i skryptów migracyjnych. Ogólny okrzyk: „Wtoczono!” Wszystkie nowe funkcje są w fazie produkcji, ale na razie tylko my możemy je zobaczyć w interfejsie. Każdy przechodzi w tryb testowy, sortuje je w grupy i zaczyna widzieć, co się ostatecznie wydarzyło.

Nie wyszło najlepiej, przekonujemy się o tym po 10 minutach, kiedy nic nie jest podłączone i nie pracuje w projektach członków zespołu. Szybka synchronizacja, zgłaszamy nasze problemy, ustalamy priorytety, dzielimy się na zespoły i przystępujemy do debugowania.

02:30. Dwa duże problemy kontra czworo oczu
Widzimy dwa duże problemy. Zdaliśmy sobie sprawę, że klienci nie zobaczą niektórych połączonych usług i pojawią się problemy z kontami partnerskimi. Obydwa wynikają z niedoskonałych skryptów migracji w niektórych przypadkach Edge. Musimy to naprawić teraz.

Piszemy zapytania, które to rejestrują, mając co najmniej 4 oczy. Testujemy je na etapie przedprodukcyjnym, aby mieć pewność, że działają i niczego nie psują. Możesz się rolować. W tym samym czasie regularnie przeprowadzamy testy integracyjne, które ujawniają jeszcze kilka problemów. Wszystkie są małe, ale też wymagają naprawy.

03:00. -2 problemy +2 problemy
Dwa poprzednie duże problemy zostały naprawione i prawie wszystkie mniejsze również. Wszyscy niezajęci poprawkami aktywnie pracują na swoich kontach i raportują, co znajdą. Ustalamy priorytety, rozdzielamy między zespoły i zostawiamy niekrytyczne elementy na rano.

Przeprowadzamy testy ponownie i odkrywają dwa nowe, duże problemy. Nie wszystkie zasady usług dotarły poprawnie, dlatego niektóre żądania użytkowników nie przechodzą autoryzacji. Plus nowy problem z kontami partnerskimi. Spieszmy szukać.

03:20. Synchronizacja awaryjna
Naprawiono jeden nowy problem. Po drugie, organizujemy synchronizację awaryjną. Rozumiemy, co się dzieje: poprzednia poprawka rozwiązała jeden problem, ale stworzyła inny. Robimy sobie przerwę, aby dowiedzieć się, jak zrobić to poprawnie i bez konsekwencji.

03:30. Sześć oczu
Rozumiemy, jaki powinien być końcowy stan bazy, aby wszystko układało się pomyślnie dla wszystkich partnerów. Piszemy wniosek 6 oczami, wdrażamy go na etapie przedprodukcyjnym, testujemy, wdrażamy na produkcję.

04:00. Wszystko działa
Wszystkie testy przeszły pomyślnie, nie widać żadnych krytycznych problemów. Czasem coś w zespole komuś nie pasuje, reagujemy błyskawicznie. Najczęściej alarm jest fałszywy. Ale czasami coś nie dociera lub osobna strona nie działa. Siedzimy, naprawiamy, naprawiamy, naprawiamy. Oddzielny zespół uruchamia ostatnią dużą funkcję – rozliczenia.

04:30. Punkt bez powrotu
Zbliża się punkt bez powrotu, czyli moment, w którym jeśli zaczniemy się wycofywać, nie dotrzymamy danego nam przestoju. Są problemy z rozliczeniami, które wszystko wiedzą i rejestrują, ale uparcie odmawiają odpisywania pieniędzy od klientów. Istnieje kilka błędów na poszczególnych stronach, akcjach i statusach. Główna funkcjonalność działa, wszystkie testy przechodzą pomyślnie. Decydujemy, że wdrożenie miało miejsce, nie będziemy się wycofywać.

06:00. Otwarte dla wszystkich w interfejsie użytkownika
Błędy naprawione. Niektóre, które nie podobają się użytkownikom, zostają pozostawione na później. Otwieramy interfejs dla każdego. Kontynuujemy prace nad rozliczeniami, czekamy na opinie użytkowników i wyniki monitoringu.

07:00. Problemy z ładowaniem API
Staje się jasne, że nieco źle zaplanowaliśmy obciążenie naszego API i przetestowaliśmy to obciążenie, które nie mogło zidentyfikować problemu. W rezultacie ≈5% żądań kończy się niepowodzeniem. Zmobilizujmy się i poszukajmy przyczyny.

Billing jest uparty i też nie chce działać. Postanawiamy odłożyć to na później, aby spokojnie przeprowadzić zmiany. Oznacza to, że gromadzone są w nim wszystkie zasoby, ale odpisy od klientów nie są realizowane. Oczywiście jest to problem, ale w porównaniu do ogólnego rolloutu wydaje się to nieistotne.

08:00. Napraw interfejs API
Wprowadziliśmy poprawkę dotyczącą obciążenia, awarie zniknęły. Zaczynamy wracać do domu.

10:00. Wszystko
Wszystko jest naprawione. Na monitoringu panuje cisza, a u klientów ekipa stopniowo zasypia. Rozliczenie pozostaje, przywrócimy je jutro.

Następnie w ciągu dnia miały miejsce wdrożenia, które naprawiały logi, powiadomienia, kody zwrotne i dostosowania dla niektórych naszych klientów.

Zatem wdrożenie się powiodło! Mogło być oczywiście lepiej, ale wyciągnęliśmy wnioski, czego nam brakowało do osiągnięcia perfekcji.

Razem

W ciągu 2 miesięcy aktywnych przygotowań do rolloutu zrealizowano 43 zadania trwające od kilku godzin do kilku dni.

Podczas wdrażania:

  • nowe i zmienione demony - 5 sztuk, zastępujące 2 monolity;
  • zmiany w obrębie baz danych - dotyczyło to wszystkich 6 naszych baz danych z danymi użytkowników, dokonano pobrań z trzech starych baz do jednej nowej;
  • całkowicie przeprojektowany interfejs;
  • ilość pobranego kodu - 33 tys. linii nowego kodu, ≈ 3 tys. linii kodu w testach, ≈ 5 tys. linii kodu migracyjnego;
  • wszystkie dane są nienaruszone, żadna maszyna wirtualna klienta nie została uszkodzona. 🙂

Dobre praktyki dobrego wdrożenia

Prowadzili nas w tej trudnej sytuacji. Ale ogólnie rzecz biorąc, warto ich przestrzegać podczas każdego wdrożenia. Jednak im bardziej złożone wdrożenie, tym większą rolę odgrywają.

  1. Pierwszą rzeczą, którą musisz zrobić, to zrozumieć, w jaki sposób wdrożenie może lub będzie miało wpływ na użytkowników. Czy będzie przestój? Jeśli tak, jaki jest przestój? Jak wpłynie to na użytkowników? Jakie są możliwe najlepsze i najgorsze scenariusze? I zabezpiecz ryzyko.
  2. Zaplanuj wszystko. Na każdym etapie musisz zrozumieć wszystkie aspekty wdrożenia:
    • dostawa kodu;
    • wycofanie kodu;
    • czas każdej operacji;
    • dotknięta funkcjonalność.
  3. Graj według scenariuszy, aż wszystkie etapy wdrożenia i ryzyko związane z każdym z nich staną się oczywiste. Jeśli masz jakiekolwiek wątpliwości, możesz zrobić sobie przerwę i osobno zbadać wątpliwy etap.
  4. Każdy etap można i należy ulepszyć, jeśli ma to pomóc naszym użytkownikom. Na przykład skróci przestoje lub usunie część zagrożeń.
  5. Testowanie wycofywania zmian jest znacznie ważniejsze niż testowanie dostarczania kodu. Koniecznie należy sprawdzić, czy w wyniku rollbacku system powróci do stanu pierwotnego i potwierdzić to testami.
  6. Wszystko, co można zautomatyzować, powinno zostać zautomatyzowane. Wszystko, czego nie da się zautomatyzować, należy wcześniej zapisać na ściągawce.
  7. Zapisz kryterium sukcesu. Jaka funkcjonalność powinna być dostępna i w jakim czasie? Jeśli tak się nie stanie, uruchom plan wycofania.
  8. A co najważniejsze – ludzie. Każdy powinien być świadomy tego, co robi, dlaczego i od czego zależy jego działania w procesie rolloutu.

Jednym zdaniem, dzięki dobremu planowaniu i opracowaniu możesz wdrożyć wszystko, co chcesz, bez konsekwencji dla sprzedaży. Nawet coś, co będzie miało wpływ na wszystkie Twoje usługi w produkcji.

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

Dodaj komentarz