Wydanie werf 1.1: ulepszenia w kompilatorze oraz plany na przyszłość.

Wydanie werf 1.1: ulepszenia w kompilatorze oraz plany na przyszłość.

werf — nasze narzędzie GitOps CLI z otwartym kodem źródłowym do budowania i dostarczania aplikacji w Kubernetes. Jak obiecaliśmy, premiera wersji v1.0 oznacza początek dodawania nowych funkcji do werf oraz przeglądu ustalonych podejść. Teraz z radością prezentujemy wydanie v1.1, które stanowi duży krok naprzód i zapowiada przyszłość kompilatora werf. Wersja jest obecnie dostępna w kanale 1.1 ea.

Podstawą wydania jest nowa architektura magazynu etapów oraz optymalizacja działania obu kompilatorów (dla Stapel i Dockerfile). Nowa architektura magazynu otwiera możliwości realizacji rozproszonych kompilacji z kilku hostów oraz równoległych kompilacji na jednym hoście.

Optymalizacja działania obejmuje eliminację zbędnych obliczeń na etapie obliczania sygnatur etapów oraz zmianę mechanizmów obliczania sum kontrolnych plików na bardziej efektywne. Ta optymalizacja zmniejsza średni czas kompilacji projektu przy użyciu werf. A także puste kompilacje, gdy wszystkie etapy istnieją w cache stages-storage, są teraz naprawdę szybkie. W większości przypadków ponowne uruchomienie kompilacji zajmie mniej niż 1 sekundę! Dotyczy to również procedur weryfikacji etapów podczas pracy z zespołami werf deploy i werf run.

Również w tej edycji pojawiła się strategia tagowania obrazów na podstawie treści — tagowania opartego na zawartości, która jest teraz domyślnie włączona i jest jedyną zalecaną.

Przyjrzyjmy się dokładniej kluczowym nowinkom w werf v1.1, a także opowiemy o planach na przyszłość.

Co zmieniło się w werf v1.1?

Nowy format nazewnictwa etapów i algorytm dobierania etapów z cache

Nowa zasada generowania nazwy etapu. Teraz każda kompilacja etapu generuje unikalną nazwę etapu, która składa się z 2 części: sygnatura (jak w v1.0) plus unikalny identyfikator czasowy.

Na przykład pełna nazwa obrazu etapu może wyglądać tak:

werf-stages-storage/myproject:d2c5ad3d2c9fcd9e57b50edd9cb26c32d156165eb355318cebc3412b-1582656767835

… lub w ogólnym ujęciu:

werf-stages-storage/PROJECT:SIGNATURE-TIMESTAMP_MILLISEC

Gdzie:

  • SIGNATURE — to sygnatura etapu, która reprezentuje identyfikator treści etapu i zależy od historii zmian w Git, które doprowadziły do tej treści;
  • TIMESTAMP_MILLISEC — to gwarantowany unikalny identyfikator obrazu, który jest generowany w momencie budowy nowego obrazu.

Algorytm dobierania etapów z cache oparty jest na sprawdzaniu pokrewieństwa commitów Git:

  1. Werf oblicza sygnaturę etapu.
  2. W stages-storage Może istnieć wiele etapów o danej sygnaturze. Werf wybiera wszystkie odpowiednie etapy zgodnie z sygnaturą.
  3. Jeśli bieżący etap jest związany z Git (git-archive, użytkownik etapu z łatkami Git: install, beforeSetup, setup; lub git-latest-patch), to werf wybiera tylko te etapy, które są związane z commit'em, będącym przodkiem bieżącego commita (dla którego wywołano budowę).
  4. Z pozostałych odpowiednich etapów wybierany jest jeden — najstarszy pod względem daty utworzenia.

Etap dla różnych gałęzi Git może mieć tę samą sygnaturę. Jednak werf zapobiegnie używaniu pamięci podręcznej związanej z różnymi gałęziami, nawet jeśli sygnatury się pokrywają.

→ Dokumentacja.

Nowy algorytm tworzenia i zapisywania etapów w repozytorium etapów

Jeśli podczas wyszukiwania etapów w pamięci podręcznej werf nie znajdzie odpowiedniego etapu, inicjowany jest proces budowy nowego etapu.

