Blog JSystems - uwalniamy wiedzę!

Szukaj
Pulpit Grafany z metrykami CPU, pamięci i sieci serwera - typowy widok pracy zespołu DevOps
Tak w praktyce wygląda DevOps w akcji: żywy pulpit monitoringu (tutaj Grafana) pokazujący kondycję działającej infrastruktury. To jeden z ostatnich elementów układanki, do którego dojdziemy. Po drodze rozłożymy na części pierwsze każde narzędzie, które sprawia, że taki widok jest w ogóle możliwy.

DevOps to jedno z najczęściej wpisywanych w wyszukiwarkę pojęć w branży IT i jednocześnie jedno z najgorzej rozumianych. Dla jednych to nazwa stanowiska, dla innych zestaw modnych narzędzi, a dla jeszcze innych magiczne zaklęcie, które ma sprawić, że oprogramowanie zacznie wdrażać się samo. Żadna z tych odpowiedzi nie jest pełna. W tym przewodniku wyjaśnimy po kolei, czym DevOps naprawdę jest, z jakich narzędzi się składa i do czego każde z nich służy. Wszystkie przykłady w kodzie uruchomiliśmy naprawdę, więc widzisz autentyczne wyniki z terminala, a nie slajdy z prezentacji.

Z tego artykułu dowiesz się:
  • Czym DevOps jest jako kultura i zestaw praktyk, a czym na pewno nie jest
  • Jak wygląda pełna pętla życia oprogramowania i który etap obsługuje które narzędzie
  • Do czego służą Git, Docker, Kubernetes, Terraform, Ansible, Prometheus i Grafana, na prawdziwych wynikach z terminala
  • Jak te narzędzia łączą się w jeden potok, od zapisania kodu po działanie na produkcji
  • Co DevOps realnie daje firmie, mierzone liczbami, a nie hasłami

Czym właściwie jest DevOps (a czym nie jest)

DevOps to sposób pracy nad oprogramowaniem, który łączy tworzenie aplikacji (ang. development, w skrócie „dev") z jej utrzymaniem na serwerach (ang. operations, „ops") w jeden, wspólny i mocno zautomatyzowany proces. To przede wszystkim kultura i zestaw praktyk, a narzędzia są dopiero konsekwencją. Sama nazwa jest zbitką słów „development" i „operations" i to nie przypadek, bo DevOps powstał dokładnie po to, żeby zburzyć mur między tymi dwoma światami.

Warto od razu rozwiać trzy nieporozumienia. DevOps nie jest jednym narzędziem: nie da się „kupić DevOps" ani zainstalować go z jednego pakietu. DevOps nie jest osobnym działem, który wrzuca się między programistów a administratorów (to zwykle tworzy trzeci mur zamiast burzyć istniejące). I choć na rynku pracy istnieje stanowisko „DevOps Engineer", samo DevOps nie jest stanowiskiem, tylko sposobem, w jaki cała organizacja dowozi i utrzymuje oprogramowanie.

Skąd w ogóle wziął się ten mur? Z konfliktu celów. Programiści są rozliczani z tego, jak szybko dostarczają nowe funkcje, więc chcą wdrażać zmiany często. Administratorzy odpowiadają za stabilność, więc każda zmiana jest dla nich ryzykiem, które chcą ograniczać. W efekcie wdrożenie (ang. deployment, czyli udostępnienie nowej wersji aplikacji użytkownikom) stawało się rzadkim, stresującym wydarzeniem, a po każdej awarii zaczynało się wzajemne obwinianie. DevOps rozwiązuje ten spór, ustawiając obie strony po tej samej stronie: wspólna odpowiedzialność, wspólny potok i automatyzacja tam, gdzie wcześniej były ręczne przekazania „przez płot".

Przed DevOps

Programiści (Dev): dowieźć nowe funkcje jak najszybciej
M U R
Administratorzy (Ops): utrzymać stabilność, ograniczać zmiany
Rzadkie wdrożenia, ręczne przekazania, obwinianie po awarii.

Po wdrożeniu DevOps

Jeden wspólny zespół i jeden zautomatyzowany potok: kod, testy, wdrożenie, monitoring.
Wspólna odpowiedzialność za produkcję, automatyzacja zamiast ręcznej pracy, szybka informacja zwrotna.
Częste, spokojne wdrożenia i szybka naprawa, gdy coś pójdzie nie tak.
Sedno DevOps to zburzenie muru między tworzeniem a utrzymaniem oprogramowania i zastąpienie ręcznych przekazań wspólnym, zautomatyzowanym potokiem.

Żeby ta zmiana kultury nie została pustym hasłem, w środowisku DevOps przyjęło się pięć filarów opisywanych skrótem CALMS: Culture (kultura wspólnej odpowiedzialności), Automation (automatyzacja powtarzalnych czynności), Lean (dostarczanie małymi porcjami, bez marnotrawstwa), Measurement (mierzenie wszystkiego, bo bez pomiaru nie wiadomo, czy jest lepiej) i Sharing (dzielenie się wiedzą zamiast trzymania jej w silosach). Zapamiętaj te pięć słów, bo do każdego z nich wrócimy przy konkretnych narzędziach.

