Close

Wprowadzenie do pipeline'ów ciągłego dostarczania

Zobacz, jak zautomatyzowane kompilacje, testy i wdrożenia tworzą wspólny łańcuch w przepływie pracy jednego wydania.

Zdjęcie portretowe Juni Mukherjee
Juni Mukherjee

Przedstawicielka programistów


Czym jest pipeline ciągłego dostarczania?


Pipeline ciągłego dostarczania jest serią zautomatyzowanych procesów dostarczania nowego oprogramowania. Stanowi on ucieleśnienie paradygmatu ciągłości, w którym zautomatyzowane kompilacje, testy i wdrożenia są skoordynowane w jeden przepływ pracy wydawania. Krótko mówiąc, pipeline CD jest zbiorem etapów, przez jakie przechodzą wprowadzane zmiany kodu, aby trafić do środowiska produkcyjnego.

Pipeline ciągłego dostarczania, w zależności od potrzeb biznesowych, dostarcza często i w przewidywalny sposób produkty wysokiej jakości kolejno ze środowiska testowego do przejściowego, a następnie produkcyjnego w zautomatyzowany sposób.

Na początek skupmy się na trzech pojęciach: jakości, częstotliwości i przewidywalności.

Kładziemy nacisk na jakość, aby podkreślić, że zwiększenie szybkości kosztem jakości nie wchodzi w grę. Firma nie chce, byśmy opracowali pipeline, który będzie skutkował błyskawicznym wdrażaniem do środowiska produkcyjnego wadliwego kodu. Omówimy zasady przesuwania testów na wcześniejsze etapy procesu oraz „DevSecOps”, a także sposoby uwzględnienia zagadnień związanych z jakością i bezpieczeństwem we wcześniejszych fazach cyklu tworzenia oprogramowania (SDLC). Położy to kres wszelkim wątpliwościom co do ryzyka, jakie pipeline'y ciągłego dostarczania stwarzają dla firm.

Częstotliwość wskazuje, że pipeline'y wykonują czynności mające na celu wydanie funkcji w dowolnej chwili, ponieważ są zaprogramowane do wyzwalania w miarę dodawania commitów do bazy kodu. Gdy w pipelinie pojawi się produkt o minimalnej wymaganej funkcjonalności, pipeline może wykonać proces tyle razy ile potrzeba, z zachowaniem okresowych kosztów utrzymania. Takie zautomatyzowane podejście umożliwia skalowanie bez powodowania wypalenia wśród członków zespołu. Umożliwia zespołom również wprowadzanie drobnych ulepszeń przyrostowych w produktach bez obaw o poważną awarię w środowisku produkcyjnym.

Poznaj rozwiązanie

Tworzenie i obsługa oprogramowania za pomocą Open DevOps

Materiały pokrewne

Czym jest pipeline DevOps?

Choć może to zabrzmieć jak pusty frazes, „błądzić jest rzeczą ludzką”. W trakcie ręcznych wydań zespoły przygotowują się na prawdziwe uderzenie, ponieważ te procesy są kruche. Przewidywalność oznacza, że wydania realizowane w toku pipeline'ów ciągłego dostarczania mają charakter deterministyczny. Pipeline'y są infrastrukturą programowalną, więc zespoły mogą się spodziewać, że za każdym razem będą one działały w pożądany sposób. Naturalnie wypadki mogą się zdarzyć, ponieważ nie ma oprogramowania całkowicie pozbawionego błędów. Jednak pipeline'y są wykładniczo lepsze niż ręczne procesy wydawania tak podatne na błędy, gdyż, w przeciwieństwie do ludzi, pipeline'y nie odczuwają stresu w obliczu napiętych terminów.

Pipeline'y mają bramki programowe, które automatycznie przekazują dalej lub odrzucają wersjonowane artefakty. Jeśli protokół wydania nie jest uznawany, bramki programowe pozostają zamknięte, a pipeline zostaje przerwany. Następuje wygenerowanie alertów, a powiadomienia są wysyłane na listę dystrybucyjną zawierającą członków zespołu, którzy mogli potencjalnie uszkodzić pipeline.

