Czym jest Jenkins i co może dla Ciebie zrobić?
Aktualnie aplikacje wdrażane są nawet kilka razy w ciągu godziny! Jak możesz to osiągnąć? Przecież często są to złożone systemy wymagające pracy wielu osób. Odpowiedź zawiera się w 3 magicznych skrótach: CI, CD i CD. Co oznaczają te skróty i jak możemy je wdrożyć z użyciem Jenkins?
Dzisiejszy sposób tworzenia oprogramowania mocno różni się od tego sprzed 10 lat. Niektórzy brodaci programiści jeszcze to pamiętają. Inżynierowie przez wiele miesięcy pracowali, każdy nad swoją aplikacją. Następnie, po wielotygodniowym okresie integracji całego systemu i intensywnych testach, aplikacja była dostarczana do klienta. W najgorszym przypadku okazywało się, że klient oczekiwał czegoś zupełnie innego…
Aktualnie aplikacje wdrażane są na serwer produkcyjny nawet po każdej małej zmianie programisty. Aby to było możliwe stosuje się systemy ciągłej integracji/ciągłego wdrożenia. Czym zatem jest ciągła integracja? I jak można ją wdrożyć z użyciem Jenkins?
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 system ciągłej integracji. Gdy integracja odbywa się kilka razy dziennie ogranicza to ilość 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 działów w firmie. Na przykład dział marketingu może zaprezentować taki program na spotkaniu z klientem. Inne zespoły mogą wykorzystać też dostarczoną aplikację jako część większego systemu.
Ciągłe wdrażanie
Continuous Deployment (CD). Ten koncept dotyczy szczególnie (choć nie tylko) aplikacji webowych. 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 produkcyjnym. Dzięki temu np. klienci sklepu internetowego w ciągu tego samego dnia mogą oglądać kilka różnych wersji witryny.
Przyjrzyjmy się teraz czym jest Jenkins i jak możemy go wykorzystać do ciągłej integracji.
Architektura Jenkinsa
Z użyciem Jenkinsa można zdefiniować zadania (ang. job) opisujące w jaki sposób skompilować, przetestować i wdrożyć aplikację. Uruchamianie tych zadań (build) odbywa się w sposób automatyczny. Dzięki tej automatyce, raz skonfigurowany potok zdarzeń, zawsze wykonuje się tak samo. Zajrzyjmy teraz nieco pod maskę.
Jenkins został stworzony w taki sposób aby łatwo rozszerzać jego możliwości. Dotyczy to także sprzętu na którym działa. Zastosowano tutaj architekturę master-slave, to znaczy, że jeden centralny serwer zarządza działaniem podległych mu maszyn.
Instancję slave nazywamy Agentem. Uruchamiana jest na dowolnym urządzeniu – serwer, maszyna wirtualna lub nawet minikomputer taki jak RaspberryPi. Na maszynie może być dowolny system operacyjny: Linux, Windows lub środowisko do uruchamiania kontenerów Dockera. Agent odpowiada za wykonywanie zadań. To tutaj przeprowadzana jest kompilacja, uruchamiane są testy, pakowanie aplikacji itp.
Instancję master nazywamy Kontrolerem. Kontroler dla każdego podłączonego Agenta sprawdza status połączenia sieciowego, dostępne miejsce na dysku, ilość RAM i inne niezbędne statystyki. Aplikacja deleguje zadania dla agentów. Pilnuje aby praca do wykonania była równo rozdzielona i aby żadna z maszyn nie była przeciążona. Kontroler odpowiada też za obsługę interfejsu użytkownika, przechowywanie konfiguracji oraz kont użytkowników. Może też archiwizować pliki powstające w procesie wykonywania zadań, takie jak raporty z przeprowadzonych testów. Proces instalacji kontrolera opisałem w tym artykule.
Taka architektura daje nam dużą elastyczność. Możemy zwiększać zasoby sprzętowe wraz ze zwiększającymi się potrzebami. Gdy kolejka zadań do wykonania staje się coraz dłuższa, i coraz dłużej czekamy na ich wykonanie, możemy w prosty sposób dodać kolejny serwer jako Agent. Kontroler natychmiast zacznie delegować mu zadania co skróci średni czas oczekiwania.
Zadanie Jenkins (Job)
Jak przygotować zadanie w Jenkinsie? Aby to zrobić musimy opisać poszczególne kroki: budowanie, testowanie, wdrożenie. Każda aplikacja pisana jest w innej technologi i używa innych narzędzi. Dla kodu c++ potrzebny jest przecież kompilator, a dla pythona wystarczy środowisko do uruchomienia.
Zadania w Jenkinsie możemy przygotować na różne sposoby. Jeśli lubimy klikać – możemy całą konfigurację stworzyć w interfejsie graficznym (nie polecam). Służy do tego freestyle project. Za pomocą bloczków możemy zaplanować kolejne akcje w ramach Joba.
Innym sposobem jest przygotowanie pliku konfiguracyjnego, w którym zdefiniujemy wszystkie kroki. W Jenkinsie, job używający plików jako konfiguracji, nazywany jest Pipeline. Plik ten ma postać skryptu w języku Groovy. Jaka jest korzyść z konfiguracji w postaci pliku? Możemy przechowywać ją razem z kodem aplikacji której on dotyczy. Dzięki temu zapewniamy wersjonowanie zmian i kopię zapasową na wypadek awarii. Oto przykładowy fragment konfiguracji joba:
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'make'
}
}
stage('Test'){
steps {
sh 'make check'
junit 'reports/*/.xml'
}
}
stage('Deploy') {
steps {
sh 'make publish'
}
}
}
}
Istnieją też inne rodzaje jobów w jenkinsie, ale o tym opowiemy sobie innym razem.
Uruchomienie zadania w Jenkinsie (build)
Gdy zadanie jest już zdefiniowane można je uruchomić. Pojedyncze uruchomienie joba nazywane jest buildem. W trakcie działania buildu wykonywane są kolejno kroki zdefiniowane w konfiguracji joba (budowanie, testowanie itp.). Build może zakończyć się z jednym ze statusów:
- success – wszystkie kroki zostały wykonane poprawnie, testy zakończyły się sukcesem
- unstable – wszystkie kroki wykonano poprawnie ale testy lub ich część zwróciły błąd
- failure – wystąpił błąd podczas wykonywania joba np. niedostępny serwer budowania lub błędne parametry konfiguracyjne
Wyniki poszczególnych uruchomień są zapisywane na masterze. Dzięki temu możemy później prześledzić historyczne buildy. Przebieg wykonywania takiego joba można obserwować w wygodnym interfejsie użytkownika.
Zadania możemy skonfigurować m.in. w taki sposób aby uruchamiały się cyklicznie np. codziennie o 8:00 lub po każdym nowym commicie do repozytorium.
Pluginy Jenkins
Cechą szczególną Jenkinsa jest możliwość rozszerzania jego możliwości z użyciem wtyczek. Dzięki temu możemy przede wszystkim integrować się z wieloma zewnętrznymi narzędziami takimi jak:
- Docker do uruchamiania kontenerów,
- Artifactory do przechowywania binariów,
- Sonar do statycznej analizy kodu,
- Jira do zarządzania projektami
- i wiele, wiele innych
Inny rodzaj wtyczek to te rozszerzające możliwe kroki do wykonania w jobie. Przykładowe to wysyłanie maili z powiadomieniami, parsowanie raportu z wynikami testów, kopiowanie artefaktów. Wtyczek jest naprawdę dużo i nie sposób ich tutaj wszystkich wymienić. Warto zwrócić uwagę na to, że niektóre z nich nie są już aktywnie rozwijane. W efekcie mogą działać niewłaściwie lub mogą zwierać luki bezpieczeństwa. Instalując wtyczkę sprawdź kiedy była jej ostatnia aktualizacja.
Podsumowanie
Jenkins jest świetnym narzędziem które możliwa wdrożenie ciągłej integracji, ciągłego dostarczania i ciągłego wdrożenia. Zastosowanie architektury master-slave umożliwia dokładanie kolejnych serwerów kiedy tylko są potrzebne. Z użyciem edytora graficznego lub pliku konfiguracyjnego możemy przygotować zadanie, które ma się wykonywać. Sami decydujemy o tym kiedy budowanie ma się odbyć. Z użyciem wtyczek możemy budować i testować aplikacje niemal w każdej technologii. Mam nadzieję, że nieco rozjaśniłem Ci czym jest Jenkins i do czego można go użyć.
To jedynie wstęp do ogromu wiedzy związanego z Jenkinsem. Napisz w komentarzu, który z tych tematów chciałbyś abym opisał szerzej w pierwszej kolejności.
Dobra robota! Zrozumiany dla laika jezyk i dobrze wytlumaczone ogolne dzialanie.
Dziękuję za komentarz, polecam się na przyszłość 🙂
a po co to komu?
wystarczy rake a dla wybrednych ninja czy cmake i będzie działac.
wydumki nikomu nie potrzebne , no może po za kierownikiem, który nie ogarnia i musi miec strone www
Dobre pytanie. Mogłoby się wydawać, że jeśli projekt buduje się lokalnie, to powinno wystarczyć. Problem pojawia się wtedy, gdy projekt składa się z wielu komponentów, nad którymi pracuje szerokie grono deweloperów. W takiej sytuacji konieczność częstego scalania zmian i integracji to absolutny must have. Pozwala to dużo szybciej wykrywać błędy i finalnie usprawnia cały proces wytwórczy.
Jeżęli można prosić aby rozszerzyć sam temat Groovy i jak wdrożyć to co zostąło napisane było by ekstra. Jestem również ciekaw co musi się znaleśc na virtual machine aby to zadziałoło. Chciałem jeszcze sprawdzić czy dobrze zrozumiałem. Virtualna maszyna jest masterem i zam są zaciądane pliki np z Team City?
To, jak przygotować i uruchomić środowisko opisałem w innym artykule: https://szkolajenkinsa.pl/2021/02/21/jenkins-instalacja-jak-zaczac-dzialac/ – tam znajdziesz więcej informacji.
Świetny artykuł! Dobry na początek 🙂
Super wprowadzenie! Od zera, czytelnie, a przy tym zwięźle!
W koncu pozbylem sie chmury i ja odinstalowalem na plugina 🙂
Świetne szkolenie. Zwięźle i z najważniejszymi funkcjami