Pętla DevOps: cykl życia oprogramowania

DevOps najłatwiej zrozumieć jako ciągłą pętlę, a nie jednorazowy proces „od-do". Oprogramowanie się planuje, pisze, buduje, testuje, wydaje, wdraża, utrzymuje i monitoruje, a wnioski z monitoringu wracają do planowania kolejnej zmiany. Ta pętla nigdy się nie zatrzymuje. Klasycznie rysuje się ją jako znak nieskończoności, w którym lewa połowa należy do „dev", a prawa do „ops". Każdy etap ma swoje narzędzia i to właśnie ich zestaw nazywamy potocznie „narzędziami DevOps".

PLANplanowanie KODpisanie BUILDbudowanie TESTtesty RELEASEwydanie DEPLOYwdrożenie OPERATEutrzymanie MONITORobserwacja DevOps ciągła pętla
Plan / Kod: Git, systemy zgłoszeń
Build: Docker, kompilatory
Test: frameworki testów, CI
Release: GitHub Actions, GitLab CI, Jenkins
Deploy: Kubernetes, Helm, Terraform, Ansible
Operate / Monitor: chmura, Proxmox, Prometheus, Grafana, Loki
Osiem etapów cyklu życia oprogramowania w DevOps. Górna połowa to „dev" (planowanie, kod, budowanie, testy), dolna to „ops" (wydanie, wdrożenie, utrzymanie, monitoring). Kropka krąży, bo pętla nigdy się nie kończy: wnioski z monitoringu wracają do planowania.

Przejdźmy teraz przez tę pętlę od strony narzędzi. To najważniejsza część przewodnika, bo odpowiada wprost na pytanie „jakich narzędzi używa DevOps i do czego".

DevOps, CI/CD, SRE, GitOps, DevSecOps: co jest czym

Zanim wejdziemy w narzędzia, uporządkujmy pojęcia, które krążą razem z DevOps i bywają ze sobą mylone. Wszystkie należą do tej samej rodziny, ale każde odpowiada na trochę inne pytanie.

DevOps
Kultura i praktyki łączące tworzenie i utrzymanie oprogramowania. Parasol, pod którym mieści się reszta pojęć.
CI/CD
Ciągła integracja i ciągłe dostarczanie (ang. Continuous Integration / Continuous Delivery). Konkretna praktyka DevOps: automatyczny potok build, test, wdrożenie po każdej zmianie.
SRE
Site Reliability Engineering, podejście spopularyzowane przez Google. Utrzymanie traktowane jak inżynieria, z budżetem błędów (ang. error budget) i celami niezawodności (SLO).
Platform Engineering
Budowanie wewnętrznej platformy i gotowych ścieżek (ang. golden paths), z których programiści korzystają samodzielnie, bez proszenia „ops" o każdą drobnostkę.
GitOps
Git jako jedyne źródło prawdy o infrastrukturze. Stan systemu opisany deklaratywnie w repozytorium, a narzędzie samo doprowadza produkcję do tego stanu.
DevSecOps
DevOps z bezpieczeństwem wpiętym w potok od początku, a nie doklejanym na końcu. Skanowanie podatności jest częścią pipeline'u.
Sześć pojęć z jednej rodziny. DevOps jest parasolem kulturowym, a CI/CD, SRE, Platform Engineering, GitOps i DevSecOps to konkretne odpowiedzi na pytanie „jak robić DevOps dobrze".

W praktyce nie musisz wybierać jednego z nich. Firma może stosować DevOps jako kulturę, budować potoki CI/CD, prowadzić utrzymanie w duchu SRE, dawać programistom platformę i wdrażać zmiany w modelu GitOps, a przy tym mieć skanery bezpieczeństwa w każdym potoku. To wszystko warstwy tej samej filozofii.

Narzędzia DevOps: co, po co i jak wyglądają w praktyce

Nie istnieje jedno „narzędzie DevOps". Istnieje zestaw narzędzi, w którym każde obsługuje inny etap pętli. Poniższa mapa porządkuje je według zadania, a potem przejdziemy przez najważniejsze z nich z prawdziwymi wynikami z terminala.

🔄
Kontrola wersji
Git, GitHub, GitLab
⚙️
CI/CD
GitHub Actions, GitLab CI, Jenkins
🐳
Konteneryzacja
Docker, Podman, Buildah
Orkiestracja
Kubernetes, Helm
🏗️
Infrastruktura jako kod
Terraform, OpenTofu, Pulumi
📋
Zarządzanie konfiguracją
Ansible, Puppet, Chef
📊
Monitoring i logi
Prometheus, Grafana, Loki, Zabbix
🛡️
Bezpieczeństwo
Trivy, rejestry obrazów, skanery
☁️
Chmura i wirtualizacja
AWS, Azure, GCP, Proxmox
Mapa narzędzi DevOps według zadania. To nie jest lista „co trzeba umieć na pamięć", tylko podział pętli na etapy: każda kategoria odpowiada za inny fragment drogi od kodu do działającej usługi.

Git: kontrola wersji i źródło prawdy

