Skalowanie i optymalizacja CI/CD

Photo of author

By maciekx

Wzrost popularności CI/CD i wyzwania związane ze skalowaniem

Implementacja przepływu pracy CI/CD w procesie tworzenia aplikacji zyskuje na znaczeniu, lecz jednocześnie skalowanie i odpowiednia optymalizacja CI/CD stanowią poważne wyzwanie.

W niniejszym artykule przyjrzymy się temu wyzwaniu i szczegółowo przeanalizujemy, jak efektywnie skalować i optymalizować CI/CD. Zapraszam do lektury!

Obecnie proces tworzenia oprogramowania zazwyczaj angażuje zespoły składające się z wielu programistów. Każdy członek zespołu lub podzespół ma swoją określoną rolę w projekcie, rozwijając przydzieloną mu część kodu.

W rezultacie, na końcu projektu, mamy do czynienia z wieloma fragmentami kodu, które trzeba zintegrować. W zależności od indywidualnych metod pracy, zarządzanie tą integracją może pochłonąć znaczną ilość czasu.

CI/CD, czyli Continuous Integration (Ciągła Integracja) oraz Continuous Delivery/Deployment (Ciągłe Dostarczanie/Wdrażanie), stanowią rozwiązanie tego problemu, zapewniając płynne udostępnianie aktualizacji bez niepotrzebnych opóźnień i konfliktów. Przeanalizujmy ten proces krok po kroku.

Ciągła integracja

CI, czyli Continuous Integration, obejmuje zbiór praktyk mających na celu stałe publikowanie zmian w kodzie i dodawanie ich do wspólnej gałęzi projektu. Umożliwia to bieżące testowanie kodu i wprowadzanie poprawek oraz zmian w czasie rzeczywistym. Głównym celem jest przetestowanie każdego elementu poprzez stworzenie odpowiednich testów.

Takie podejście pozwala uniknąć sytuacji, w której wszystko jest sprawdzane naraz na samym końcu, oraz zapobiega pracy na zbyt wielu elementach jednocześnie. Przeprowadzanie testów jednostkowych jest niezwykle istotne, aby to zagwarantować. Dzięki temu łatwiej wykryć ewentualne błędy, zapewniając, że kod dobrze się kompiluje i nie powoduje regresji.

Ciągłe dostarczanie

Continuous Delivery (Ciągłe Dostarczanie) łączy ciągłą integrację i testowanie, które można spakować w kontenery i wprowadzić do środowiska produkcyjnego. Oznacza to, że gromadzi te fragmenty kodu i wykonane testy i wdraża je do środowiska docelowego za pomocą automatyzacji.

Nawet jeśli wymaga interwencji człowieka, proces ten zostaje zautomatyzowany, przenosząc wszystko, co zostało opracowane, „na antenę” w sposób zintegrowany i kompletny. W praktyce, dzięki ciągłemu dostarczaniu, nasza aplikacja jest gotowa do wdrożenia w środowisku produkcyjnym w dowolnym momencie.

Ciągłe wdrażanie

Mimo podobieństw, ciągłe dostarczanie i ciągłe wdrażanie różnią się od siebie. Chociaż ich celem jest wdrożenie aplikacji do produkcji, środki do osiągnięcia tego celu są odmienne. Kluczową różnicą między ciągłym dostarczaniem a ciągłym wdrażaniem jest etap weryfikacji.

Ciągłe wdrażanie umożliwia bezpośrednie wdrożenie każdej modyfikacji, która przejdzie przez różne etapy naszego potoku. W przypadku ciągłego dostarczania, niezbędny jest etap manualnej weryfikacji przez człowieka, zanim wdrożenie zostanie zainicjowane.

Skalowanie CI/CD

Wraz ze wzrostem liczby mikrousług, skalowanie CI/CD staje się nieuniknione. Zwiększona liczba mikroserwisów prowadzi do sytuacji, w której wiele potoków łączy się z jednym repozytorium git, co z kolei obciąża serwer CI i obniża jego wydajność.

Aby skutecznie skalować CI/CD, konieczne jest opracowanie ujednoliconego i zautomatyzowanego procesu rozwoju dla wszystkich zespołów. Zapewni to jakość dostaw od poszczególnych deweloperów i zespołów, a także ułatwi zarządzanie całym potokiem.

