Jak oddzielić migracje bazy danych od uruchamiania aplikacji podczas wdrażania kontenerów

Eva Wong jest Technicznym pisarzem i stałym majsterkowiczem w ZimaSpace. Całe życie geek z pasją do homelabów i oprogramowania open-source, specjalizuje się w tłumaczeniu skomplikowanych koncepcji technicznych na przystępne, praktyczne przewodniki. Eva wierzy, że samodzielne hostowanie powinno być zabawą, a nie czymś onieśmielającym. Poprzez swoje samouczki umożliwia społeczności rozwiewanie tajemnic konfiguracji sprzętu, od budowy pierwszego NAS po opanowanie kontenerów Docker.

Duplikatów migracji bazy danych łatwiej uniknąć, gdy zmiany schematu są wdrażane jako jeden jawny etap wdrożenia, a nie podczas uruchamiania każdego kontenera aplikacji.

Zapobiegawcze podejście polega na wyznaczeniu jednego właściciela migracji, jednego zestawu danych uwierzytelniających i jednego sygnału ukończenia, zanim nowe repliki zaczną obsługiwać ruch. Kontenery aplikacji internetowej i workerów powinny móc się restartować bez uzyskiwania uprawnień do zmian schematu, wdrożenie powinno czekać na pomyślne zakończenie zadania migracji, a zmiany schematu należy projektować tak, aby stare i nowe wersje aplikacji mogły przez krótki czas współistnieć. Eliminuje to wyścig zamiast jedynie liczyć na to, że każda replika jako pierwsza zauważy tę samą historię migracji.

Usuń polecenia migracji ze standardowego uruchamiania aplikacji

Sprawdź entrypoint obrazu, polecenie Compose, polecenie workera, wrapper health checka i skrypt wdrożeniowy pod kątem automatycznych wywołań migracji. Aplikacja powinna móc się zrestartować bez modyfikowania schematu, chyba że restart jest celowo wybranym etapem migracji.

Artykuł Octopus dotyczący wdrożeń wskazuje, że migracje wymagają oddzielnego cyklu życia, zamiast być powiązane z uruchamianiem każdego procesu mikrousługi.

Pozostaw plik binarny migracji dostępny tam, gdzie jest potrzebny, ale nie wywołuj go jednocześnie z entrypointu aplikacji internetowej i drugiego zadania. Jeden jawnie wyznaczony właściciel jest łatwiejszy do audytowania niż kilka ścieżek uruchamiania zależnych od blokad frameworka.

Uruchamiaj jedno zadanie migracji przed wdrożeniem

Utwórz jednorazowe zadanie korzystające z tych samych plików migracji co wydanie. Powinno ono kończyć się pomyślnie dopiero wtedy, gdy docelowa baza danych osiągnie oczekiwany stan schematu. Uzależnij wdrożenie aplikacji od tego wyniku.

Aktualny przewodnik wdrożeniowy pokazuje, jak jedno zadanie uruchamia się przed wdrożeniem, zamiast pozwalać każdej replice rywalizować podczas startu.

Nie skaluj zadania migracji tak jak usługi aplikacji. Zadanie powinno mieć jednego wykonawcę dla każdej docelowej bazy danych, ograniczony czas działania, logi oraz wyraźny stan niepowodzenia, który blokuje nową wersję aplikacji.

Uzależnij uruchamianie aplikacji od pomyślnej migracji

Kontenery aplikacji internetowej i workerów powinny czekać na potwierdzenie pomyślnego zakończenia etapu migracji, ale nie powinny ponownie wykonywać migracji. Zależność dotyczy wyniku, a nie ponownego wykonania zmiany schematu.

Wzorzec wdrożeniowy Andrew Locka zakłada, że pody aplikacji czekają na migrację, podczas gdy logika migracji pozostaje scentralizowana.

W przypadku niewielkiego stosu na domowym serwerze tę samą zasadę można wdrożyć za pomocą dedykowanej usługi Compose i kontrolowanego skryptu wdrożeniowego. Mechanizm powinien być na tyle prosty, aby nieudana migracja wyraźnie zatrzymywała wdrożenie.

Stosuj zgodne wstecznie zmiany schematu podczas okresu współistnienia

Wdrożenia kroczące mogą przez pewien czas uruchamiać stare i nowe wersje aplikacji korzystające z jednej bazy danych. Unikaj migracji, która usuwa lub zmienia nazwę pola, zanim stara wersja przestanie go używać.

Niedawny przewodnik dotyczący migracji bez przestojów zaleca najpierw rozszerzać, a dopiero potem zawężać, aby dodatnie zmiany schematu zostały wdrożone przed destrukcyjnym sprzątaniem.

W razie potrzeby podziel duże zmiany na etapy rozszerzania, uzupełniania danych, przełączenia i zawężania. Zadanie migracji nie powinno tworzyć schematu rozumianego wyłącznie przez nowy kontener, gdy stare repliki nadal obsługują żądania.

Nie udostępniaj replikom aplikacji danych uwierzytelniających do migracji

Jeśli to możliwe, używaj konta bazy danych z uprawnieniami do zmian schematu wyłącznie w jednorazowym etapie migracji. Standardowe kontenery aplikacji powinny mieć węższy zakres uprawnień, obejmujący tylko odczyt i zapis danych potrzebnych aplikacji.

Artykuł Liquibase dotyczący wdrożeń opisuje, dlaczego zmiany bazy danych powinny należeć do automatyzacji, zapewniającej kontrolowane i powtarzalne stosowanie zmian.

Takie rozdzielenie zmniejsza ryzyko przypadkowego uruchomienia migracji nawet po restarcie lub zwielokrotnieniu procesu aplikacji. Przechowuj uprzywilejowane dane uwierzytelniające w ścieżce sekretów wdrożeniowych, a nie w środowisku zwykłej, długotrwale działającej usługi.

Sprawdź, czy wdrożenie nie zastosuje partii zmian dwukrotnie

Przetestuj wdrożenie w tymczasowej bazie danych lub na przywróconej migawce, uruchamiając wiele replik aplikacji, restartując je i ponownie wykonując polecenie wdrożeniowe. Etap migracji powinien rozpoznać istniejący stan schematu bez ponownego wprowadzania zmian.

JetBrains podsumowuje zasadę operacyjną jako uruchamianie migracji jako etapu wdrożenia przed standardowym uruchomieniem aplikacji.

Polityka zapobiegania jest kompletna, gdy restarty aplikacji nie mogą modyfikować schematu, jedna nieudana migracja blokuje wydanie, a wielokrotne wykonanie wdrożenia pozostawia bazę danych bez zmian. Powiązany artykuł ZimaSpace na temat diagnozowania duplikatów migracji stanowi ścieżkę naprawczą, jeśli do podwójnego wykonania już doszło.

Wsparcie i wskazówki

Więcej do przeczytania

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.