Do czego służy: przechowuje historię każdej zmiany w kodzie i w konfiguracji, pozwala wielu osobom pracować równolegle na gałęziach i w każdej chwili cofnąć się do działającej wersji. W DevOps Git jest źródłem prawdy nie tylko dla aplikacji, ale i dla infrastruktury.

Git to rozproszony system kontroli wersji, czyli narzędzie, które zapamiętuje kolejne stany projektu jako „commity" (zapisane migawki zmian). Cała reszta łańcucha DevOps zaczyna się właśnie tutaj: potok CI/CD uruchamia się po zapisaniu zmiany, a w podejściu GitOps to zawartość repozytorium decyduje o tym, co ma działać na produkcji. Poniżej realna historia małego repozytorium z gałęzią funkcji i połączeniem jej z główną linią rozwoju:

Terminal z git log --graph pokazujący historię commitów z gałęzią i połączeniem oraz git status
Prawdziwa historia repozytorium w terminalu. Gałąź funkcji (feature/healthcheck) została połączona z główną linią (main) osobnym commitem scalającym. Na dole to samo repozytorium pokazuje polecenie git status: jeden zmodyfikowany plik czeka na zatwierdzenie.

Zwróć uwagę, że w tej historii są nie tylko commity z kodem aplikacji, ale też z plikami Dockera, manifestami Kubernetes i konfiguracją potoku CI/CD. To typowe dla DevOps: infrastruktura mieszka w tym samym repozytorium co aplikacja i podlega tym samym regułom, czyli przeglądowi zmian, historii i możliwości cofnięcia. Nie ma już „konfiguracji, która żyje tylko w głowie administratora".

CI/CD: automatyczny potok build, test i wdrożenie

Do czego służy: odbiera każdą zmianę z repozytorium i automatycznie ją buduje, testuje i (jeśli wszystko przejdzie) wdraża. Zamiast ręcznego, stresującego wdrożenia raz na kwartał, dostajesz powtarzalny proces, który można uruchamiać wielokrotnie dziennie.

CI/CD to skrót od ciągłej integracji (ang. Continuous Integration, czyli częstego scalania zmian i automatycznego sprawdzania, czy nic się nie zepsuło) oraz ciągłego dostarczania (ang. Continuous Delivery, czyli automatycznego przygotowania i wdrożenia gotowej wersji). Najpopularniejsze narzędzia to GitHub Actions, GitLab CI oraz Jenkins. Potok opisuje się jako plik w repozytorium. Oto minimalny, ale realny przepływ w GitHub Actions, który po każdej zmianie na gałęzi main buduje obraz i go wdraża:

name: build-and-deploy
on:
  push:
    branches: [main]
jobs:
  ship:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Testy
        run: pytest -q
      - name: Zbuduj i wypchnij obraz
        run: |
          docker build -t registry.example.com/sklep-api:${{ github.sha }} .
          docker push registry.example.com/sklep-api:${{ github.sha }}
      - name: Wdróż na klaster
        run: kubectl set image deploy/sklep-api sklep-api=registry.example.com/sklep-api:${{ github.sha }}

Ten plik to nie teoria. Wypchnęliśmy go do prawdziwego repozytorium, a GitHub Actions wykonał cały potok od początku do końca, bez naszej ingerencji:

GitHub Actions - przebieg potoku CI/CD z zielonymi krokami: testy, budowanie obrazu i wdrożenie
Realny przebieg potoku w GitHub Actions (nasze repozytorium demonstracyjne). Każdy krok, od testów po wdrożenie, zakończył się powodzeniem. Ostatni krok, „Wdroz obraz na srodowisko", to automatyczne wdrożenie zbudowanego obrazu do rejestru.

A tak wygląda log samego kroku wdrożenia z tego przebiegu. To już nie zapowiedź, tylko realny zapis publikacji gotowego obrazu:

Log kroku wdrożenia w GitHub Actions - publikacja obrazu do rejestru, kolejne warstwy Pushed
Log kroku wdrożenia z tego samego przebiegu GitHub Actions. Widać publikację kolejnych warstw obrazu do rejestru (Pushed) i końcowe potwierdzenie: wdrożenie zakończone sukcesem.

Chcesz zbudować własny potok CI/CD od commita po wdrożenie? Szkolenie GitHub Actions ma terminy gwarantowane.

Tam, gdzie potok jest bardziej rozbudowany albo firma woli własny serwer, króluje Jenkins. Poniżej realny widok tak zwanego stage view, czyli podziału jednego uruchomienia potoku na etapy z czasami wykonania. To dokładnie ten obraz, na który patrzy inżynier, gdy chce sprawdzić, na którym kroku potok się zatrzymał:

Jenkins stage view - kolejne etapy potoku CI/CD z czasami wykonania
Jenkins, widok etapów potoku (stage view). Każda kolumna to jeden krok potoku (pobranie kodu, budowanie, testy, publikacja obrazu, wdrożenie), a kolor i czas pokazują, czy krok się powiódł i jak długo trwał.

Gdy któryś krok zawiedzie, przechodzi się do konsoli danego uruchomienia i czyta logi. To pierwszy odruch przy diagnozie nieudanego wdrożenia:

Konsola Jenkinsa z logami uruchomienia potoku
Konsola pojedynczego uruchomienia w Jenkinsie. To surowe logi kolejnych poleceń potoku, od których zaczyna się każda diagnoza, gdy build lub wdrożenie się nie powiedzie.