Skalowanie można osiągnąć poprzez zdefiniowanie procesu CI, który obejmuje wykonywanie testów jednostkowych i walidację jakości dostarczanego kodu.

Następnym krokiem jest proces tworzenia obrazów i ich wdrażania w środowiskach w sposób ciągły za pomocą CD, a następnie zdefiniowanie procesu tworzenia obrazów i ich wdrażania w środowisku produkcyjnym.

Kroki do skalowania CI/CD

Pierwszym etapem jest uzgodnienie potoku z architektami, przy udziale liderów zespołów. Następnie następuje mapowanie gałęzi Git na poszczególne środowiska (np. develop -> development, master -> homologacja i produkcja). Kolejnym krokiem jest uruchomienie zadania CI przy każdym żądaniu pull request i zadania CD przy każdej zmianie w mapowanych gałęziach.

Strumień zadań można utworzyć dla śledzenia zarówno CI, jak i CD.

Przepływ pracy CI rozwija się w 7 etapach:

  • Pobranie gałęzi źródłowej i docelowej dla danego pull request;
  • Sprawdzenie, czy scalanie nie zawiera konfliktów wymagających manualnego rozwiązania;
  • Uruchomienie testów jednostkowych;
  • Zbudowanie pakietu, aby zweryfikować jego integralność i poprawność kompilacji;
  • Weryfikacja jakości kodu;
  • Zwiększenie i zatwierdzenie wersji projektu do gałęzi źródłowej;
  • Powiadomienie repozytorium Git o sukcesie lub niepowodzeniu żądania pull request za pomocą Webhooka lub API Rest.

Przepływ zadań CD przebiega następująco:

  • Wskazana gałąź zostaje wyrejestrowana.
  • Artefakt jest budowany przy użyciu narzędzia odpowiedniego dla projektu.
  • Po utworzeniu artefaktu, projekty biblioteczne są wysyłane do Nexusa w celu przechowywania artefaktu, co kończy przepływ.

Realizowane są następujące działania:

Krok 1: Tworzony jest obraz Dockera dla wygenerowanego artefaktu, a wersja artefaktu jest stosowana do obrazu Dockera.

Krok 2: Obraz jest przesyłany do rejestru Dockera.

Krok 3: Wdrożenie następuje poprzez wdrożenie obrazu za pomocą Kubernetes.

W przypadku projektów aplikacji znajdujących się w środowisku zatwierdzania/produkcyjnym, należy wykonać kroki 1 i 2 opisane powyżej, a następnie:

  • Wdrożyć poprzez wdrażanie obrazów za pomocą Kubernetes w środowisku zatwierdzania;
  • Zadanie wstrzymuje się, oczekując na zatwierdzenie wdrożenia do produkcji;
  • Po zatwierdzeniu obraz jest promowany do produkcji;
  • W przeciwnym wypadku obraz jest wycofywany w środowisku zatwierdzania.

Optymalizacja CI/CD

CI/CD usprawnia cykl rozwoju aplikacji i rozwiązuje problemy związane z integracją nowego kodu i zwiększeniem częstotliwości dostarczania.

Poniżej przedstawiono metody dalszej optymalizacji wykorzystania CI/CD:

Priorytetowe naprawianie uszkodzonych kompilacji

W przypadku wystąpienia błędu w kompilacji, jej naprawa powinna stać się priorytetem zespołu. Jeśli nie można naprawić kompilacji w krótkim czasie, zespół musi podjąć decyzję o usunięciu kodu lub wyłączeniu flagi funkcji.

Celem naprawiania uszkodzonej kompilacji jest zapewnienie, że kompilacja zawsze będzie generować działający kod, który można potencjalnie wydać.

Częste i małe wdrożenia

Zasadniczo każde wdrożenie niesie ze sobą pewne ryzyko dla stabilności aplikacji. Dlatego dążymy do tego, aby wdrożenia nie były zbyt częste. Problem z tym podejściem polega na tym, że kumulujemy zbyt wiele zmian. Jeśli którakolwiek z tych zmian zawiedzie, może to wymusić wycofanie także tych zmian, które działały prawidłowo.