Zauważmy, że kilka procesów (na jednym lub kilku hostach) może rozpocząć budowę tego samego etapu w mniej więcej tym samym czasie. Werf wykorzystuje algorytm optymistycznej blokady stages-storage w momencie zapisywania nowo zbudowanego obrazu w stages-storage. W ten sposób, gdy budowa nowego etapu jest gotowa, werf blokuje stages-storage i zapisuje tam nowo zbudowany obraz tylko wtedy, gdy nie istnieje już odpowiedni obraz (zgodnie z sygnaturą i innymi parametrami — zob. nowy algorytm wyszukiwania etapów w pamięci podręcznej).

Nowo zbudowany obraz zapewne będzie miał unikalny identyfikator według TIMESTAMP_MILLISEC (zob. nowy format nazewnictwa etapów). W przypadku, gdy w stages-storage znajdzie się odpowiedni obraz, werf odrzuci nowo zbudowany obraz i użyje obrazu z pamięci podręcznej.

Innymi słowy: pierwszy proces, który zakończy budowę obrazu (najszybszy), otrzyma prawo do jego zapisania w stages-storage (i to właśnie ten jeden obraz będzie używany dla wszystkich budów). Wolniejszy proces budowy nigdy nie zablokuje szybszego procesu przed zapisaniem wyników budowy bieżącego etapu i przejściem do budowy następnego.

→ Dokumentacja.

Poprawiono wydajność budowniczego Dockerfile

Do tej pory pipeline etapów dla obrazu budowanego z Dockerfile składa się z jednego etapu — dockerfile. Przy obliczaniu sygnatury uwzględniana jest suma kontrolna plików context, które będą używane podczas budowy. Przed tym ulepszeniem werf rekursywnie przechodził przez wszystkie pliki i obliczał sumę kontrolną, sumując kontekst i moduł każdego pliku. Począwszy od wersji v1.1, werf może korzystać z obliczonych sum kontrolnych, przechowywanych w repozytorium Git.

Podstawą algorytmu jest git ls-tree. Algorytm uwzględnia wpisy w .dockerignore i przechodzi rekursywnie przez drzewo plików tylko w razie potrzeby. Dzięki temu uwolniliśmy się od odczytywania systemu plików, a zależność algorytmu od rozmiaru context nie jest istotna.

Algorytm również sprawdza pliki untracked i w razie potrzeby uwzględnia je w sumie kontrolnej.

Ulepszono wydajność podczas importowania plików

W wersjach werf v1.1 wykorzystuje się serwer rsync podczas importowania plików z artefaktów i obrazów. Wcześniej import odbywał się w dwóch krokach z użyciem montowania katalogu z systemu gospodarza.

Wydajność importów w macOS nie jest już ograniczona przez Docker volumes, a importy odbywają się w tym samym czasie, co w systemach Linux i Windows.

Tagowanie oparte na zawartości

Werf v1.1 wspiera tzw. tagowanie oparte na zawartości obrazu — tagowania opartego na zawartości. Tagi wynikowych obrazów Docker zależą od zawartości tych obrazów.

Podczas uruchamiania polecenia werf publish --tags-by-stages-signature lub werf ci-env --tagging-strategy=stages-signature będą tagowane publikowane obrazy tzw. podpisem etapów obrazu. Każdy obraz jest tagowany swoim własnym podpisem etapów tego obrazu, który jest obliczany na tych samych zasadach, co zwykły podpis każdego etapu z osobna, ale stanowi uogólniony identyfikator obrazu.

Podpis etapów obrazu zależy od:

  1. zawartości tego obrazu;
  2. historii zmian w Git, które doprowadziły do tej zawartości.

W repozytorium Git zawsze znajdują się puste commity, które nie zmieniają zawartości plików obrazu. Na przykład, commity tylko z komentarzami, merge-commity lub commity, które zmieniają te pliki w Git, które nie będą importowane do obrazu.

Używając tagowania opartego na zawartości, rozwiązujemy problemy zbędnych ponownych uruchomień podów aplikacji w Kubernetes spowodowanych zmianami nazwy obrazu, nawet jeśli zawartość obrazu się nie zmieniła. Przy okazji, to jeden z powodów, które utrudniają przechowywanie wielu mikrousług jednej aplikacji w jednym repozytorium Git.

Tagowanie oparte na treści jest bardziej niezawodną metodą niż tagowanie oparte na gałęziach Gita, ponieważ zawartość wynikowych obrazów nie zależy od kolejności wykonywania pipeline'ów w systemie CI do budowy wielu commitów z tej samej gałęzi.

