Poprzedni Następny

Jak wykorzystać Jenkinsa do szybszego dostarczania w projektach SDN?

Autorem tekstu jest Dariusz Grabowski
Starszy programista SDN w EXATEL

 


Rozwój projektów SDN (ang. Software-Defined Networking) jest wyzwaniem logistycznym. Jak wytwarzać oprogramowanie jednocześnie dla płaszczyzny danych i płaszczyzny sterowania? Jak zapewnić zgodność pomiędzy aplikacjami różnych warstw? Jak szybko znaleźć błędy w tych aplikacjach? Z pomocą przychodzi nam Jenkins, czyli szwajcarski scyzoryk do zadań specjalnych. Możemy go wykorzystać do pełnienia 2 ról: Strażnika i Dyrygenta. Strażnika, który będzie czuwał nad jakością oprogramowania. Dyrygenta, bo zapewni, że wszystkie testy uruchomią się w odpowiedniej kolejności i o odpowiednim czasie.

 

Taką współpracę Strażnika i Dyrygenta w przypadku wytwarzania oprogramowania nazywamy procesem ciągłej integracji i ciągłego wdrożenia. Są to procesy, dzięki którym przy użyciu specjalnych narzędzi jesteśmy w stanie szybciej dostarczać kod wysokiej jakości.

Ciągła integracja

Zacznijmy od wyjaśnienia czym jest owa integracja. Skrót CI pochodzi od ang. Continuous Integration. Gdy wielu programistów pracuje nad aplikacją pojawia się problem synchronizacji ich pracy. Ciągła integracja polega na częstym umieszczaniu fragmentów kodu w repozytorium. Następnie taki kod jest budowany, a dalej uruchamiane są testy. W przypadku błędu programista szybko dostaje informacje zwrotną. Najczęściej proces ten kontrolowany jest przez serwer ciągłej integracji. Gdy integracja odbywa się kilka razy dziennie ogranicza to liczbę błędów i koszt związany z ich odnalezieniem.

 

Ciągłe dostarczanie

Inaczej Continuous Delivery (CD). Po fazie integracji i przetestowaniu programu może nastąpić automatyczna faza dostarczenia. Polega ona na przygotowaniu aplikacji do instalacji, spakowaniu i umieszczeniu w centralnym repozytorium. Dzięki takiemu podejściu zespół deweloperski może regularnie przesyłać najnowszą wersję aplikacji do innych zespołów w firmie. Na przykład zespół wytwarzający oprogramowanie kontrolera SDN może wykorzystać przygotowaną aplikację z urządzenia sieciowego. Z jej użyciem może przeprowadzić testy zgodności interfejsów lub przepływu danych. W ten sposób każda dostarczona aplikacja może być wykorzystana jako część większego systemu.

Ciągłe wdrażanie w SDN

Continuous Deployment (CD). Dzięki zastosowaniu ciągłego wdrożenia aplikacja, po fazie automatycznych testów i przygotowaniu do instalacji, może zostać automatycznie zainstalowana na serwerze/urządzeniu produkcyjnym. Realizacja CD jest trudna w przypadku urządzeń sieciowych w warstwie danych. Ich interfejs często wymusza fizyczny dostęp do przeprowadzenia aktualizacji, a gdy urządzenia rozsiane są po całym kraju, może być to logistyczne wyzwanie. Z drugiej strony zachodzi konieczność przestawienia urządzenia w tryb utrzymania. Nie może wtedy świadczyć usług i ruch sieciowy musi zostać przełączony na inną ścieżkę

Dużo łatwiej zrealizować to w kontekście kontrolera SDN, W szczególności, gdy jego funkcjonalność realizowana jest przez klaster aplikacji. W takim przypadku możliwe jest aktualizowanie po kolei każdego węzła w klastrze, aż wszystkie osiągną najnowszą wersję oprogramowania. Takie rozwiązanie nie zaburza ciągłości pracy kontrolera.

Przyjrzyjmy się teraz czym jest Jenkins i jak możemy go wykorzystać do ciągłej integracji.

Czym jest Jenkins?

Jenkins jest aplikacją do automatyzacji wytwarzania oprogramowania. W roli Dyrygenta: wykrywa zmiany w repozytorium, uruchamia budowanie aplikacji i wyzwala przeprowadzenie testów. W roli Strażnika jakości: sprawdza pokrycie kodu testami, analizuje pod kątem błędów budowania i generuje raporty z przeprowadzonych testów.

Aby łatwiej zarządzać tymi wszystkimi funkcjonalnościami, możemy w Jenkinsie tworzyć zadania (ang. job). Job realizuje proces ciągłej integracji dla pojedynczej aplikacji. Zadania najczęściej przyjmują postać potoków (ang. pipeline), czyli następujących po sobie etapów/zdarzeń. Przykład takiego potoku możemy zobaczyć na poniższym rysunku:

Skąd Jenkins ma wiedzieć w jaki sposób budować i testować naszą aplikację? W tym celu stosuje się Jenkinsfile – plik w języku Groovy o dość ograniczonej składni. Dla zbudowania powyższego potoku można użyć przykładowy kod:

Jak łatwo się domyśleć każda z zielonych kropek w pipeline odzwierciedlona jest poprzez sekcje stage. W ramach każdej z nich występuje steps, czyli lista kroków (poleceń) do wykonania w celu zrealizowania danego etapu. W celu pełnego poznania składni Jenkins pipeline odsyłam na stronę dokumentacji.

Potok ciągłej integracji dla projektów SDN

