trzy drogi devops

Trzy drogi DevOps i co z nich wynika

Książka “Projekt Feniks. Powieść o IT, modelu DevOps i o tym, jak pomóc firmie w odniesieniu sukcesu” stanowi idealny łagodny wstęp do tej metodyki. Jestem przekonany, że po jej przeczytaniu czytelnik nie raz i nie dwa krzyknie “ależ ja spotkałem podobnego człowieka/sytuację!”. Definiuje ona i pokazuje w działaniu trzy główne zbiory zasad DevOps (nazywane też drogami DevOps). Dzisiaj właśnie o tych zasadach.

Charakterystyczną cechą procesu wydawania nowych wersji aplikacji jest nie tylko relatywnie duży odsetek zawartych w nim ręcznych działań, ale również trudność w całkowitym ich wyeliminowaniu. Operacje manualne często trudno wyeliminować całkowicie, gdyż nawet w dalece zautomatyzowanych procesach wydawania nowych wersji potrzebny jest krok decyzyjny. Zwykle ostateczną decyzję o tym, czy uruchomić wydawanie nowej wersji pozostawia się człowiekowi – często jest to osoba dedykowana zarządzaniu procesem zmian (ang. Change Manager) lub wręcz zarządzająca procesem wydawania nowych wersji (ang. Release Manager).

Szczególnie w dużych projektach zdarza się, że osoby pełniące w/w role nie są specjalistami technicznymi, a raczej koordynatorami pewnych obszarów np. pełnią jednocześnie rolę właścicieli produktu (ang. product owner) wg. metodyki Agile. W takich sytuacjach ważne jest aby maksymalnie usprawnić podejmowanie takiej decyzji, np. poprzez zgromadzenie w jednym miejscu wszystkich niezbędnych informacji i zautomatyzowanie wszystkich czynności wykonywanych po podjęciu takiej decyzji. Idealną sytuacją jest udostępnienie np. w ramach Jenkins albo JIRA jednego przycisku o nazwie “utwórz nową wersję” którego kliknięcie przez uprawnioną osobę uruchamia całość procesu i automatycznie realizuje wszystkie potrzebne czynności.

Specjaliści DevOps zwracają jednak uwagę, że istnieją tzw. “wydania niskiego ryzyka”. Zwykle są to bardzo proste zmiany, które realizacja powinna skutkować w pełni zautomatyzowanym powstawaniem i wdrożeniem nowych wersji aplikacji. Przykładowo, zgłoszone błędy produkcyjne muszą przejść przez sekwencję testów (najlepiej automatycznych, choć jest to bardzo utrudnione ze względu na różnorodność zgłoszeń błędów) i po ich pozytywnym przejściu najczęściej nie jest potrzebna indywidualna decyzja o powstaniu nowej wersji aplikacji. Taka operacja może więc zostać w pełni zautomatyzowana łącznie z podjęciem decyzji o wydaniu nowej wersji – za podjęcie takiej decyzji uznaje się w takiej sytuacji np. umieszczenie przez programistę kodu w odpowiednim repozytorium i zaznaczenie w odpowiednim systemie informacji o rozwiązaniu zgłoszonego błędu.

W sytuacji potwierdzenia jakości dostarczonego rozwiązania przez następujące po po tych operacjach testy (których przygotowanie może być np. obowiązkowo realizowaną częścią rozwiązania błędu), pozostałe czynności mogą wykonać już procesy automatyczne. Takie podejście wydatnie wspierają współcześnie stosowane technologie takie jak konteneryzacja i architektura oparta na mikrousługi. Jest ono także pierwszym krokiem do pełnego uruchomienia opisanego dalej procesu ciągłego wdrażania.

Konfigurowanie środowisk

Każdy specjalista operacji IT wie, że czasami środowisko łatwiej zbudować od zera, niż je naprawić. Zwykle jest też tak, że im bardziej skomplikowane jest środowisko, tym są większe szanse (albo ryzyko) wystąpienia takiej sytuacji. Dodatkowo, w czasach rozpowszechnienia wirtualizacji i konteneryzacji, punkty wyjścia do budowy środowiska są zwykle bardzo dobrze zdefiniowane i możliwe do szybkiego odtworzenia. Dlaczego więc nie zautomatyzować w pełni procesu przygotowania środowiska i nie zaakceptować, że w przypadku potrzeby wykonania w środowisku JAKIEJKOLWIEK zmiany jest ono budowane od zera? 