Ważne: począwszy od tego momentu stages-signature — to jedyna zalecana strategia tagowania. Będzie ona używana domyślnie w zespole werf ci-env (chyba że wyraźnie określono inną schemat tagowania).

→ Dokumentacja. Ta funkcja zostanie również omówiona w osobnym artykule. ZAAKTUALIZOWANO (3 kwietnia): Artykuł ze szczegółami opublikowane.

Poziomy logowania

Użytkownik ma możliwość kontrolowania wyjścia, ustalania poziomu logowania i pracy z informacjami debugującymi. Dodano opcje --log-quiet, --log-verbose, --log-debug.

Domyślnie w wyjściu znajduje się minimum informacji:

Wydanie werf 1.1: ulepszenia w kompilatorze oraz plany na przyszłość.

Przy użyciu szczegółowego wyjścia (--log-verbose) można śledzić, jak działa werf:

Wydanie werf 1.1: ulepszenia w kompilatorze oraz plany na przyszłość.

Szczegółowe wyjście (--log-debug), oprócz informacji debugujących werf, zawiera również logi używanych bibliotek. Można na przykład zobaczyć, jak odbywa się interakcja z Docker Registry i zidentyfikować miejsca, w których spędza się dużą ilość czasu:

Wydanie werf 1.1: ulepszenia w kompilatorze oraz plany na przyszłość.

Plany przyszłościowe

Uwaga! Opisane poniżej funkcje z oznaczeniem v1.1 staną się dostępne w tej wersji, z wielu z nich - w najbliższym czasie. Aktualizacje zostaną wprowadzone za pośrednictwem automatycznych aktualizacji przy użyciu multiwerf. Te funkcje nie dotyczą stabilnej części funkcji v1.1, ich pojawienie się nie wymaga ręcznego interwencji użytkownika w istniejące konfiguracje.

Pełna obsługa różnych realizacji Docker Registry (NOWOŚĆ)

Celem jest to, aby użytkownik mógł korzystać z dowolnej realizacji bez ograniczeń podczas korzystania z werf.

Na ten moment wyodrębniamy następujący zestaw rozwiązań, dla których zamierzamy zapewnić pełne wsparcie:

  • Default (library/registry)*,
  • AWS ECR,
  • Azure*,
  • Docker Hub,
  • GCR*,
  • GitHub Packages,
  • GitLab Registry*,
  • Harbor*,
  • Quay.

Rozwiązania zaznaczone gwiazdką to te, które obecnie są już w pełni wspierane przez werf. Dla pozostałych jest wsparcie, ale z ograniczeniami.

Można wyróżnić dwa główne problemy:

  • Niektóre rozwiązania nie obsługują usuwania tagów za pomocą API Docker Registry, co uniemożliwia użytkownikom korzystanie z automatycznego czyszczenia, wdrożonego w werf. Dotyczy to AWS ECR, Docker Hub i GitHub Packages.
  • Niektóre rozwiązania nie obsługują tak zwanych zagnieżdżonych repozytoriów (Docker Hub, GitHub Packages i Quay) albo obsługują je, ale użytkownik musi je tworzyć ręcznie, korzystając z UI lub API (AWS ECR).

Te i inne problemy zamierzamy rozwiązać, korzystając z natywnych API tych rozwiązań. W ten proces wchodzi również pokrycie testami całego cyklu pracy werf dla każdego z nich.

Rozproszona budowa obrazów (↑)

  • Wersja: v1.2 v1.1 (priorytet dla wdrożenia tej funkcji został zwiększony)
  • Terminy: marzec-kwiecień marzec
  • Problemu

Na chwilę obecną, werf v1.0 i v1.1 można używać jedynie na jednym dedykowanym hoście do operacji budowy i publikacji obrazów oraz do wdrażania aplikacji w Kubernetes.

Aby zrealizować możliwości rozproszonej pracy werf, kiedy budowa i wdrożenie aplikacji w Kubernetes odbywają się na wielu dowolnych hostach, a hosty te nie zachowują swojego stanu między budowami (tymczasowe runner’y), wymagana jest realizacja możliwości używania Docker Registry jako magazynu kroków.

Wcześniej, kiedy projekt werf nosił nazwę dapp, ta funkcjonalność istniała. Jednak napotkaliśmy szereg problemów, które należy uwzględnić przy wdrożeniu tej funkcji w werf.