A oto, jak działa pipeline CD: commit lub niewielka partia przyrostowa commitów trafia do środowiska produkcyjnego za każdym razem, gdy pipeline zostanie pomyślnie zrealizowany. Ostatecznie zespoły dostarczają funkcje, a w końcu całe produkty w sposób bezpieczny i możliwy do skontrolowania.

Fazy pipeline'u ciągłego dostarczania


Architektura produktu przechodzącego przez pipeline jest kluczowym czynnikiem determinującym anatomię pipeline'u ciągłego dostarczania. Wysoce zależna architektura produktu generuje skomplikowany graficzny wzór pipeline'u, w którym różne pipeline'y mogą się zaplątać, zanim ostatecznie trafią do środowiska produkcyjnego.

Architektura produktu wpływa również na różne fazy pipeline'u i artefakty produkowane w każdej fazie. Przyjrzyjmy się czterem najważniejszym fazom ciągłego dostarczania:

  1. Faza komponentów
  2. Faza podsystemów
  3. Faza systemowa
  4. Faza produkcyjna

Zarysowane poniżej koncepcje mają zastosowanie nawet wówczas, gdy przewidujesz w swojej organizacji mniej lub więcej niż te cztery fazy.

Powszechnie panuje błędne przekonanie, że fazy te manifestują się w sposób fizyczny w Twoim pipelinie. Niekoniecznie tak jest. Są to fazy logiczne, które mogą przekładać się na kamienie milowe wyznaczane przez takie środowiska, jak testowe, przejściowe czy produkcyjne. Przykładowo komponenty i podsystemy można kompilować, testować i wdrażać w środowisku testowym. Podsystemy lub systemy można komponować, testować i wdrażać w środowisku przejściowym. Z kolei podsystemy lub systemy można przekazywać do środowiska produkcyjnego w ramach frazy produkcyjnej.

Koszt usterek jest niewielki, jeśli zostaną wykryte w środowisku testowym, średni w przypadku ich wykrycia w środowisku przejściowym, a w środowisku produkcyjnym jest on wysoki. „Przesunięcie w lewo” oznacza przesunięcie sprawdzania poprawności na wcześniejsze etapy pipeline'u. Obecnie bramka między środowiskiem testowym a przejściowym ma wbudowane znacznie więcej technik obronnych, dzięki czemu środowisko przejściowe nie wygląda już jak miejsce zbrodni.

Dawniej zagadnienia bezpieczeństwa informatycznego poruszano na końcu cyklu tworzenia oprogramowania, gdy odrzucone wydania mogły stwarzać zagrożenie dla cyberbezpieczeństwa firmy. Choć intencje były szlachetne, takie podejście prowadziło do frustracji i opóźnień. Podejście „DevSecOps” zakłada wbudowanie zabezpieczeń w produkty już na etapie projektowania, zamiast wysyłania gotowego (prawdopodobnie słabo zabezpieczonego) produktu do oceny.

Przyjrzyjmy się bliżej, w jaki sposób można zastosować podejścia „przesunięcia w lewo” oraz „DevSecOps” w przepływie pracy opartym na ciągłym dostarczaniu. W kolejnych sekcjach omówimy szczegółowo każdą fazę.

Faza komponentów w modelu ciągłego dostarczania


Najpierw w ramach pipeline'u są kompilowane komponenty — najmniejsze nadające się do dystrybucji i testowania jednostki produktu. Przykładowo bibliotekę zbudowaną przez pipeline można nazwać komponentem. Certyfikacja komponentu może odbywać się między innymi poprzez przeglądy kodu, testy jednostkowe i przy użyciu statycznych analizatorów kodu.

Przeglądy kodu są dla zespołów ważnym elementem pozwalającym wypracować wspólną wizję funkcji, testów oraz infrastruktury potrzebnych do udostępnienia produktu. Druga para oczu potrafi zdziałać cuda. Z biegiem lat możemy się uodpornić na nieprawidłowy kod na tyle, że przestaniemy dostrzegać jego niedoskonałości. Świeże perspektywy mogą wymusić na nas ponowne przyjrzenie się tym słabościom i autentyczne ich przepracowanie, jeśli zajdzie taka potrzeba.

Testy jednostkowe są niemal zawsze pierwszym zestawem testów oprogramowania, którym poddajemy nasz kod. Nie obejmują bazy danych ani sieci. Pokrycie kodu to procent kodu poddany testom jednostkowym. Dostępnych jest wiele sposobów pomiaru pokrycia, na przykład pokrycia linii kodu, pokrycia klas i pokrycia metod.

