Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

DevOps w chmurze Amazonu

Autor: Piotr Karpiuk o piątek 2. Czerwiec 2017

Wielką popularnością obecnie cieszy się programowanie zwinne (ang. agile software development), które rozpoczęło żywot w 2001 roku, a z czasem zdobyło wielką popularność i dość skutecznie wyparło tradycyjny „wodospadowy” model tworzenia oprogramowania. Metodyki zwinne odnoszą się zwłaszcza do współpracy pomiędzy programistami a użytkownikami biznesowymi.

Tymczasem w czeluściach procesu tworzenia oprogramowania czai się jeszcze inny konflikt, tym razem w obrębie organizacji: pomiędzy deweloperami a osobami odpowiedzialnymi za wdrożenie oprogramowania. Tradycyjnie w dużych firmach IT deweloperzy chcą szybko tworzyć i modyfikować oprogramowanie, podczas gdy na drodze staje im dział eksploatacji (ang. IT operations, czyli administratorzy, architekci infrastruktury sprzętowej i personel wsparcia klienta) zainteresowany głównie stabilnością i niezawodnością, a nie zmianami (patrz kultowy rysunek obok, pochodzący z jednej z pierwszych konferencji DevOps w 2010 roku). Na konflikcie interesów traci cała firma.

DevOps to kombinacja kultury, praktyk i narzędzi które łącznie przyspieszają dostarczanie klientom kolejnych wersji aplikacji i usług. W środowisku deweloperów DevOps skupia się na pojęciach takich jak budowanie kodu (ang. code building), testy pokrycia, testy jednostkowe, pakowanie i wdrażanie. W środowisku eksploatacji mówimy o aprowizacji (ang. provisioning), konfiguracji, orkiestracji i wdrażaniu. Dla obu obszarów wspólne pojęcia to zarządzanie wersjami, wdrażanie, wycofywanie zmian (ang. roll back) i testowanie.

Można powiedzieć, że o ile klasyczne metodyki zwinne dotyczą zwinności biznesowej, DevOps odnosi się do zwinności IT.


Infrastruktura jako kod

Podstawową zasadą DevOps jest traktowanie infrastruktury w taki sam sposób jak deweloperzy traktują kod (ang. Infrastructure as Code, IaC). Jest to możliwe w środowiskach zwirtualizowanych, gdzie tworzenie maszyn wirtualnych i łączenie ich w sieci można łatwo automatyzować. Taką platformę można stworzyć we własnej firmie, ale jest ona już od dawna standardem w środowisku chmur obliczeniowych. Tzw. aprowizacja infrastruktury (ang. infrastructure provisioning) odbywa się na podstawie deklaratywnego opisu zawartego w pliku tekstowym. Przykładowo w chmurze AWS usługa CloudFormation tworzy całe podsieci na podstawie pliku JSON o odpowiedniej strukturze. W rezultacie tworzony przez administratorów plik z opisem infrastruktury sprzętowej może podlegać dokładnie tym samym rygorom co kod źródłowy tworzony przez deweloperów (wersjonowanie, wycofywanie do poprzedniej wersji, testowanie, powtarzalność wdrożenia itp.).

O ile w chmurze AWS usługa CloudFormation pozwala utworzyć i skonfigurować całą sieć wirtualnych maszyn (i innych usług AWS takich jak kolejki komunikatów czy NoSQLowe bazy danych), to AMI (ang. Amazon Machine Image) pozwala na podstawie pliku aprowizować pojedynczą maszynę wirtualną. Obraz AMI zawiera system operacyjny oraz wymagane oprogramowanie (np. serwer aplikacji, serwer WWW, system zarządzania bazami danych itp.). Możesz skorzystać z darmowych obrazów udostępnianych przez AWS, kupić obraz od któregoś z klientów Amazonu, albo utworzyć samemu (z garniturem oprogramowania które jest najlepiej skrojone do Twoich potrzeb).

Ciągła integracja

Ciągła integracja (ang. continuous integration, CI) to praktyka deweloperska, w której powstaje swoista zautomatyzowana linia produkcyjna aktywowana każdym wrzuceniem paczki zmian do systemu zarządzania wersjami. Kolejnymi etapami takiego potoku wdrożeń (ang. pipeline) są budowa aplikacji ze źródeł i testy (jednostkowe, poprawności stylu, analiza statyczna kodu). Główny cel to możliwie szybkie wykrywanie błędów, poprawa jakości oprogramowania i redukcja czasu w jakim kolejne wersje są prezentowane klientom. Istotne jest tu, aby programiści wrzucali do repozytorium swój kod często – co najmniej raz dziennie, a przed tym przetestowali go testami jednostkowymi. Dodatkowe wyzwania wiążą się z przeprowadzaniem testów w środowisku możliwie najbardziej przypominającym produkcyjne, wizualizacja procesu i łatwe wygenerowanie dowolnej wybranej wersji oprogramowania.

