
Temat monorepo był już wielokrotnie omawiany i zazwyczaj wywołuje dość żywe dyskusje. Tworząc jako narzędzie Open Source, mające na celu ulepszenie procesów budowy kodu aplikacji z Git do obrazów Docker (i ich późniejszej dostawy do Kubernetes), rzadko zastanawiamy się, który wybór jest lepszy. Najważniejsze dla nas jest zapewnienie wszystkiego, co niezbędne zwolennikom różnych opinii (o ile to nie stoi w sprzeczności z rozsądkiem, oczywiście).
Niedawno wprowadzona obsługa mono-repo w werf jest dobrym tego przykładem. Ale najpierw rozważmy, jak ta obsługa w ogóle wiąże się z używaniem werf i co ma wspólnego 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 Kubernetes, a zatem są konteneryzowane. Do przechowywania kontenerów i obrazów potrzebny jest rejestr (registry). Jako taki rejestr w firmie używany jest Docker Hub z jedynym kontem COMPANY. Na podobieństwo większości systemów przechowywania kodu źródłowego, Docker Hub nie pozwala na tworzenie zagnieżdżonej hierarchii repozytoriów, takiej jak COMPANY/PROJECT/IMAGE. W takim przypadku… jak więc przechowywać w rejestrze aplilacje niemonolityczne, nie tworząc osobnego konta dla każdego projektu?

Możliwe, że opisana sytuacja jest komuś znana, ale rozważmy temat organizacji przechowywania aplikacji w ogóle, tzn. bez odniesienia do powyższego przykładu i Docker Hub.
Sposoby rozwiązania
Jeśli aplikacja jest monolityczna, dostarczana w jednym obrazie, to nie ma z tym problemów i po prostu zapisujemy obrazy w rejestrze kontenerów projektu.
Gdy aplikacja jest przedstawiona w postaci kilku komponentów, mikroserwisów, należy wybrać określone podejście. Na przykładzie typowej aplikacji webowej składającej się z dwóch obrazów: frontend i backend — możliwe opcje to:
- Przechowywać obrazy w osobnych zagnieżdżonych repozytoriach:

- Przechowywać wszystko w jednym repozytorium, a nazwę obrazu uwzględnić w tagu, na przykład w następujący sposób:

NB: W ogóle rzecz biorąc, istnieje jeszcze możliwość przechowywania w różnych repozytoriach, PROJECT-frontend i PROJECT-backend, ale nie będziemy jej rozważać ze względu na trudności w utrzymaniu, organizacji i rozdzielaniu uprawnień między użytkownikami.
Wsparcie w werf
Początkowo werf ograniczał się do zagnieżdżonych repozytoriów — na szczęście większość rejestrów wspiera tę możliwość. Od wersji , dodano obsługę rejestrów, w których nie wspiera się zagnieżdżenia, a Docker Hub jest jednym z nich. Od tego momentu użytkownik ma wybór, jak przechowywać obrazy aplikacji.
Implementacja jest dostępna w ramach opcji --images-repo-mode=multirepo|monorepo (domyślnie multirepo, tj. przechowywanie w zagnieżdżonych repozytoriach). Określa ona wzorce, według których obrazy są przechowywane w rejestrze. Wystarczy wybrać odpowiedni tryb przy użyciu podstawowych poleceń, a reszta pozostanie niezmieniona.
Ponieważ większość opcji werf można ustawiać zmiennymi środowiskowymi, w systemach CI/CD tryb przechowywania, zazwyczaj, można łatwo ustawić globalnie dla całego projektu. Na przykład, w przypadku GitLaba wystarczy dodać zmienną środowiskową w ustawieniach projektu: Ustawienia -> CI / CD -> Zmienne: WERF_IMAGES_REPO_MODE: multirepo|monorepo.
Jeśli mówimy o publikacji obrazów i wdrażaniu aplikacji (o tych procesach można dokładniej przeczytać w odpowiednich artykułach dokumentacji: i ), to tryb jednoznacznie określa wzorzec, 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 — to proces czyszczenia registry (możliwości czyszczenia dostępne w werf, patrz w ).
Przy czyszczeniu werf bierze pod uwagę obrazy używane w klastrach Kubernetes, a także polityki ustalane przez użytkownika. Podstawą polityk jest rozdzielenie tagów na strategie. Strategie obecnie wspierane to:
- 3 strategie związane z prymitywami Git, takimi jak tag, gałąź i commit;
- 1 strategia dla dowolnych, użytkowniczych tagów.
Informacje o strategii tagu przechowujemy przy publikacji obrazu w etykietach końcowego obrazu. Sama wartość — tak zwany metatag — jest niezbędna do stosowania części polityk. Na przykład, przy usuwaniu gałęzi lub tagu z repozytorium Git logiczne jest usunąć także powiązane niewykorzystywane obrazy z rejestru, co jest objęte częścią naszych polityk.
Przy zachowaniu w jednym repozytorium (monorepo), w tagu obrazu, poza metatagiem, może być również przechowywana nazwa obrazu: PROJEKT:frontend-META-TAG. Aby je oddzielić, nie wprowadzaliśmy żadnego specyficznego separatora, tylko dodaliśmy niezbędną wartość do etykiety końcowego obrazu podczas publikacji.
NB: Jeśli chcesz zobaczyć wszystko, co opisano w kodzie źródłowym werf, punkt wyjścia może stanowić .
W tym artykule nie będziemy poświęcać więcej uwagi problematyce oraz uzasadnieniu naszego podejścia: na temat strategii tagowania, przechowywania danych w etykietach i procesu publikacji jako całości — wszystko to zostało szczegółowo opisane w niedawnym wystąpieniu Dmitrija Stoljarowa: „».
Podsumowując,
Brak wsparcia dla rejestrów bez zagnieżdżenia nie stanowił dla nas ani dla znanych nam użytkowników werf czynnika blokującego — zawsze można było utworzyć 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 szerszemu społeczności DevOps. Wprowadzając to, napotkaliśmy główną trudność w przetwarzaniu mechanizmu czyszczenia rejestru kontenerów. Teraz, gdy wszystko jest gotowe, miło jest wiedzieć, że komuś stało się łatwiej, a my (jako główni programiści projektu) nie przewidujemy znaczących trudności w dalszym wsparciu tej funkcji.
Pozostań z nami, a wkrótce opowiemy o innych nowościach w !
P.S.
Przeczytaj także na naszym blogu:
- «»;
- «».
Źródło: habr.com