Choć dobrze jest mieć dobre pokrycie kodu pozwalające ograniczyć refaktoryzację, wyznaczenie sobie za cel wysokiego pokrycia może być zgubne w skutkach. Wbrew intuicji, niektóre zespoły mogące poszczycić się wysokim pokryciem kodu mają więcej awarii niż zespoły, w których takie pokrycie jest niskie. Pamiętaj również, że wartościami pokrycia można łatwo manipulować. Działając pod dużą presją, zwłaszcza w trakcie przeglądów wydajności, programiści mogą sięgać do nieuczciwych praktyk, aby zwiększyć pokrycie kodu. Nie będziemy się tu jednak zajmować tym szczegółowo.

Statyczna analiza kodu wykrywa problemy w kodzie bez jego wykonywania. Jest to niedrogi sposób wykrywania problemów. Podobnie jak w przypadku testów jednostkowych, te testy wykonywane są na kodzie źródłowym, a czas ich wykonania jest krótki. Analizatory statyczne wykrywają potencjalne wycieki z pamięci, a także wskaźniki jakości kodu, takie jak złożoność cykliczna i powielony kod. W tej fazie statyczne testy zabezpieczeń (SAST) są sprawdzonym sposobem wykrywania luk w zabezpieczeniach.

Zdefiniuj wskaźniki regulujące działanie bramek programowych i określające zasady przekazywania kodu między fazą komponentów a fazą podsystemów.

Faza podsystemów ciągłego dostarczania


Luźno sprzężone komponenty tworzą podsystemy — najmniejsze jednostki nadające się do wdrożenia i uruchomienia. Przykładowo podsystemem jest serwer. Przykładem podsystemu jest również mikrousługa działająca w kontenerze. W przeciwieństwie do komponentów, podsystemy mogą być wdrażane i weryfikowane w kontekście przypadków użycia klientów.

Podsystemami są nie tylko interfejs użytkownika Node.js czy warstwa API Java, ale także bazy danych. W niektórych organizacjach systemy zarządzania relacyjnymi bazami danych (RDBMS) są obsługiwane ręcznie, choć pojawiły się już narzędzia nowej generacji, które automatyzują zarządzanie zmianami baz danych i pomyślnie realizują ich ciągłe dostarczanie. Pipeline'y ciągłego dostarczania zawierające bazy danych NoSQL są łatwiejsze do wdrożenia niż systemu RDBMS.

Podsystemy mogą być wdrażane i certyfikowane na podstawie testów funkcjonalnych, wydajnościowych i testów zabezpieczeń. Przyjrzyjmy się, w jaki sposób każdy z tych rodzajów testów przyczynia się do weryfikacji produktu.

Testy funkcjonalne obejmują wszystkie przypadki użycia klienta, które uwzględniają internacjonalizację (I18N), lokalizację (L10N), jakość danych, ułatwienia dostępu, negatywne scenariusze itp. Testy te pozwalają zyskać pewność, że produkt działa zgodnie z oczekiwaniami klientów, spełnia zasady inkluzywności i dobrze służy rynkowi, na potrzeby którego został utworzony.

Wartości referencyjne wydajności musisz ustalić z product ownerami. Włącz testy wydajności do pipeline'u i na podstawie wartości referencyjnych określ progi zaliczenia i niezaliczenia pipeline'ów. Powszechnym mitem jest twierdzenie, że nie trzeba integrować testów wydajności z pipeline'ami ciągłego dostarczania, jednak stanowi to naruszenie paradygmatu ciągłości.

Ostatnio w kilku dużych organizacjach doszło do takich naruszeń, a zagrożenia dla cyberbezpieczeństwa nigdy nie były tak poważne. Musimy się zabezpieczyć i zadbać o to, aby w zabezpieczeniach naszych produktów — tak w pisanym przez nas kodzie, jak i w importowanych do naszego kodu bibliotekach innych podmiotów — nie było żadnych luk. Faktem jest, że w oprogramowaniu open source wykryto poważne naruszenia bezpieczeństwa, a my powinniśmy korzystać z narzędzi i technik pozwalających oznaczyć te błędy i wymusić przerwanie pipeline'u. Sprawdzonym sposobem wykrywania luk w zabezpieczeniach są dynamiczne testy zabezpieczeń (DAST).