Tak hasłowo można przedstawić rozumowanie stojące za koncepcją “infrastruktura jako kod” (ang. infrastructure as a code – IaC). Drugą blisko związaną koncepcją opierającą się na analogicznych założeniach jest też “konfiguracja jako kod” (ang. configuration as a code – CaC), która jest omawiana w jednym z dalszych rozdziałów. Granica między tymi dwoma koncepcjami jest w dużym stopniu umowna i można ją różnie przeprowadzić.

Po pierwsze, można to zrobić w taki sposób, że za konfigurację uznaje się wszystkie zmiany w środowisku wymagane wyłącznie przez produkowaną aplikację do jej poprawnego działania. Natomiast infrastruktura to wszystkie wcześniejsze, zwykle dość standardowe operacje instalacyjno-konfiguracyjne. Podział na takie dwa obszary ma najczęściej sens, ponieważ cechują się one różną zmiennością. Infrastruktura jest dużo bardziej stabilna i niezależna od środowiska aplikacyjnego, więc opłacalne jest wydzielanie jej i osobne kontrolowanie jej zmian. Dzieje się tak również dlatego, że w niektórych sytuacjach zmiany w infrastrukturze pociągają za sobą np. konsekwencje formalne związane z np. licencjami za używane oprogramowanie.

Drugim sposobem przeprowadzania tego rozgraniczenia jest np. podział na kod, który tworzy infrastrukturę (np. w chmurze) i kod, który wyłącznie zmienia jej konfigurację (np. poprzez zmianę parametrów środowiska).

W dalszej części tego artykułu używane jest to pierwsze rozróżnienie IaC i CaC.

Spośród zalet koncepcji IaC warto wymienić trzy, które szczególnie wspierają optymalizowanie przepływu strumienia wartości technologii, a tym samym wpisują się w metodykę DevOps:

  • Szybkość – wykonanie operacji w pełni automatycznie jest zawsze szybsze niż wykonanie tej samej operacji ręcznie. Zatem dostarczenie środowiska trwa krócej, co samo w sobie jest już wartością z punktu widzenia DevOps.
  • Ryzyko – operacje automatyczne w przeciwieństwie do manualnych nie są podatne na zwykłe pomyłki. W obu przypadkach mogą wystąpić błędy, ale ze względu na kolejną cechę (powtarzalność) – dużo łatwiej eliminować je z kodu. 

Utrzymywanie kodu w narzędziu IaC zmniejsza też ryzyka związane z aktualnością dokumentacji, czy transferem i ewentualną utratą wiedzy przez organizację.

Kod ten stanowi także niebagatelne źródło informacji zwrotnych o środowiskach dostępne dla programistów, pełniąc tym samym ważną funkcję w realizacji celów drugiej drogi DevOps.

  • Powtarzalność – pozwala eliminować błędy z kodu stosując podejście iteracyjne. Zwykle też operacje definiowane przez narzędzia IaC są też idempotentne, co dodatkowo ułatwia rozwiązywanie problemów nawet w częściowo zbudowanym środowisku (powtórzenie już wykonanej operacji nie wprowadza błędów). 

Spora część narzędzi stosuje deklaratywne podejście do definiowania infrastruktury, tym samym prawie całkowicie zwalniając użytkownika z myślenia o konkretnych operacjach jakie dla danego środowiska trzeba wykonać – jest to określane przez samo narzędzie na podstawie zdefiniowanego pożądanego stanu docelowego.

Oczywiście, powyższe zalety przekładają się na zmniejszenie kosztów operacji IT, co ma niebagatelny koszty procesu produkcji jako całości.