Wolisz Jenkinsa na własnym serwerze? Szkolenie CI/CD w Jenkins ma terminy gwarantowane.

Docker: konteneryzacja, czyli koniec z „u mnie działa"

Do czego służy: pakuje aplikację razem ze wszystkimi zależnościami w jeden przenośny obraz (ang. image), który zachowuje się identycznie na laptopie programisty, w potoku CI i na produkcji. To rozwiązuje klasyczny problem „u mnie działa, a na serwerze nie".

Docker to najpopularniejsze narzędzie do konteneryzacji, czyli uruchamiania aplikacji w izolowanych, lekkich „pudełkach" zwanych kontenerami. Kontener różni się od maszyny wirtualnej tym, że nie nosi ze sobą całego systemu operacyjnego, tylko współdzieli jądro z hostem, dlatego startuje w ułamku sekundy. Aplikację opisuje się plikiem Dockerfile. Kluczowa dobra praktyka to budowanie wielostopniowe (ang. multi-stage build): w jednym etapie kompilujemy program z pełnym zestawem narzędzi, a do finalnego obrazu kopiujemy tylko gotowy plik wykonywalny.

# Etap budowania: pełne środowisko Go
FROM golang:1.23-alpine AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app .

# Etap finalny: pusty obraz tylko z binarką
FROM scratch
COPY --from=build /app /app
EXPOSE 8080
ENTRYPOINT ["/app"]

Efekt jest wymierny. Zbudowaliśmy ten sam program na dwa sposoby: naiwnie (cały obraz z narzędziami Go zostaje w środku) oraz wielostopniowo (do finalnego obrazu trafia sama binarka). Oto realne rozmiary z naszego terminala:

Terminal: docker images pokazujący obraz naiwny 472 MB i wielostopniowy 7,3 MB oraz warstwy docker history
Ten sam program zbudowany na dwa sposoby. Obraz naiwny (naive) waży 472 MB, bo zabiera ze sobą całe środowisko Go. Obraz wielostopniowy (multi) to zaledwie 7,3 MB, a docker history potwierdza dlaczego: w praktyce składa się z jednej warstwy, samej binarki o rozmiarze 5,08 MB.

Z 472 MB robi się 7,3 MB, czyli obraz kilkadziesiąt razy mniejszy. Mniejszy obraz to szybszy transfer, szybszy start i mniejsza powierzchnia ataku (o bezpieczeństwie za chwilę). Docker służy też do składania kilku usług w jedną całość poleceniem docker compose. Cały zestaw (serwer WWW, baza i pamięć podręczna) opisuje jeden plik compose.yaml, w którym deklarujemy też kontrolę kondycji usług (ang. healthcheck) i zależności między nimi:

services:
  web:
    image: nginx:alpine
    ports: ["8080:80"]
    depends_on:
      redis:
        condition: service_healthy    # startuj web dopiero, gdy redis jest zdrowy
  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      retries: 5
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: sekret
    volumes:
      - dbdata:/var/lib/postgresql/data
volumes:
  dbdata:

Po uruchomieniu poleceniem docker compose up -d Docker startuje wszystkie usługi we właściwej kolejności i pilnuje ich stanu:

Terminal: docker compose up i docker compose ps pokazujące start usług z kontrolą kondycji
docker compose uruchamia kilka usług naraz i pilnuje kolejności. Serwer WWW (web) wystartował dopiero po tym, jak pamięć podręczna (redis) zgłosiła stan Healthy. Wcześniej taką zależność trzeba było obsługiwać ręcznie.

Widać tu istotny szczegół: serwer WWW wystartował dopiero po tym, jak pamięć podręczna (redis) zgłosiła stan Healthy. To automatyzacja zależności między usługami, którą wcześniej trzeba było robić ręcznie. Jeśli interesuje Cię konteneryzacja konkretnej aplikacji krok po kroku, pokazaliśmy to na przykładzie osadzania aplikacji Flask na Dockerze.

Konteneryzację najłatwiej opanować, budując realne obrazy pod okiem praktyka. Szkolenie Docker i Kubernetes: od zera do bohatera ma terminy gwarantowane.

Kubernetes i Helm: orkiestracja kontenerów

Do czego służy: zarządza setkami kontenerów na wielu serwerach. Utrzymuje zadaną liczbę kopii aplikacji, sam restartuje te, które padły, rozkłada ruch i pozwala aktualizować wersję bez przerwy w działaniu. To „system operacyjny" nowoczesnej produkcji.