Na poniższej ilustracji przedstawiono przepływ pracy omówiony w fazach komponentów i podsystemów. W celu zoptymalizowania całkowitego czasu wykonania pipeline'u i uzyskania szybkiej informacji zwrotnej niezależne kroki można realizować równolegle.

A) Certyfikacja komponentów i/lub podsystemów w środowisku testowym
Faza podsystemów w ciągłym dostarczaniu

Faza systemowa ciągłego dostarczania


W pipelinie można uwzględnić instrukcję, aby po spełnieniu przez podsystemy wymagań funkcjonalnych, wydajnościowych i związanych z bezpieczeństwem, luźno powiązane podsystemy zostały połączone w jeden system przygotowany do wydania jako całość. Oznacza to, że najszybszy zespół może pracować w tempie najwolniejszego. To z kolei przypomina mi stare powiedzenie, że o wytrzymałości łańcucha decyduje jego najsłabsze ogniwo.

Odradzamy korzystanie z tego negatywnego wzorca kompozycyjnego, w którym podsystemy składa się w jeden system, który ma zostać wydany jako całość. W tym negatywnym wzorcu powodzenie podsystemów ściśle zależy od innych podsystemów. Zainwestowanie w artefakty z możliwością niezależnego wdrażania pozwoli uniknąć takiego negatywnego wzorca.

W sytuacjach, gdy systemy muszą być zweryfikowane jako całość, do ich certyfikacji można wykorzystać testy integracyjne, wydajnościowe i zabezpieczeń. W przeciwieństwie do fazy podsystemowej w tej fazie testów nie używa się symulacji ani stubów. Ważne jest również skoncentrowanie się na testowaniu przede wszystkim interfejsów oraz sieci.

Poniższa ilustracja przedstawia podsumowanie przepływu pracy w fazie systemowej w razie konieczności składania podsystemów w całość. Nawet jeśli jesteś w stanie wdrażać swoje podsystemy w środowisku produkcyjnym, poniższa ilustracja pomoże Ci wyznaczyć bramki programowe potrzebne do przekazania kodu z tej fazy do kolejnej.

Pipeline może automatycznie wysyłać wnioski o zmiany w celu pozostawienia śladu audytowego. Większość organizacji wykorzystuje ten przepływ pracy do zmian standardowych, co oznacza zaplanowane wydania. Przepływ ten powinno się również stosować w przypadku zmian awaryjnych lub nieplanowanych wydań, choć niektóre zespoły idą tutaj na skróty. Zwróć uwagę, jak wniosek o zmianę zostaje zamknięty automatycznie przez pipeline ciągłego dostarczania, gdy błędy wymuszą jego przerwanie. Pozwala to uniknąć wniosków o zmianę porzuconych w środku przepływu pracy w ramach pipeline'u.

Na poniższej ilustracji przedstawiono przepływ pracy omówiony w fazie systemowej ciągłego dostarczania. Pamiętaj, że niektóre kroki mogą uwzględniać ludzką ingerencję. Takie ręczne kroki mogą być wykonywane w ramach ręcznych bramek w pipelinie. Po utworzeniu schematu całości wizualizacja pipeline'u przypomina w dużym stopniu mapę strumienia wartości wydań Twojego produktu.

B) CERTYFIKACJA PODSYSTEMÓW I/LUB SYSTEMU W ŚRODOWISKU PRZEJŚCIOWYM
Faza systemowa w ciągłym dostarczaniu

Po poświadczeniu złożonego systemu nie wprowadzaj dalszych zmian w złożeniu, tylko przekaż je do środowiska produkcyjnego.

Faza produkcyjna ciągłego dostarczania


Bez względu na to, czy podsystemy można wdrażać niezależnie czy trzeba je składać w system, w tej fazie finalnej do środowiska produkcyjnego wdrażane są wersjonowane artefakty.