Ciągłe wdrażanie

Ciągłe dostarczanie (ang. continuous delivery) wiąże się z wydłużeniem potoku wdrożeń o zautomatyzowane testy integracji aplikacji w utworzonym automatycznie środowisku testowym symulującym produkcyjne (staging) i zautomatyzowane przygotowanie paczki z oprogramowaniem gotowej do wrzucenia na produkcję. Krótko mówiąc, gdy firma osiągnęła etap ciągłego dostarczania, ma zawsze gotową do wdrożenia świeżą paczkę która przeszła wszelkie możliwe testy. Decyzja o wrzuceniu paczki na produkcję jest decyzją biznesową, a nie techniczną.

Kluczowym dla idei DevOps pojęciem jest ciągłe wdrażanie (ang. continuous deployment, CD), które idzie jeszcze dalej i obejmuje automatyczne wdrożenie nowej wersji oprogramowania na produkcji. Wdrożenie najnowszych zmian na produkcji nie jest tu wydarzeniem godnym jakiejś szczególnej uwagi. Nie wymaga przygotowania planu, przekazywania dokumentacji, ani okna konserwacji. Wdrożenie jest rutynowym, powtarzalnym procesem uzasadnionym po wielekroć testami wykonanymi na etapie budowania i w środowisku testowym.

Dzięki praktykom CD, oprogramowanie może być wdrażane szybko, powtarzalnie i niezawodnie. Gdy okaże się że nowa wersja na produkcji nie spełnia oczekiwań klienta, może być łatwo wycofana do wersji poprzedniej. W miarę jak kod jest przepychany przez poszczególne etapy potoku, rośnie jego jakość na skutek kolejnych weryfikacji. Problemy wykryte na wczesnym etapie wstrzymują potok a deweloperzy są powiadamiani o tym i dostają do ręki wyniki testów zakończonych niepowodzeniem.

Przedstawioną tu koncepcję potoku wdrożeń należy traktować jako pewien wzorzec, który można na wiele sposobów modyfikować dodając inne etapy dopasowane do wymogów aplikacji. Ponadto, budowa potoku wdrożeń jest długotrwałym przedsięwzięciem i nigdy się nie kończy – nawet firmy z dojrzałym potokiem poświęcają wiele czasu na jego ciągłe udoskonalanie („DevOps jest podróżą, a nie celem”). Warto zacząć od minimalnego sensownego potoku (ang. minimum viable pipeline, MVP).

Pomysły na rozbudowanie modelu CI/CD:

  • może być więcej środowisk testowych (staging) testujących różne aspekty aplikacji – wydajność, zgodność z regulacjami prawnymi (ang. compliance), bezpieczeństwo, testy interfejsu użytkownika itp.
  • testy jednostkowe mogą obejmować również infrastrukturę sieciową i konfigurację, a nie tylko sam kod aplikacji,
  • integracja z innymi systemami i procesami takimi jak śledzenie preblemów (ang. issue tracking) i powiadamianie o zdarzeniach,
  • integracja z migracją schematów baz danych.

Zespoły

Amazon rekomenduje zorganizowanie trzech zespołów wchodzących w skład środowiska CI/CD, co sprawdza się zarówno w szybko rosnących start-upach, wielkich organizacjach, jak i w samym Amazonie:

  • zespół aplikacji – pisze kod źródłowy aplikacji, testy, backlog itp.,
  • zespół infrastruktury – współpracuje ściśle z zespołem aplikacji, pisze kod tworzący i konfigurujący infrastrukturę sieciową maszyn wirtualnych, np. szablony CloudFormation, przepisy dla narzędzi takich jak Chef, Puppet, Salt czy Ansible.
  • zespół narzędziowy – odpowiedzialny za infrastrukturę i narzędzia tworzące potok wdrożeń. Jeden zespół narzędziowy może obsługiwać wiele różnych projektów.

Dwa pierwsze zespoły powinny „wyżywić się dwiema pizzami”, czyli w praktyce ich stan osobowy nie powinien łącznie przekraczać 10-12 osób.