Gdy kontenerów jest kilka, wystarczy Docker. Gdy są ich setki na wielu maszynach, potrzebny jest dyrygent. Tym dyrygentem jest Kubernetes (często skracany do „K8s"), czyli system do orkiestracji kontenerów. W Kubernetesie nie mówisz „uruchom ten kontener", tylko opisujesz stan docelowy („chcę trzy działające kopie aplikacji"), a klaster sam do niego dąży i sam go pilnuje. Różnice między samym Dockerem a Kubernetesem rozłożyliśmy na części w osobnym tekście o tym, czym różni się Kubernetes od Dockera. Stan docelowy opisuje się deklaratywnie w pliku YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sklep-api
spec:
  replicas: 3                 # utrzymuj 3 kopie aplikacji
  selector:
    matchLabels: { app: sklep-api }
  template:
    metadata: { labels: { app: sklep-api } }
    spec:
      containers:
        - name: sklep-api
          image: registry.example.com/sklep-api:1.4.2
          resources:
            requests: { cpu: "100m", memory: "128Mi" }
            limits:   { cpu: "500m", memory: "256Mi" }

Poniżej prawdziwa sesja na działającym klastrze. Do przykładów użyliśmy k3s, czyli lekkiej, w pełni zgodnej dystrybucji Kubernetesa (to nadal Kubernetes, tyle że w wersji idealnej do nauki na laptopie, co widać w kolumnie VERSION jako v1.34.1+k3s1). Uruchamiamy aplikację w trzech kopiach, klaster sam doprowadza ją do stanu gotowości, a na końcu skalujemy do pięciu kopii jednym poleceniem:

Terminal: kubectl get nodes, create deployment, rollout status, get pods i scale na żywym klastrze
Prawdziwa sesja na działającym klastrze Kubernetes (jeden lokalny węzeł, lekka dystrybucja k3s). Uruchamiamy aplikację w trzech kopiach, klaster sam doprowadza wdrożenie do gotowości (rollout status), a jedno polecenie kubectl scale zmienia liczbę kopii z trzech na pięć.

To jest właśnie „samonaprawa" i skalowanie w praktyce: gdyby któraś kopia padła, Kubernetes od razu uruchomiłby nową, żeby utrzymać zadaną liczbę. Konfiguracje dla całych aplikacji pakuje się dodatkowo w Helm, czyli menedżer pakietów dla Kubernetesa. Zamiast trzymać dziesiątki plików YAML, instalujesz aplikację jak paczkę: helm install sklep-api ./chart, a aktualizujesz przez helm upgrade. Helm pozwala też jednym poleceniem cofnąć się do poprzedniej wersji, gdy coś pójdzie nie tak.

Chcesz swobodnie zarządzać Kubernetesem na realnym klastrze? Szkolenie Kubernetes: orkiestracja kontenerów ma terminy gwarantowane.

Terraform: infrastruktura jako kod

Do czego służy: tworzy i zmienia infrastrukturę (serwery, sieci, bazy, klastry) na podstawie plików tekstowych, zamiast klikania w panelu chmury. Dzięki temu infrastruktura jest powtarzalna, wersjonowana w Git i można ją recenzować jak każdy inny kod.

Terraform to najpopularniejsze narzędzie do podejścia zwanego infrastrukturą jako kod (ang. Infrastructure as Code). Opisujesz w plikach, co ma istnieć, a Terraform sam wylicza, co dodać, zmienić lub usunąć, żeby rzeczywistość zgadzała się z opisem. Opis jest krótki i czytelny. Poniższy fragment mówi po prostu: „ma istnieć kontener z serwerem nginx dostępny na porcie 8095":

resource "docker_container" "web" {
  name  = "tf-web"
  image = docker_image.nginx.image_id
  ports {
    internal = 80
    external = 8095
  }
}

Najważniejsze jest to, że Terraform najpierw pokazuje plan, a dopiero po akceptacji go wykonuje. Nigdy nie zmienia niczego bez uprzedzenia. Oto prawdziwe uruchomienie na naszym środowisku, gdzie Terraform tworzy obraz i kontener:

Terminal: terraform plan, apply i state list tworzące obraz oraz kontener
Terraform w działaniu. Najpierw plan („Plan: 2 to add"), po którym dokładnie wiesz, co się wydarzy, a dopiero potem apply, który tworzy zasoby („Apply complete! Resources: 2 added"). Na końcu state list pokazuje, czym Terraform teraz zarządza.

Zdanie Plan: 2 to add, 0 to change, 0 to destroy to serce Terraform. Zanim cokolwiek się wydarzy, widzisz dokładnie, co narzędzie zamierza zrobić. Uruchomione ponownie na niezmienionym opisie, Terraform nie zrobi nic (bo rzeczywistość już się zgadza). Ta właściwość, zwana idempotencją, oznacza, że to samo polecenie wykonane wielokrotnie daje ten sam stan końcowy.

Infrastrukturę jako kod najszybciej przyswoisz w praktyce, na własnym stanie i planach. Szkolenie Terraform i infrastruktura jako kod ma terminy gwarantowane.

Ansible: zarządzanie konfiguracją serwerów

Do czego służy: konfiguruje serwery i instaluje na nich oprogramowanie według opisu w prostym pliku, na wielu maszynach naraz i zawsze do tego samego stanu. Terraform tworzy serwer, a Ansible sprawia, że jest poprawnie skonfigurowany.

Ansible uzupełnia Terraform. Gdzie Terraform odpowiada za powołanie infrastruktury, tam Ansible dba o to, co jest na serwerach: instaluje pakiety, kopiuje konfiguracje, zakłada użytkowników, uruchamia usługi. Opis zadań, zwany „playbookiem", jest czytelny nawet dla osoby, która nie zna narzędzia: to lista kroków z jasnymi nazwami. Poniżej fragment playbooka konfigurującego serwer aplikacji:

- name: Konfiguracja serwera aplikacji Sklep API
  hosts: web
  become: true
  tasks:
    - name: Zapewnij katalog konfiguracji
      ansible.builtin.file:
        path: /etc/sklep
        state: directory

    - name: Utworz systemowego uzytkownika aplikacji
      ansible.builtin.user:
        name: sklep
        system: true

Playbook uruchamia się jednym poleceniem, a Ansible na końcu pokazuje raport (ang. PLAY RECAP) z liczbą zadań wykonanych i zmienionych. Oto prawdziwy wynik uruchomienia naszego playbooka:

Terminal: ansible-playbook z zadaniami changed i podsumowaniem PLAY RECAP ok=5 changed=3
Prawdziwe uruchomienie playbooka. Każde zadanie ma jasny status (tutaj changed, czyli Ansible coś zmienił), a końcowy raport PLAY RECAP podsumowuje: pięć zadań wykonanych, trzy wprowadziły zmiany, zero błędów.

Podobnie jak Terraform, Ansible jest idempotentny. Uruchomiony ponownie na już skonfigurowanym serwerze pokaże changed=0, bo nie będzie miał nic do zmiany. To dlatego DevOps tak ceni te narzędzia: opisujesz stan docelowy raz, a potem możesz go egzekwować w kółko, na jednym serwerze albo na tysiącu, zawsze z tym samym skutkiem.

Automatyzację konfiguracji serwerów warto przećwiczyć na realnych maszynach. Szkolenie Automatyzacja zadań z Ansible ma terminy gwarantowane.

Prometheus, Grafana i Loki: monitoring i obserwowalność

Do czego służy: pokazuje, co dzieje się z systemem w czasie rzeczywistym. Prometheus zbiera metryki (liczby, na przykład zużycie procesora), Grafana rysuje z nich pulpity, Loki centralizuje logi, a reguły alertów budzą inżyniera, zanim zauważy to klient.

Nie da się utrzymywać systemu, którego się nie widzi. Ta warstwa nazywa się obserwowalnością (ang. observability), czyli zdolnością odpowiedzenia na pytanie „dlaczego to się dzieje" na podstawie danych, które system o sobie udostępnia. Prometheus to baza czasowa, która co kilkanaście sekund odpytuje aplikacje i serwery o ich metryki. Najpierw sprawdza się, czy w ogóle ma z czego zbierać dane, na liście celów (ang. targets):

Prometheus - lista celów (targets) z których zbierane są metryki
Prometheus, lista celów. Każdy wiersz to źródło metryk (aplikacja lub eksporter), a status w kolumnie State mówi, czy Prometheus poprawnie się z nim łączy i zbiera dane.

Metryki odpytuje się językiem PromQL. Poniższe zapytanie liczy udział odpowiedzi z błędem serwera (kody 5xx) w całym ruchu, czyli klasyczny wskaźnik „czy usługa się psuje":

# Udział odpowiedzi 5xx w całym ruchu usługi (ostatnie 5 minut)
sum(rate(http_requests_total{service="sklep-api",status=~"5.."}[5m]))
  /
sum(rate(http_requests_total{service="sklep-api"}[5m]))

Prosty wykres w samym Prometheusie to już duży krok. Ten sam ruch przedstawiony graficznie od razu pokazuje, kiedy zaczął się problem i czy sam wrócił do normy:

Wykres metryki w interfejsie Prometheusa - zmiana wartości w czasie
Metryka narysowana w czasie w interfejsie Prometheusa. Na wykresie łatwo dostrzec zarówno chwilowy skok, jak i powolny trend, czego z surowych liczb nie widać.

Prometheus rysuje proste wykresy, ale prawdziwe, bogate pulpity buduje się w Grafanie, czyli narzędziu do wizualizacji danych. Pulpit Grafany widzisz już na samej górze tego artykułu: ten kolorowy zestaw wskaźników i wykresów kondycji serwera to właśnie ona. Grafanie poświęciliśmy osobny, szczegółowy przewodnik, więc jeśli chcesz nauczyć się budować takie pulpity od zera, przeczytaj czym jest Grafana w przewodniku dla początkujących.

Sam wykres to za mało. Metryki mają sens dopiero wtedy, gdy potrafią samodzielnie zawołać o pomoc. Do tego służą reguły alertów i menedżer alertów (ang. Alertmanager), który wysyła powiadomienie na wskazany kanał, gdy przekroczony zostanie próg. Poniżej realny, wyzwolony alert po polsku:

Alertmanager - aktywny, wyzwolony alert o wysokim zużyciu CPU
Alertmanager z aktywnym alertem. Gdy reguła (tutaj wysokie zużycie procesora) zostaje spełniona przez zadany czas, alert zmienia stan na aktywny i trafia do wskazanego kanału, na przykład na e-mail albo do komunikatora zespołu.

Do metryk dochodzą jeszcze logi (zapisy zdarzeń), które centralizuje Loki albo starszy, ale wciąż popularny stos ELK (Elasticsearch, Logstash, Kibana). Metryki mówią „coś jest nie tak", a logi odpowiadają „dlaczego". Razem tworzą obserwowalność, bez której DevOps byłby lataniem po ciemku.

Cały stos monitoringu w jednym miejscu, na żywej infrastrukturze: Szkolenie Monitoring i Observability: Grafana, Prometheus, Loki, Zabbix ma terminy gwarantowane.

DevSecOps: bezpieczeństwo wpięte w potok

Do czego służy: wykrywa znane podatności w obrazach i zależnościach automatycznie, na etapie budowania, zanim aplikacja trafi na produkcję. Bezpieczeństwo staje się częścią potoku, a nie odrębnym audytem raz do roku.

DevSecOps to DevOps, w którym bezpieczeństwo „przesunięto w lewo", czyli jak najbliżej początku procesu. Zamiast sprawdzać aplikację dopiero przed wdrożeniem, skanuje się ją przy każdym budowaniu. Popularnym skanerem jest Trivy, który wyszukuje znane podatności (ang. CVE) w obrazie. Świetnie pokazuje też, dlaczego wybór podstawowego obrazu ma znaczenie. Przeskanowaliśmy dwa warianty tego samego serwera WWW, pełny (oparty na systemie Debian) i odchudzony (oparty na Alpine):

Terminal: trivy skanuje obraz nginx pełny (126 podatności) i odchudzony (35 podatności)
Skan podatności narzędziem Trivy. Ten sam serwer WWW: wariant pełny (oparty na Debianie) ma 126 poważnych podatności, a odchudzony (oparty na Alpine) tylko 35. Sam wybór chudszego obrazu podstawowego drastycznie zmniejsza powierzchnię ataku.

Ta sama aplikacja, a liczba poważnych podatności spada ze 126 do 35 tylko dlatego, że wybraliśmy chudszy obraz podstawowy. To jest DevSecOps w pigułce: bezpieczeństwo nie jest osobnym etapem na końcu, tylko konsekwencją dobrych decyzji podejmowanych po drodze i pilnowanych automatycznie. Skany takie jak ten wpina się wprost do potoku CI/CD, który potrafi zatrzymać wdrożenie, gdy pojawi się nowa krytyczna podatność.

Chmura i wirtualizacja: fundament, na którym to wszystko stoi

Do czego służy: dostarcza moc obliczeniową na żądanie. Zamiast kupować serwery na lata, wynajmujesz dokładnie tyle, ile potrzebujesz, i płacisz za użycie, a Terraform tworzy to wszystko kodem.

Cała pętla DevOps musi na czymś działać. Najczęściej jest to chmura publiczna: Amazon Web Services (AWS), Microsoft Azure lub Google Cloud (GCP). Chmura daje infrastrukturę na żądanie, rozliczaną za faktyczne użycie, i to z nią najczęściej rozmawia Terraform. Alternatywą (albo uzupełnieniem) jest wirtualizacja na własnym sprzęcie, na przykład Proxmox, popularny do budowy domowego lub firmowego laboratorium. Dla nauki DevOps nie potrzebujesz jednak od razu chmury: pełny klaster Kubernetes postawisz lokalnie na laptopie, dokładnie tak, jak zrobiliśmy to na potrzeby przykładów w tym artykule.

Jak to wszystko gra razem: od commita do produkcji

Pojedyncze narzędzia to dopiero połowa historii. Prawdziwa siła DevOps bierze się z tego, że układają się one w jeden ciągły potok. Prześledźmy drogę zwykłej zmiany w kodzie, od momentu zapisania jej przez programistę do chwili, gdy działa na produkcji i jest obserwowana:

🔄
Commit
Git
⚙️
Build + test
CI/CD
🐳
Obraz
Docker
🛡️
Skan
Trivy
Wdrożenie
Kubernetes
📊
Monitoring
Grafana
Droga jednej zmiany przez potok DevOps. Kod z Gita uruchamia potok CI/CD, który buduje obraz Dockera, skanuje go pod kątem podatności, wdraża na Kubernetes, a Prometheus i Grafana od razu zaczynają go obserwować. Wnioski z monitoringu wracają do planowania kolejnej zmiany.
  1. Commit (Git). Programista zapisuje zmianę i wypycha ją do repozytorium. To wyzwala resztę.
  2. Build i testy (CI/CD). Potok automatycznie pobiera kod, uruchamia testy i buduje aplikację. Jeśli testy nie przejdą, proces się zatrzymuje i nikt nie musi tego pilnować ręcznie.
  3. Obraz (Docker). Z aplikacji powstaje przenośny obraz kontenera, otagowany identyfikatorem tej konkretnej zmiany.
  4. Skan bezpieczeństwa (Trivy). Obraz jest skanowany pod kątem znanych podatności. Krytyczne znaleziska mogą zatrzymać wdrożenie.
  5. Wdrożenie (Kubernetes). Klaster stopniowo zastępuje starą wersję nową, pilnując, żeby usługa ani na chwilę nie przestała odpowiadać.
  6. Monitoring (Prometheus i Grafana). Od pierwszej sekundy nowa wersja jest obserwowana. Jeśli wzrośnie liczba błędów, alert obudzi zespół, a wnioski wrócą do planowania.

Zwróć uwagę, że w całym tym łańcuchu człowiek podejmuje jedną świadomą decyzję: zapisuje dobrą zmianę w kodzie. Resztę wykonują narzędzia. To jest właśnie automatyzacja, o której mówi „A" w skrócie CALMS, i to ona odróżnia dojrzały DevOps od ręcznego wdrażania „na piechotę".

Do czego DevOps przydaje się firmie (i inżynierowi)

Cała ta maszyneria nie jest sztuką dla sztuki. DevOps ma mierzalny cel: dostarczać oprogramowanie szybciej i stabilniej zarazem, co przez lata wydawało się sprzecznością. Najczęściej używa się do tego czterech wskaźników znanych jako metryki DORA (od nazwy zespołu badawczego, który je spopularyzował). Opisują one, jak sprawnie organizacja dowozi zmiany:

Częstotliwość wdrożeń
Jak często dowozimy zmiany. Najlepsze zespoły wdrażają wielokrotnie dziennie.
Czas od kodu do produkcji
Ile mija od zapisania zmiany do jej działania. Cel: godziny, nie tygodnie.
Czas naprawy awarii (MTTR)
Jak szybko wracamy do sprawności po awarii. Cel: minuty, nie dni.
Odsetek nieudanych zmian
Jaka część wdrożeń kończy się awarią. Im mniej, tym dojrzalszy proces.
Cztery metryki DORA. DevOps dąży do tego, by pierwsza z nich rosła (wdrażamy częściej), a trzy pozostałe malały (szybciej, stabilniej, z mniejszą liczbą wpadek). Dobre zespoły poprawiają je wszystkie naraz, bo automatyzacja jednocześnie przyspiesza i zabezpiecza.

Przełóżmy to na konkret. Dla firmy DevOps oznacza szybsze dostarczanie nowych funkcji (a więc szybszą reakcję na rynek), mniej awarii i krótsze przestoje, powtarzalność (nowe środowisko stawia się z kodu w minuty, a nie w dni) oraz przewidywalne koszty infrastruktury. Dla inżyniera to mniej nudnej, ręcznej pracy i gaszenia pożarów, a więcej budowania rzeczy, które sprawiają, że pożary w ogóle nie wybuchają. To także jeden z najlepiej opłacanych i najbardziej poszukiwanych zestawów umiejętności w branży.

Od czego zacząć naukę DevOps

Skoro wiesz już, czym DevOps jest i z czego się składa, naturalne pytanie brzmi „od czego zacząć". Najważniejsza zasada to właściwa kolejność. Najczęstszy błąd to rzucanie się od razu na Kubernetes, bo wygląda najatrakcyjniej. Bez fundamentów jest jednak ścianą niezrozumiałych skrótów. Sensowna droga wygląda tak:

  1. Fundamenty: Linux (bo serwery i kontenery to w większości Linux), sieci, Git i jeden język skryptowy (najczęściej Python albo Bash).
  2. Konteneryzacja i orkiestracja: najpierw Docker, potem Kubernetes. W tej kolejności, nie odwrotnie.
  3. Automatyzacja i infrastruktura jako kod: potoki CI/CD oraz Terraform i Ansible.
  4. Chmura i monitoring: jedna chmura (AWS lub Azure) plus Prometheus i Grafana.

Najlepiej uczyć się na własnym laboratorium. Pełny klaster Kubernetes uruchomisz lokalnie w minutę, a jeśli masz stary komputer lub domowy serwer, postaw na nim Proxmoxa i kilka maszyn wirtualnych, żeby przećwiczyć wszystko od instalacji po symulowaną awarię. Kompletną, rozpisaną na fazy drogę wraz z realnymi widełkami zarobków opisaliśmy osobno, w przewodniku o tym, jak zostać inżynierem DevOps od zera.

Podsumowanie

DevOps to nie narzędzie ani stanowisko, tylko sposób pracy: kultura wspólnej odpowiedzialności za oprogramowanie, wsparta automatyzacją całej pętli od pomysłu po monitoring działającej usługi. Narzędzia, o których mowa, nie są celem samym w sobie, tylko odpowiedziami na konkretne pytania. Git pilnuje historii i jest źródłem prawdy. CI/CD automatyzuje build, testy i wdrożenie. Docker pakuje aplikację, a Kubernetes nią dyryguje na produkcji. Terraform i Ansible zamieniają infrastrukturę w kod. Prometheus i Grafana sprawiają, że widać, co się dzieje, a Trivy pilnuje bezpieczeństwa po drodze. Razem tworzą one potok, w którym zwykła zmiana w kodzie sama płynie przez budowanie, testy, skan, wdrożenie i monitoring, a człowiek podejmuje tylko decyzje, które naprawdę wymagają jego uwagi. To właśnie jest DevOps i do tego on służy.

Szkolenia DevOps JSystems
DevOps — kompleksowe szkolenie z praktykiem Warsztaty z Dockera, Kubernetes, Ansible, Terraform, CI/CD i monitoringu na realnej infrastrukturze. Uczysz się dokładnie tych narzędzi, które pokazaliśmy w tym artykule. Terminy gwarantowane. Przyjdź na szkolenie DevOps -->

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...