Wdrażanie bez przestojów pozwala uniknąć przestojów po stronie klientów i powinno się je praktykować przy wdrażaniu ze środowiska testowego do przejściowego, a następnie do produkcyjnego. Wdrożenia typu blue-green są popularną techniką wdrażania bez przestojów, w której nowe fragmenty wdraża się w małym wycinku populacji (nazywanym „green”), podczas gdy pozostająca w błogiej nieświadomości większość populacji „blue” korzysta ze starych fragmentów. Jeśli pojawią się problemy, wszystkich przywraca się do stanu „blue” i w efekcie liczba poszkodowanych klientów jest niewielka (jeśli w ogóle tacy się pojawią). Jeśli zaś w grupie „green” wszystko będzie jak należy, pozostałą część populacji powoli przenosi się ze stanu „blue” do „green”.

Obserwuję jednak, że w niektórych organizacjach nadużywa się ręcznych bramek. Wymagają one od zespołów uzyskania ręcznego zatwierdzenia w trakcie spotkania przy tablicy zatwierdzania zmian. Najczęstszym powodem jest błędna interpretacja podziału obowiązków i wydzielenia obaw. Jeden dział przekazuje materiał drugiemu, aby uzyskać zgodę na kolejny krok. Obserwuję również, że niektórych zatwierdzających korzystających z tablic zatwierdzania zmian cechuje zaledwie powierzchowna znajomość zmian trafiających do produkcji, przez co proces ręcznego zatwierdzania staje się powolny i żmudny.

To dobry moment, aby przypomnieć różnicę między ciągłym dostarczaniem a ciągłym wdrażaniem. Ciągłe dostarczanie dopuszcza bramki ręczne, podczas gdy ciągłe wdrażanie — nie. Choć obydwa modele określa się skrótem CD, ciągłe wdrażanie wymaga większej dyscypliny oraz rygoru, ponieważ w pipelinie nie uwzględnia się ludzkiej ingerencji.

Istnieje różnica między przeniesieniem bitów a ich włączeniem. W środowisku produkcyjnym przeprowadza się testy smoke będące podzbiorem pakietów testów integracji, wydajności i zabezpieczeń. Po wykonaniu testów smoke bity zostają włączone, a produkt zostaje aktywowany u klientów.

Poniższy schemat ilustruje kroki przeprowadzone przez zespół w końcowej fazie ciągłego dostarczania.

C) CERTYFIKACJA PODSYSTEMÓW I/LUB SYSTEMU W ŚRODOWISKU PRODUKCYJNYM
Faza produkcyjna w ciągłym dostarczaniu

Ciągłe dostarczanie to nowy standard


Aby skutecznie realizować model ciągłego dostarczania lub ciągłego wdrażania, nieodzowne jest również stosowanie ciągłej integracji i ciągłego testowania. Mając solidne podstawy, osiągniesz sukces pod wszystkimi trzema względami, czyli jakości, dużej częstotliwości i przewidywalności.

Pipeline ciągłego dostarczania pomaga w przekształceniu Twoich pomysłów w produkty przez zastosowanie szeregu zrównoważonych eksperymentów. Jeśli uznasz, że pomysł nie jest tak dobry, jak się wydawało, możesz szybko przejść do lepszego pomysłu. Ponadto pipeline'y skracają średni czas rozstrzygania (MTTR) problemów w środowisku produkcyjnym, ograniczając tym samym przestoje po stronie klientów. Dzięki ciągłemu dostarczaniu zyskujesz produktywne zespoły i zadowolonych klientów, a komu na tym nie zależy?

Dowiedz się więcej w naszym samouczku dotyczącym ciągłego dostarczania.

Juni Mukherjee
Juni Mukherjee

Juni is a thought citizen in the DevSecOps space and has made deep investments in the field of Continuous Delivery. She has helped organizations build Continuous Delivery Pipelines, and would love to solve the problems that plague our industry today. She has authored a couple of books.


Udostępnij ten artykuł
Następny temat

Zalecane lektury

Dodaj te zasoby do zakładek, aby dowiedzieć się więcej na temat rodzajów zespołów DevOps lub otrzymywać aktualności na temat metodyki DevOps w Atlassian.

Ilustracja DevOps

Społeczność DevOps

Ilustracja DevOps

Przeczytaj blog

Ilustracja przedstawiająca mapę

Zacznij korzystać za darmo

Zapisz się do newslettera DevOps

Thank you for signing up