Testy

  • Faza „build”
    • Testy jednostkowe – tworzone przez deweloperów równolegle z kodem źródłowym aplikacji; takie testy są najtańsze w produkcji a ich wykonywanie spośród wszystkich typów testów trwa najkrócej, powinny stanowić ok. 70% testów aplikacji (patrz rysunek wyżej) i pokrywać niemal cały kod źródłowy aplikacji, ponieważ błędy znalezione na tak wczesnym etapie mogą być poprawione szybko i tanio
    • Statyczna analiza kodu – sprawdza zgodność z wytycznymi formatowania kodu, wykrywa luki bezpieczeństwa itp.
  • Faza „staging”
    • Testy integracji
    • Testy komponentów – testują komunikację między komponentami i otrzymywane wyniki
    • Testy systemowe – sprawdzają czy aplikacja spełnia wymagania biznesowe – UI, API, logika zaplecza (ang. backend logic) itd.
    • Testy wydajności, obciążenia, przeciążenia
    • Testy niefunkcjonalne (jakościowe): skalowalność, bezpieczeństwo, czas odpowiedzi
  • Faza „production” – tutaj warto przeprowadzić tzw. „testy kanarkowe” sprawdzające działanie aplikacji na jedynie niewielkim podzbiorze serwerów produkcyjnych, zanim zmiany obejmą całe środowisko.

Ciągłe wdrażanie w chmurze AWS

Usługa AWS CodeCommit to system kontroli wersji Git przystosowany do środowiska chmurowego. Przystosowanie obejmuje współpracę z innymi usługami AWS, automatyczne skalowanie, oraz narzędzia do przeglądania, edycji i grupowej współpracy. Tym niemniej jest to Git, więc możesz połączyć go z własnymi narzędziami do Gita.

CodePipeline integruje się z CodeCommit i realizuje całą koncepcję linii produkcyjnej, przy czym poszczególne jej etapy możesz zastąpić własnymi ulubionymi narzędziami (np. Jenkins, Solano CI, TeamCity). CodeBuild to Amazonowa propozycja build servera, o tyle ciekawa że poza obsługą wielu popularnych języków programowania i kontenerów Dockera automatycznie się skaluje – może wykonywać wiele zleceń budowania naraz.

Do budowy i orkiestracji potoku wdrożeń ciągłego dostarczania w chmurze AWS służy usługa CodeStar, która używa CodePipeline, CodeBuild, CodeCommit i CodeDeploy dostarczając swoje narzędzia konfiguracji, szablony i kokpit (ang. dashboard) do wizualizacji i monitorowania potoku wdrożeń. Używając skrótu myślowego można powiedzieć że CodeStar dostarcza wszystkiego czego potrzebujesz aby szybko tworzyć i wdrażać aplikacje w środowisku chmury Amazonu.

Usługa CodeDeploy odpowiada za samo wdrożenie spakowanej aplikacji gotowej do wrzucenia na produkcję i umieszczonej w S3. Oto jak działa (patrz obrazek):

  1. Aplikacja jest pakowana i umieszczana w S3 wraz z plikiem specyfikacji (AppSpec file) definiującym serię kroków jakie CodeDeploy ma wykonać. Taki pakiet jest nazywany „rewizją” CodeDeploy (ang. CodeDeploy revision).
  2. Tworzysz aplikację w CodeDeploy i definiujesz instancje EC2 do których aplikacja ma być wdrożona (tzw. deployment group) – w każdej instancji musi chodzić agent CodeDeploy. Tu również określasz kubełek S3 w którym znajduje się pakiet z pkt. 1.
  3. Agenci odpytują CodeDeploy aby otrzymać instrukcje.
  4. Każdy agent CodeDeploy wyciąga kod aplikacji i wdraża go na swojej instancji, posiłkując się dodatkowo otrzymanymi skryptami.

Kolejne dwie usługi AWS: Elastic Beanstalk i OpsWorks, idą trochę dalej. Wspierają nie tylko wdrażanie nowej wersji oprogramowania, ale także zmiany w infrastrukturze sieciowej. Beanstalk obsługuje popularne stosy technologii (np. Apache Tomcat, .NET na WindowsServer z IIS, Node.js, PHP+Apache itp.) i wystarczy dostarczyć mu odpowiedni plik *.war lub *.zip, a bardziej zaawansowany i konfigurowalny OpsWorks wykonuje dowolne przepisy (ang. recipes) popularnego otwartoźródłowego narzędzia do konfiguracji Chef. Obydwie usługi AWS wspierają monitoring i wersjonowanie (w tym łatwe przywracanie aplikacji do poprzedniej wersji). OpsWorks zajmuje się nie tylko wdrażaniem, ale również zarządzaniem całą aplikacją i jej cyklem życia.

Używanie wymienionych do tej pory usług AWS do realizacji potoku wdrożeń ma i tę zaletę, że są one dobrze zintegrowane z usługą CloudWatch Logs – tak więc dostępne są logi z działania całego potoku.

Jeśli jesteś przyzwyczajony do Jenkinsa i chcesz budować potok w oparciu o niego, to zdecydowanie polecaną ścieżką jest użycie AWS Code Pipeline Plugin.

Literatura

Share and Enjoy:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Śledzik
  • Blip
  • Blogger.com
  • Gadu-Gadu Live
  • LinkedIn
  • MySpace
  • Wykop

Zostaw komentarz

XHTML: Możesz użyć następujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>