Ze względu na ważność koncepcji IaC dla funkcjonowania DevOps jako całości, narzędzia te są jednymi z kluczowych elementów łańcucha narzędzi wykorzystywanych przez DevOps (ang. DevOps toolchain). Prawdopodobnie dlatego istnieje na rynku tak wiele narzędzi opartych o tę koncepcję. Najczęściej też trudno rozdzielić ich funkcjonalności wspierające IaC od tych wspierających CaC (ang. configuration as a code). Z najpopularniejszych warto wymienić tutaj:

  • Ansible – rozwiązanie będące własnością firmy RedHat posiadające również wersję Community. Rozwiązanie bezagentowe, oparte o podejście deklaratywne i wykorzystujące pliki YAML do definicji infrastruktury. Rozszerzenia funkcjonalności realizowane przez moduły mogą być tworzone w wielu różnych językach programowania. Posiada centralne repozytorium gotowych rozwiązań (modułów, ról) – tzw. Ansible Galaxy.
  • Chef – kompleksowe, składające się ze specjalizowanych modułów rozwiązanie firmy Progress do automatyzacji i zarządzania konfiguracją. Posiada warianty oparte o licencję Apache 2.0. Rozwiązanie typu klient/serwer bądź bezagentowe, oparte o podejście deklaratywne i Ruby.
  • Puppet – rozwiązanie stworzone przez firmę o tej samej dostępne w wersji open source jak i komercyjnie. Rozwiązanie oparte o podejście deklaratywne. Centralnym narzędziem używanym do definiowania infrastruktury są tu moduły – będące typowym przykładem dedykowanego DSL.
  • Terraform – rozwiązanie firmy HashiCorp koncentrujące się na współpracy z usługami chmurowymi. Posiada zarówno wersję open source jak i płatną Enterprise. Umożliwia korzystanie z API dostawców chmurowych z pomocą deklaratywnego DSL. Rozszerzalne za pomocą modułów będących mieszaniną DSL i plików JSON. Posiada centralne repozytorium gotowych modułów nazywane “Terraform registry”.

Wszystkie w/w narzędzia współpracują z najpowszechniejszymi systemami operacyjnymi, systemami konteneryzacji i orkiestratorami kontenerów, narzędziami do wirtualizacji – zarówno wewnątrz infrastruktury korporacyjnej jak i w chmurach publicznych.

Powyższe pozycje w żaden sposób nie wyczerpują listy dostępnych rozwiązań – wybór konkretnego z nich jest oczywiście ważny i ma najczęściej daleko idące konsekwencje, tym niemniej największą zmianą jakościową w operacjach IT jest samo zastosowanie koncepcji IaC w praktyce.

Końcowa część strumienia wartości technologii

Umownym końcem przebiegu strumienia wartości technologii dla konkretnej partii pracy jest udostępnienie klientowi wywożonej wersji aplikacji oraz gromadzenie danych o jej funkcjonowaniu. Umowność zaklasyfikowania tych operacji do części końcowej polega min. na tym że zgodnie z rekomendacjami DevOps te same czynności związane z instalacją, konfigurowaniem i monitorowaniem aplikacji są wykonywane nie tylko na środowiskach produkcyjnych, ale również na testowych. Poza tym strumień wartości technologii jest procesem ciągłym – różne partie pracy znajdują się jednocześnie na jego różnych etapach.

Instalowanie i konfigurowanie aplikacji

Wzajemny związek między instalowaniem i konfigurowaniem aplikacji a pozostałymi elementami procesu dostarczania infrastruktury (ang. infrastructure provisioning) opisanego w jednym z poprzednich rozdziałów jest bardzo zależny od używanych technologii. W przeszłości te dwie aktywności były dość ściśle rozgraniczone – po zainstalowaniu i skonfigurowaniu infrastruktury systemowej pozostawała ona w dużym stopniu niezmienna (zwykle z dokładnością do aktualizacji oprogramowania standardowego), często też dostęp do niej był kontrolowany przez działy funkcjonujące poza strukturą projektową – typową administrację IT. Obecnie, głównie ze względu na konteneryzację rozwiązań, rozróżnienie między tym co jest dostarczaniem a co konfigurowaniem infrastruktury dla aplikacji straciło swój jednoznaczny charakter. 

Jednak wciąż istnieje kilka koncepcji charakterystycznych dla prac instalacyjno-konfiguracyjnych opisywanych w tym rozdziale, szczególnie w kontekście metodyki DevOps. Wymagają one opisania i są nimi:

  • Pojęcie ciągłego dostarczania (ang. continuous delivery) zwykle definiuje się jako utrzymywanie w określonej gałęzi repozytorium kodu cały czas gotowego do wdrożenia. Dzieje się to poprzez automatyczne instalowanie i testowanie rozwiązania na przeznaczonym do tego środowisku i natychmiastowe dostarczanie autorowi zmiany informacji zwrotnej pozwalającej skorygować ewentualne błędy. Pojęcie jest rozszerzeniem procesu ciągłej integracji w kierunku większego stopnia automatyzacji
  • Pojęcie ciągłego wdrażania (ang. continuous deployment) oprócz czynności opisanych w punkcie wyżej obejmuje również automatyzację procesu wdrażania na produkcję (opis procesów – zobacz). 