Uwaga. Ta możliwość nie zakłada pracy budowniczego wewnątrz pod’ów Kubernetes, ponieważ dla tego wymagana jest eliminacja zależności od lokalnego serwera Docker (w pod’ach Kubernetes brak dostępu do lokalnego serwera Docker, ponieważ sam proces działa w kontenerze, a współpraca z serwerem Docker w sieci nie jest wspierana ani nie będzie wspierana przez werf). Wsparcie dla pracy w Kubernetes zostanie wdrożone oddzielnie.

Oficjalne wsparcie dla GitHub Actions (NOWOŚĆ)

Zawiera dokumentację werf (sekcje reference i guide), a także oficjalną akcję GitHub do pracy z werf.

Ponadto pozwoli to na pracę werf na efemerycznych runnerach.

Mechanika interakcji użytkownika z systemem CI opiera się na przypisywaniu etykiet do pull-request’ów w celu inicjacji określonych działań związanych z budową/wdrożeniem aplikacji.

Lokalny rozwój i wdrażanie aplikacji z werf (↓)

  • Wersja: v1.1
  • Terminy: styczeń-luty kwiecień
  • Problemu

Głównym celem jest osiągnięcie pojedynczej, zunifikowanej konfiguracji do wdrażania aplikacji zarówno lokalnie, jak i w produkcji, bez skomplikowanych działań, „z pudełka”.

Od werf wymagana jest również taka metoda pracy, która umożliwia wygodną edycję kodu aplikacji i natychmiastowe uzyskiwanie informacji zwrotnej z działającej aplikacji do debugowania.

Nowy algorytm czyszczenia (NOWOŚĆ)

  • Wersja: v1.1
  • Terminy: kwiecień
  • Problemu

W bieżącej wersji werf v1.1 w procedurze cleanup nie przewiduje się czyszczenia obrazów dla schematu tagowania opartego na zawartości (content-based tagging) — te obrazy będą się gromadzić.

W bieżącej wersji werf (v1.0 i v1.1) stosowane są różne polityki czyszczenia dla obrazów opublikowanych zgodnie z schematami tagowania: gałąź Git, znacznik Git lub commit Git.

Wprowadzono nowy ujednolicony algorytm czyszczenia obrazów dla wszystkich schematów tagowania, oparty na historii commitów w Git:

  • Przechowywać nie więcej niż N1 obrazów powiązanych z N2 ostatnimi commitami dla każdego z git HEAD (gałęzie i tagi).
  • Przechowywać nie więcej niż N1 obrazów-etapów powiązanych z N2 ostatnimi commitami dla każdego z git HEAD (gałęzie i tagi).
  • Przechowywać wszystkie obrazy, które są używane w jakichkolwiek zasobach klastra Kubernetes (skanowane są wszystkie kube-konteksty pliku konfiguracyjnego i namespace’y; można ograniczyć to zachowanie specjalnymi opcjami).
  • Przechowywać wszystkie obrazy, które są używane w manifestach konfiguracji zasobów zapisanych w Helm-release.
  • Obraz może być usunięty, jeżeli nie jest powiązany z żadnym HEAD z git (na przykład, ponieważ odpowiedni HEAD został usunięty) i nie jest używany w żadnym z manifestów w klastrze Kubernetes oraz w release'ach Helm.

Równoległa budowa obrazów (↓)

  • Wersja: v1.1
  • Terminy: styczeń-luty kwiecień*

Aktualna wersja werf buduje obrazy i artefakty opisane w werf.yaml, kolejno. Należy zrównoleglić proces budowy niezależnych etapów obrazów i artefaktów, a także zapewnić wygodny i informacyjny wyjściowy.

* Uwaga: termin został przesunięty z powodu wyższego priorytetu w realizacji rozproszonej budowy, która doda więcej możliwości skalowania poziomego oraz używania werf z GitHub Actions. Równoległa budowa jest następnym krokiem optymalizacji, dającym skalowalność pionową przy budowie jednego projektu.

Migracja na Helm 3 (↓)

  • Wersja: v1.2
  • Terminy: luty-marzec maj*

Objęto to przejściem na nową bazę kodu Helm 3 oraz sprawdzony, wygodny sposób migracji istniejących instalacji.

* Uwaga: przejście na Helm 3 nie doda istotnych możliwości do werf, ponieważ wszystkie kluczowe funkcje Helm 3 (3-way-merge i brak tillera) są już zaimplementowane w werf. Co więcej, werf ma dodatkowe możliwości poza wymienionymi. Jednak to przejście pozostaje w naszych planach i zostanie zrealizowane.

