
Temat monorepo był już wielokrotnie poruszany, a zwykle wywołuje dość aktywne dyskusje. Tworząc jako narzędzie Open Source, mające na celu usprawnienie procesów budowy kodu aplikacji z Git do obrazów Docker (i ich późniejszego dostarczania do Kubernetes), rzadko zastanawiamy się, który wybór jest lepszy. Kluczowe jest dla nas zapewnienie wszystkiego, co niezbędne dla zwolenników różnych opinii (o ile nie stoi to w sprzeczności z rozsądkiem, oczywiście).
Nowo wprowadzona obsługa mono-repo w werf jest dobrym tego przykładem. Ale najpierw zastanówmy się, jak to wsparcie jest związane z używaniem werf oraz jakie ma to powiązanie z Docker Registry…
Problematyka
Wyobraźmy sobie taką sytuację. W firmie jest wiele zespołów programistycznych zajmujących się niezależnymi projektami. Większość aplikacji działa w Kubernetesie, a więc są konteneryzowane. Aby przechowywać kontenery i obrazy, potrzebny jest rejestr (registry). Jako taki rejestr w firmie wykorzystywany jest Docker Hub z jednym kontem. FIRMA. Podobnie jak w większości systemów przechowywania kodu źródłowego, Docker Hub nie pozwala na tworzenie zagnieżdżonej hierarchii repozytoriów, takiej jak FIRMA/PROJEKT/OBRAZ. W takim przypadku… jak poradzić sobie z tym ograniczeniem przy przechowywaniu nierelacyjnych aplikacji w rejestrze, nie tworząc oddzielnego konta dla każdego projektu?

Możliwe, że opisana sytuacja jest komuś dobrze znana, ale zastanówmy się nad organizacją przechowywania aplikacji w ogóle, tj. bez odniesienia do powyższego przykładu i Docker Hub.
Możliwości rozwiązania
Jeśli aplikacja jest monolityczna, dostarczana w jednym obrazie, to nie ma problemu i po prostu przechowujemy obrazy w rejestrze kontenerów projektu.
Kiedy aplikacja jest reprezentowana przez kilka komponentów, mikroserwisów, konieczne jest wybranie odpowiedniego podejścia. Na przykładzie typowej aplikacji webowej składającej się z dwóch obrazów: frontend i backend — możliwe warianty to:
- Przechowywanie obrazów w oddzielnych zagnieżdżonych repozytoriach:

- Przechowywanie wszystkiego w jednym repozytorium, a nazwa obrazu jako tag, na przykład, w następujący sposób:

NB: Właściwie jest jeszcze opcja z przechowywaniem w różnych repozytoriach, PROJEKT-frontend i PROJEKT-backend, ale nie będziemy go rozważać z powodu złożoności wsparcia, organizacji i przydzielania uprawnień między użytkownikami.
Wsparcie w werf
Początkowo werf ograniczał się do repozytoriów zagnieżdżonych — na szczęście większość rejestrów wspiera tę funkcjonalność. Od wersji , dodano obsługę rejestrów, w których nie jest wspierana zagnieżdżoność, w tym Docker Hub. Od tego momentu użytkownik zyskał wybór, jak przechowywać obrazy aplikacji.
Implementacja jest dostępna w ramach opcji --images-repo-mode=multirepo|monorepo (domyślnie multirepo, tzn. przechowywanie w zagnieżdżonych repozytoriach). Określa ona wzorce, według których obrazy są przechowywane w rejestrze. Wystarczy wybrać odpowiedni tryb podczas użycia głównych poleceń, a wszystko inne pozostanie bez zmian.
Ponieważ większość opcji werf można ustawić zmiennymi środowiskowymi, w systemach CI/CD tryb przechowywania można zazwyczaj łatwo ustawić globalnie dla całego projektu. Na przykład, w przypadku GitLab wystarczy dodać zmienną środowiskową w ustawieniach projektu: Ustawienia -> CI / CD -> Zmienne: WERF_IMAGES_REPO_MODE: multirepo|monorepo.
Jeśli chodzi o publikację obrazów i wdrażanie aplikacji (o tych procesach można przeczytać w odpowiednich artykułach dokumentacji: i ), to tryb określa szablon, według którego można pracować z obrazem.
Diabeł tkwi w szczegółach
Różnica i główna trudność przy dodawaniu nowego sposobu przechowywania polega na procesie czyszczenia rejestru (możliwości czyszczenia wspierane w werf, patrz ).
Podczas czyszczenia werf uwzględnia obrazy używane w klastrach Kubernetes, a także polityki ustalane przez użytkownika. W podstawie polityk leży podział tagów na strategie. Strategie aktualnie wspierane to:
- 3 strategie związane z podstawowymi operacjami Git, takimi jak tag, gałąź i commit;
- 1 strategia dla dowolnych tagów użytkowników.
Informacje o strategii taga przechowujemy podczas publikacji obrazu w etykietach końcowego obrazu. Samo znaczenie – tzw. metatag – jest niezbędne do zastosowania części polityk. Na przykład przy usuwaniu gałęzi lub taga z repozytorium Git logiczne jest usunięcie również powiązanych nieużywanych obrazów z rejestru, co jest objęte częścią naszych polityk.
Podczas przechowywania w jednym repozytorium (monorepo), w tagu obrazu, oprócz metatagu, może być również przechowywana nazwa obrazu: PROJEKT:frontend-META-TAG. Aby je oddzielić, nie wprowadziliśmy żadnego specyficznego separatora, lecz po prostu dodaliśmy potrzebną wartość do etykiety końcowego obrazu przy publikacji.
NB: Jeśli chcesz zobaczyć wszystko opisane w kodzie źródłowym werf, punktem wyjścia może być .
W tym artykule nie poświęcimy więcej uwagi problematyce i uzasadnieniu naszego podejścia: o strategiach tagowania, przechowywaniu danych w etykietach oraz o procesie publikacji w całości — szczegółowo opisano to w niedawnym wystąpieniu Dmitrija Stoljarowa: „».
Podsumowując
Brak wsparcia dla rejestrów bez zagnieżdżeń nie był czynnikiem blokującym dla nas ani dla znanych nam użytkowników werf — zawsze można podnieść oddzielny rejestr obrazów (lub przejść na tzw. Container Registry w Google Cloud)… Jednak zniesienie takiego ograniczenia wydawało się logiczne, aby narzędzie było bardziej przyjazne dla szerszej społeczności DevOps. Realizując to, napotkaliśmy główny problem z przetwarzaniem mechanizmu czyszczenia rejestru kontenerów. Teraz, kiedy wszystko jest gotowe, cieszy nas, że komuś jest łatwiej, a my (jako główni deweloperzy projektu) nie przewidujemy znaczących trudności w dalszym wsparciu tej funkcji.
Pozostańcie z nami, wkrótce opowiemy o innych nowościach w !
P.S.
Przeczytaj również na naszym blogu:
- «»;
- «».
Źródło: habr.com