Procesy ciągłej dostarczania i wdrażania oznacza się zbiorczo skrótem “CD” – od pierwszych znaków ich nazw.

  • Narzędzia dedykowane dla procesów CD. Jak w wielu opisanych już tu przypadkach, do realizacji procesów CD mogą służyć różnorakie narzędzia. Można je podzielić na kilka klas takich jak:
    • Narzędzia dedykowane do zarządzania konfiguracją i stosujące podejście “konfiguracja jako kod”. Wiele z narzędzi opisanych w rozdziale o instalowaniu środowisk ma moduły dedykowane do wykonywania operacji wdrażania. Przykładem jest Chef który posiada moduł “Chef App Delivery”.
    • Narzędzia takie jak Jenkins posiadają odpowiednie wtyczki zarówno do wdrażania jak i konfigurowania aplikacji.
    • Dedykowane narzędzia do wdrażania takie jak Octopus Deploy czy Digital.ai Deploy.
    • Wdrażanie i konfigurowanie aplikacji może być zaimplementowane z użyciem jednego ze standardowych DSL (takiego jak choćby PowerShell). Wszystko oczywiście zależy od uwarunkowań technicznych i organizacyjnych.
  • W związku z tym, że parametry konfiguracyjne wytwarzanej aplikacji definiują zwykle programiści, a narzędziami do IaC lub CaC dysponują najczęściej osoby zajmujące się operacjami, często opłacalne jest używanie scentralizowanego systemu dostarczającego konfigurację na potrzeby samej aplikacji. Taki system pozwala na:
    • Pobieranie przez aplikację aktualnej konfiguracji aplikacji w czasie rzeczywistym. Dzięki temu nie ma potrzeby wydawania nowej wersji tylko po to aby zmienić globalnie lub lokalnie wartości wybranych parametrów konfiguracyjnych.
    • Przechowywanie danych konfiguracji w standardowych narzędziach i standardowej formie, np. plików JSON w repozytorium kodu, czyli w Git. Takie podejście automatycznie zapewnia śledzenie zmian w konfiguracji aplikacji.
    • Umożliwienie łatwego modyfikowania konfiguracji przez zespoły deweloperskie. W tym również na produkcji – pod warunkiem posiadania odpowiednich uprawnień w systemie kontroli wersji.

Narzędzia dostarczające takiej funkcjonalności są bliskie koncepcji “konfiguracja jako kod” – mowa tu o dedykowanej konfiguracji i danych o charakterze dość bliskim deklaratywnym DSL. Siłą rzeczy, takie narzędzia są ściśle związane technologią, w jakiej wykonana jest aplikacja. Przykładowo, dla aplikacji stworzonych w Spring istnieje Spring Cloud Config.

Czynności związane z instalowaniem aplikacji oraz zmianami konfiguracji są znaczącą częścią prac operacyjnych, zatem dobry wybór narzędzi wspierającym może dać duże korzyści dla sprawnego przepływu strumienia wartości technologii – tak jak definiuje to DevOps.

Monitorowanie

Kolejną znaczącą częścią prac operacyjnych jest monitorowanie działania systemów. Mowa to nie tylko o monitorowaniu działania systemu produkcyjnego, ale również środowisk testowych oraz wszystkich innych elementów infrastruktury które są oceniane jako krytyczne dla sprawnego funkcjonowania procesu produkcji (a więc np. systemów do ciągłej integracji).

Monitorowanie systemów dostarcza danych telemetrii, które są jednym z najważniejszych elementów poprawnego funkcjonowania zasad drugiej drogi DevOps – dzięki nim programiści posiadają aktualną informację o zachowaniu produkowanej przez siebie aplikacji albo w warunkach “laboratoryjnych” (jakimi są środowiska testowe) albo w warunkach rzeczywistych.

Użyteczne systemy dostarczające zespołowi wytwórczemu informacji zwrotnej o działaniu produktu posiadają zwykle co najmniej następujące cechy, po części omówione już w poprzednich rozdziałach:

  • Scentralizowanie dostępu do danych z monitorowania/analizy.
  • Gromadzenie danych o technicznym, ale i funkcjonalnym działaniu aplikacji.
  • Agregowanie i kontekstowe łączenie danych z różnych elementów monitorowanego systemu. Możliwość korzystania z danych z systemów zewnętrznych.
  • Możliwość eksportu danych do systemów zewnętrznych (np. kontroli wersji czy obsługi zdarzeń).
  • Wyliczanie syntetycznych statystyk.
  • Powiadamianie rutynowe oraz o anomaliach.
  • Narzędzia analityczne.