Nasuwa się pytanie: dlaczego ciągła integracja w projektach SDN jest wyzwaniem? Mamy tutaj do czynienia z dwiema wpływającymi na siebie warstwami: sterowania i danych. Urządzenia działające w poszczególnych warstwach wytwarzane są często w zupełnie innych technologiach. Charakterystyka ich działania jak i wymagania wydajnościowe również się różnią. Konfigurację urządzeń sieciowych z użyciem kontrolera przeprowadza się “od czasu do czasu” natomiast wydajny przepływ danych jest wymaganiem ciągłym.

Potok ciągłej integracji dla projektu SDN może przybierać różne formy. Zaprezentowane tutaj podejście to raczej pomysł jeden z wielu, a nie jedyne słuszne podejście. Zachęcam do eksperymentowania i dopasowywania potoku do wymagań w konkretnym projekcie.

Jednym z możliwości wytwarzania oprogramowania dla urządzeń sieciowych jest użycie kontenerów. Dzięki temu uzyskujemy powszechnie znany interfejs, który jest niezależny od technologii użytej do napisania samej aplikacji. Nasz Dyrygent Jenkins obserwuje repozytorium kodu w poszukiwaniu zmian (nowych commitów). Gdy je wykryje, uruchamia proces budowania. Obraz zbudowanego kontenera po podstawowym przetestowaniu (ciągła integracja) może zostać przesłany do centralnego repozytorium binariów (ciągłe dostarczanie).

Warto nadmienić, że w przypadku oprogramowania SDN nie ma mowy o testach manualnych. Wszystkie one muszą być realizowane z użyciem specjalistycznego oprogramowania jak generatory ruchu sieciowego czy środowiska symulacyjne. Uruchomienie testów integracyjnych urządzenia sieciowego (rysunek niżej) będzie zatem polegać na przygotowaniu środowiska testowego, w tym pobranie kontenerów z oprogramowaniem. Następnie uruchamiane są właściwe skrypty testowe. Na zakończenie generowany jest raport i następuje czyszczenie środowiska testowego. Owe czyszczenie zapewnia, że dany przebieg testów nie wpłynie na kolejny, uruchomiony na tej samej maszynie.

Gdy aplikacja urządzenia sieciowego zostanie odpowiednio sprawdzona, przychodzi czas na testy z kontrolerem. W tym przypadku konieczne jest jak najwierniejsze odzwierciedlenie rzeczywistego środowiska. Dlatego też stosuje się złożone topologie urządzeń sieciowych. Owe topologie można stworzyć z użyciem maszyn wirtualnych. Do automatycznego tworzenia i konfigurowania wielu jednostek warto użyć oprogramowania Terraform lub podobnego, dzięki któremu opiszemy wszystkie ustawienia topologii jako kod.

Niestety uruchomienie takiego środowiska symulacyjnego jest czasochłonne. Jak można rozwiązać ten problem? Wystarczy uruchomić środowisko raz, a przy każdym kolejnym teście jedynie przywrócić pożądaną konfigurację. Dzięki temu programiści i testerzy szybciej otrzymają informację zwrotną z testów, jeśli zostanie wykryty błąd. Przykład takiego potoku na grafice poniżej:

Zarządzanie jakością

Zarządzanie jakością to praca dla Jenkinsa – Strażnika. W każdym momencie trwania projektu dobrze mieć przegląd stanu całego systemu lub aplikacji. Czym jest owa jakość? To wszystkie metryki, które stanowią o tym czy kod aplikacji spełnia standardy kodowania. Ważny jest nie tylko bieżący stan, ale też trend, to jest czy jakość poprawia się wraz z zaawansowaniem projektu. Przykładowe metryki, które można śledzić z użyciem Jenkinsa to:

  • pokrycie kodu testami
  • błędy przechwycone przez kompilator
  • wyniki statycznej analizy kodu
  • zbiorcze wyniki testów
  • zgodność z przyjętym formatowaniem kodu
  • i wiele, wiele więcej

Interfejs graficzny Jenkinsa pozwala nam na wyświetlanie tych metryk za pomocą wykresów tak jak na rysunku poniżej.

Podsumowanie

W tym artykule opisałem czym jest proces ciągłej integracji i ciągłego dostarczania oprogramowania. Opisałem wyzwania związane z implementacją takiego procesu w projektach SDN. Podałem też przykładowe potoki służące do realizacji CI/CD w kontekście wytwarzania i testowania aplikacji urządzeń sieciowych i kontrolera. Dlaczego warto stosować to podejście? Jest co najmniej kilka powodów. Dzięki częstej integracji ew. wprowadzone błędy w oprogramowaniu dużo łatwiej wykryć – szybciej informacja zwrotna trafia do programistów. Kolejna kwestia to regularnie dostarczane aplikacji w kontenerach. Dzięki temu mogą być często testowane w otoczeniu całego systemu. To pozwala na szybsze “dowożenie” pełnej funkcjonalności dla końcowego użytkownika. Z użyciem Jenkinsa możemy też stale kontrolować jakość oprogramowania dla całego projektu. To nie tylko narzędzie dla zespołów deweloperskich, ale też dla innych interesariuszy. Warto to narzędzie przetestować i krok po kroku automatyzować kolejne obszary projektu.

 

***

O autorze

Darek od kilkunastu lat zajmuje się programowaniem. Jest miłośnikiem wszelkiego rodzaju automatyzacji oraz prawdziwym pasjonatem Jenkinsa. Prywatnie prowadzi bloga Szkoła Jenkinsa. Jest także autorem darmowego e-booka „Top 10 wtyczek do Jenkinsa, które ułatwią Ci pracę”.

 

Przycisk kierujący na stronę poświęconą programom SDN EXATEL
Przycisk kierujący na stronę poświęconą rekrutacjom w EXATEL

Podobne