Zastosuj wzorzec dusiciela i podziel złożone zmiany na mniejsze i prostsze. Częstsze wdrażanie mniejszych partii kodu zmniejsza ryzyko wystąpienia problemów.

Automatyzacja testów QA w celu ograniczenia ryzyka

Prawdopodobnie wszyscy doświadczyliśmy sytuacji typu „działało u mnie na lokalnym komputerze”, ponieważ środowiska lokalne programistów często się różnią. Różnice między środowiskiem lokalnym a środowiskiem produkcyjnym mogą być znaczące. Optymalizację CI/CD można osiągnąć poprzez automatyzację testów QA, takich jak testy przeglądarki, co zmniejszy ryzyko pojawienia się błędów w działającej aplikacji.

Zaufanie do automatycznych testów

Aby zweryfikować poprawność kodu dodawanego przez programistów, CI polega na zautomatyzowanym i niezawodnym zestawie testów. Pierwszym testem, który musi przejść kod, jest sprawdzenie, czy w ogóle się kompiluje. Następnie można dodać tyle testów, ile uznamy za konieczne.

Ile testów należy uwzględnić? Decydując, trzeba pamiętać, że celem CI jest dostarczenie informacji zwrotnej tak szybko, jak to możliwe. Jeśli programista musi czekać godzinę na opinię, proces nie będzie efektywny. Zawsze będziemy coś przeoczać, ale gdy błąd zostanie zauważony w środowisku produkcyjnym, należy utworzyć dla niego przypadek testowy i dołączyć go do pętli CI.

Stałe uwzględnianie bezpieczeństwa

Bezpieczeństwo narzędzi CI/CD jest kluczowe, ponieważ integrują się one z istniejącymi konfiguracjami i środowiskami. CI/CD wymaga programowego uruchamiania wszystkich narzędzi do testowania bezpieczeństwa, a wyniki są agregowane w jednym miejscu. Warto poszukać narzędzi posiadających API do automatycznych audytów szyfrowania.

Korzyści ze skalowania i optymalizacji CI/CD

Oprócz zwiększenia efektywności zespołów programistycznych, skalowanie i optymalizacja CI/CD przynoszą szereg innych korzyści, takich jak:

Zmniejszone koszty ogólne

Czas programistów jest cenny, ale co z czasem poświęconym na ręczne wdrażanie kodu czy plików? Automatyzacja znacznej części przepływu pracy pozwala zaoszczędzić czas na wykonywanie pracochłonnych zadań manualnych, co wszyscy z pewnością docenią. Zautomatyzowane testowanie pozwala również na wykrycie problemów na wcześniejszym etapie, a nie dopiero w fazie kontroli jakości lub produkcji. Więcej błędów naprawionych w krótszym czasie to wyraźna korzyść.

Dostarczanie z mniejszą liczbą błędów i mniejszym ryzykiem

Dzięki częstemu publikowaniu małych zmian, błędy są wykrywane na znacznie wcześniejszym etapie procesu tworzenia. Wdrażanie automatycznych testów na wszystkich etapach rozwoju eliminuje ryzyko wprowadzenia wadliwego kodu do następnego etapu, a ewentualne wycofanie małych zmian staje się łatwiejsze.

Szybsza reakcja na zmiany rynkowe

Warunki rynkowe nieustannie się zmieniają. Załóżmy, że odkrywasz, że nowy produkt traci przychody lub że więcej klientów odwiedza Twoją stronę za pomocą smartfonów niż laptopów. Zoptymalizowanie procesu ciągłego dostarczania umożliwi szybsze wdrożenie koniecznych zmian.

Zwiększone zaufanie

Solidny zestaw testów w zoptymalizowanym procesie CI/CD znacznie zwiększa pewność, że nie wystąpią żadne błędy. Przejrzystość procesu i edukacja zespołu oraz klientów przekłada się na zwiększone zaufanie do całego zespołu programistycznego.

Słowa końcowe

CI/CD przyspiesza integrację i dostarczanie oprogramowania. Kluczowe jest jednak skalowanie i optymalizacja tego procesu, aby uniknąć sytuacji, w której zwiększona złożoność doprowadzi do spadku produktywności.

Warto również zapoznać się z najlepszymi narzędziami CI.


newsblog.pl