Istnieje duża ilość narzędzi do monitorowania systemów – zarówno w formie samodzielnych rozwiązań, ale również jako części pakietów o szerszym zastosowaniu. Warto tu zwrócić uwagę na dwie nieco różne grupy produktów wspierających dostarczanie informacji zwrotnej postulowane przez drugą drogę DevOps. 

  • Klasyczne systemy monitorowania oparte o zasady zdefiniowane w APM (ang. application performance managementzobacz). Systemy koncentrują się na gromadzeniu różnego rodzaju metryk w postaci numerycznej. Analiza logów (o ile jest dostępna) pełni rolę drugorzędną. Warto tu wymienić dwa o zdecydowanie różnym charakterze:
    • AppDynamics – kompleksowe komercyjne rozwiązanie oferujące możliwość monitorowania wszystkich warstw systemów (łącznie z monitorowaniem wydajności aplikacji na stacji użytkownika końcowego czy rozwiązań dla systemów mobilnych) będące własnością firmy Cisco. Realizuje wszystkie postulaty zdefiniowane w APM. Ważną możliwością dawaną przez narzędzie jest możliwość definiowania transakcji w monitorowanych aplikacjach i analizowania wpływu działania wszystkich warstw systemu na wydajność tak zdefiniowanych transakcji.
    • Zabbix – otwartoźródłowe rozwiązania dostarczane przez firmę o tej samej nazwie. Umożliwia realizację wszystkich postulatów zdefiniowanych przez APM poprzez odpowiedni dobór wtyczek. Wspiera monitorowanie stacji końcowych użytkowników a także monitorowanie z użyciem i bez użycia agentów. Narzędzie cechują szerokie możliwości współpracy z systemami zewnętrznymi.
  • Systemy monitorowania połączone z mechanizmami archiwizowania i analizy logów. Nie są systemami monitorowania wydajności w klasycznym tego słowa znaczeniu, ponieważ dużą rolę pełni w nich element przetwarzania surowych danych. Dzięki szerokim możliwościom analizy i agregacji danych o różnych typach (nie tylko numerycznych) pełnią ważną rolę w dostarczaniu informacji zwrotnej. Pozwalają programistom analizować dane z logów nad których wytworzeniem mają oni bezpośrednią kontrolę poprzez umieszczenie odpowiednich rozkazów w kodzie aplikacji. W połączeniu z możliwością przełączania poziomu szczegółowości logowania zdarzeń podczas działania systemu (dawaną np. przez wspomniane wcześniej narzędzia do dostarczania konfiguracji w trybie runtime), narzędzia te są bardzo efektywnym wsparciem przy rozwiązywaniu problemów. Dwa popularne to:
    • Elastic stack – zestaw narzędzi w skład którego wchodzą przede wszystkim Elasticsearch – specjalizowany system do gromadzenia, wyszukiwania i analizowania danych oraz Kibana – konfigurowalny interfejs graficzny przeznaczony do wizualizacji danych. Najczęściej używany do analizy logów łącznie z komponentem Logstash przeznaczonym do pobierania i konwersji danych. Rozwiązanie Elastic stack może służyć nie tylko do gromadzenia i analizy logów, ale również danych z innych źródeł – poprzez system wtyczek.
    • Splunk – narzędzie do analizy logów występujące w trzech wersjach: Enterprise, Cloud oraz darmowej Light (o mniejszych możliwościach). Wyposażone w pełny graficzny interfejs użytkownika z szerokimi możliwościami raportowania, tworzenia wykresów, alertów itp.  Umożliwia włączenie mechanizmów sztucznej inteligencji do procesu analizy logów.

Monitorowanie systemów może też być częścią proaktywnego podejścia do usprawnienia procesu rozwiązywania problemów, które to podejście rekomenduje DevOps (np. wspomniana już technika chaos monkey). Proaktywność opiera się na symulowaniu awarii i przeprowadzaniu ćwiczeń w ich rozwiązywaniu. Dzięki takiemu podejściu zespoły doskonalą swoje umiejętności analityczne ale także weryfikowana jest przydatność danych zawartych w systemach monitorowania oraz zaimplementowane w nich mechanizmy.

Zapraszamy do dyskusji

Patronujemy

 
 
More Stories
Płatne funkcje znikają z Chrome’a! Śniadanie z Programowaniem #56