Jsonnet do opisu konfiguracji Kubernetes (↓)

  • Wersja: v1.2
  • Terminy: styczeń-luty, kwiecień-maj

Werf będzie wspierać opis konfiguracji dla Kubernetes w formacie Jsonnet. Przy tym werf pozostanie zgodny z Helm i będzie możliwość wyboru formatu opisu.

Powodem jest to, że szablony języka Go, według ocen wielu osób, mają wysoki próg wejścia, a zrozumiałość kodu tych szablonów również cierpi.

Rozważana jest również możliwość wdrożenia innych systemów opisu konfiguracji Kubernetes (na przykład Kustomize).

Praca wewnątrz Kubernetes (↓)

  • Wersja: v1.2
  • Terminy: kwiecień-maj, maj-czerwiec

Cel: zapewnienie budowy obrazów i dostarczania aplikacji za pomocą runnerów w Kubernetes. Tzn. budowa nowych obrazów, ich publikacja, oczyszczanie i wdrożenie mogą odbywać się bezpośrednio z podów Kubernetes.

Aby zrealizować tę możliwość, najpierw wymagana jest możliwość rozproszonego budowania obrazów (patrz punkt powyżej).

Wymagana jest również obsługa trybu pracy budowniczego bez serwera Docker (tj. budowa podobna do Kaniko lub budowa w userspace).

Werf będzie wspierać budowę w Kubernetes nie tylko za pomocą Dockerfile, ale także przy użyciu swojego budowniczego Stapel z inkrementalnymi przebudowami i Ansible.

Krok w stronę otwartego rozwoju

Kochamy naszą społeczność (GitHub, Telegram) i chcemy, aby coraz więcej osób pomagało uczynić werf lepszym, rozumieli, w jakim kierunku zmierzamy i uczestniczyli w rozwoju.

Niedawno podjęto decyzję o przejściu na GitHub project boards aby ujawnić proces pracy naszej zespołu. Teraz można zobaczyć najbliższe plany oraz obecne prace w następujących obszarach:

Wykonano dużą pracę z issue:

  • Usunięto nieaktualne.
  • Istniejące przekształcono do jednolitego formatu, z odpowiednią ilością szczegółów i detali.
  • Dodano nowe issue z pomysłami i propozycjami.

Jak włączyć wersję v1.1

Wersja jest obecnie dostępna w kanale 1.1 ea (na kanałach stable i rock-solid wydania pojawią się w miarę stabilizacji, jednak ea sama w sobie jest już wystarczająco stabilna do użycia, ponieważ przeszła przez kanały. alpha i beta). Aktywowane przez multiwerf w następujący sposób:

source $(multiwerf use 1.1 ea)
werf COMMAND ...

Podsumowanie

Nowa architektura magazynu etapów i optymalizacja pracy kompilatora dla Stapel i Dockerfile otwierają możliwości realizacji rozproszonych i równoległych kompilacji w werf. Te funkcje wkrótce pojawią się w tej samej wersji v1.1 i będą automatycznie dostępne poprzez mechanizm autoaktualizacji (dla użytkowników multiwerf).

W tej wersji dodano strategię tagowania na podstawie zawartości obrazów — tagowania opartego na zawartości, — która stała się strategią domyślną. Został również przetworzony log głównych komend: werf build, werf publish, werf deploy, werf dismiss, werf cleanup.

Następnym istotnym krokiem będzie dodanie rozproszonych kompilacji. Rozproszone kompilacje od czasu v1.0 stały się bardziej priorytetowym zadaniem niż kompilacje równoległe, ponieważ dodają więcej wartości do werf: wertykalne skalowanie kompilatorów oraz wsparcie efemerycznych kompilatorów w różnych systemach CI/CD, a także możliwość oficjalnego wsparcia GitHub Actions. Dlatego terminy realizacji kompilacji równoległych zostały przesunięte. Pracujemy jednak nad tym, aby jak najszybciej wdrożyć obie te możliwości.

Śledź nas na bieżąco! I nie zapomnij odwiedzić nas w GitHub, aby utworzyć zgłoszenie, znaleźć już istniejące i dodać głos, stworzyć PR lub po prostu obserwować rozwój projektu.

P.S.

Przeczytaj także na naszym blogu:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster