Kestra, przepływy w YAML i wiele języków
Kestra to platforma do orkiestracji przepływów, w której definicja przepływu jest dokumentem w YAML, a zadania wykonują się w dowolnym języku. Bieżąca linia wydań nosi numer 1.3 i jest rozwijana od marca 2026 roku, a licencja silnika to Apache 2.0.
Ta jedna decyzja projektowa odróżnia je od narzędzi, w których przepływ jest kodem w konkretnym języku, i pociąga za sobą wszystkie pozostałe różnice. Warto ją zrozumieć, zanim porównasz cokolwiek innego.
Przepływ jako dokument, a nie kod
W narzędziach opartych o jeden język przepływ jest funkcją albo klasą, więc żeby go przeczytać, trzeba znać ten język. Tutaj przepływ jest opisem struktury, a kod siedzi wewnątrz zadań.
id: import-dzienny
namespace: dane.produkcja
tasks:
- id: pobierz
type: io.kestra.plugin.scripts.python.Script
script: |
import requests
dane = requests.get("https://api.example.com/zamowienia").json()
print(len(dane))
- id: przeksztalc
type: io.kestra.plugin.jdbc.postgresql.Query
sql: INSERT INTO raport SELECT * FROM staging WHERE data = CURRENT_DATE
triggers:
- id: codziennie
type: io.kestra.plugin.core.trigger.Schedule
cron: "0 3 * * *"Struktura jest widoczna od razu: co po czym, co uruchamia całość, gdzie leży granica między krokami. Zadanie pierwsze uruchamia Pythona, drugie wykonuje zapytanie w bazie, i nikt nie musi znać obu, żeby zrozumieć przepływ.
Konsekwencje są dwie i obie realne.
Pierwsza jest organizacyjna. Przepływ da się przeczytać osobie, która nie programuje w języku zadań: analitykowi, administratorowi, osobie odbierającej pracę. Przy zespołach mieszanych to bywa ważniejsze niż elegancja kodu.
Druga jest techniczna i mniej przyjemna. Logika wyrażona w dokumencie jest uboższa niż logika w języku programowania. Warunek albo pętla dają się zapisać, natomiast rozbudowana logika sterująca w YAML robi się nieczytelna szybciej, niż wynikałoby z liczby linii.
Wielojęzyczność jako sedno
Skoro kod siedzi wewnątrz zadań, język przestaje być wyborem na poziomie całego narzędzia.
Jeden przepływ może uruchamiać skrypt Pythona, zapytanie w bazie, polecenie powłoki, kontener z gotowym obrazem i wywołanie zewnętrznego interfejsu. To nie są obejścia, tylko normalne typy zadań.
Zysk widać w organizacjach, w których dane przechodzą przez kilka zespołów. Analitycy piszą zapytania, inżynierowie skrypty, a zespół platformowy uruchamia kontenery, i wszystko mieści się w jednym przepływie zamiast w trzech systemach spiętych wywołaniami.
Wtyczek jest kilkanaście setek i to jest liczba warta odnotowania, bo określa, jak dużo z tego dostajesz gotowe. Połączenie z typową bazą, magazynem plików w chmurze albo systemem kolejkowym jest zwykle wpisem w dokumencie, a nie kodem, który trzeba napisać.
Warto natomiast pamiętać, że wtyczka to zależność jak każda inna. Przy rzadziej używanych warto sprawdzić, kiedy ostatnio były aktualizowane, bo katalog tej wielkości nie jest jednorodny pod względem dbałości.
Zdarzenia i wyzwalacze
Przepływ da się uruchomić harmonogramem, i to jest wariant oczywisty. Ciekawsze są pozostałe.
Wyzwalacz zdarzeniowy reaguje na pojawienie się pliku w magazynie, na wiadomość w kolejce, na zmianę w bazie albo na wywołanie interfejsu. Dzięki temu przepływ startuje wtedy, gdy jest co robić, a nie wtedy, gdy wypadł termin.
Wyzwalacz oparty o zakończenie innego przepływu pozwala budować łańcuchy bez sztucznych opóźnień. To jest rzecz, którą przy harmonogramie systemowym ludzie rozwiązują ustawianiem drugiego zadania piętnaście minut później i modleniem się, żeby pierwsze zdążyło.
Osobno warto znać wyzwalacz odpytujący, bo ma cechę zaskakującą przy liczeniu obciążenia. Sprawdza źródło w ustalonych odstępach niezależnie od tego, czy coś się zmieniło, więc przy kilku takich przepływach system pracuje stale, choć nic się nie dzieje.
Przy projektowaniu warto zacząć od pytania, co właściwie ma uruchomić przepływ. Odpowiedź „codziennie o trzeciej" bywa uproszczeniem czegoś, co naprawdę znaczy „gdy pojawią się dane z poprzedniego dnia", a te dwie rzeczy zachowują się inaczej, gdy dane się spóźnią.
Edycja otwarta i komercyjna
Podział jest tu wyraźny i warto go znać przed wdrożeniem w firmie.
Wersja otwarta na licencji Apache 2.0 obejmuje silnik, interfejs i większość wtyczek, czyli wszystko, co potrzebne do uruchomienia przepływów. To nie jest wersja okrojona do demonstracji, tylko działające narzędzie. Katalog wtyczek dzieli się jednak na dwie części i garść pozycji oznaczonych jako firmowe wymaga edycji komercyjnej, więc przy nietypowej integracji warto to sprawdzić przed decyzją.
Wersja komercyjna dokłada rzeczy potrzebne organizacji, a nie zespołowi: logowanie przez firmowy system tożsamości, uprawnienia oparte o role, wsparcie z gwarancją czasu reakcji oraz mechanizmy zarządzania wieloma zespołami na jednej instalacji.
Podział nie jest jednak dwudzielny, bo obok instalacji własnej producent prowadzi też wariant zarządzany. Kestra Cloud to ta sama platforma utrzymywana po stronie dostawcy, z wtyczkami firmowymi w cenie i rozliczeniem rosnącym wraz z użyciem, natomiast dostęp przyznawany jest na wniosek, więc nie jest to usługa, w której zakładasz konto w pięć minut.
Praktyczny wniosek jest prosty. Zespół uruchamiający przepływy dla siebie obejdzie się wersją otwartą i nie straci na tym nic istotnego. Organizacja, w której z jednej instalacji korzysta pięć zespołów o różnych uprawnieniach, potrzebuje kontroli dostępu, a ta jest po stronie komercyjnej.
Warto tę granicę sprawdzić na własnym przypadku przed decyzją, bo lista rzeczy przypisanych do każdej edycji zmienia się między wydaniami.
Przekazywanie danych między zadaniami
To jest miejsce, w którym podejście oparte o dokument różni się od kodu najbardziej, i warto je zrozumieć, bo tu powstaje najwięcej pomyłek.
W kodzie wynik funkcji przekazuje się dalej jako wartość. Tutaj zadania są od siebie odizolowane, więc wynik jednego trafia do magazynu, a kolejne odwołuje się do niego przez wyrażenie wskazujące na identyfikator zadania i nazwę wyjścia.
Praktyczny skutek jest podwójny. Zadania mogą działać w różnych językach i na różnych maszynach, bo nie dzielą pamięci. Oraz: przekazywanie danych ma koszt, bo przechodzą przez magazyn, a nie przez zmienną.
Stąd wynika reguła, którą warto przyjąć od początku. Przekazuj identyfikatory i ścieżki, a nie zawartość. Zadanie pobierające milion rekordów powinno zapisać je do bazy albo do pliku i przekazać dalej wskazanie, a nie całą tablicę. Przekazywanie dużych struktur przez magazyn działa i przestaje działać przy skali, przy której nikt się tego nie spodziewa.
Druga rzecz to zmienne i wyrażenia. Dokument obsługuje szablony pozwalające sięgać po datę przebiegu, parametry wejściowe i wyniki poprzednich zadań. To jest wygodne i kuszące do nadużycia: wyrażenie z trzema zagnieżdżonymi warunkami w polu tekstowym jest kodem napisanym w najgorszym możliwym miejscu.
Praktyczna granica brzmi tak: wyrażenie wybierające wartość albo składające ścieżkę jest w porządku, a wyrażenie podejmujące decyzję biznesową powinno być zadaniem ze skryptem, który da się przeczytać i przetestować.
Obsługa błędów i ponawianie
Warto opisać, co dostajesz gotowe, bo to jest główny powód sięgania po orkiestrator zamiast po harmonogram systemowy.
Ponawianie deklaruje się przy zadaniu: liczba prób, odstęp i sposób jego narastania. Zadanie sięgające po zewnętrzny interfejs, który bywa niedostępny, dostaje trzy próby, i to jest kilka linii w dokumencie zamiast pętli w kodzie.
Zadania obsługujące błąd uruchamiają się wtedy, gdy coś poszło nie tak, i pozwalają posprzątać albo powiadomić właściwą osobę. To jest różnica wobec sytuacji, w której przepływ po prostu się zatrzymuje, a informacja trafia do dziennika, do którego nikt nie zagląda.
Ograniczenie współbieżności działa na poziomie przepływu i na poziomie zadania. Przepływ uruchamiany co pięć minut, który czasem trwa siedem, bez tego ograniczenia będzie miał dwa przebiegi naraz, a przy zapisie do tej samej tabeli to zwykle nie jest to, o co chodziło.
Ostatnia rzecz to obsługa opóźnień i przerw. Zadanie może poczekać określony czas, może zatrzymać przepływ do momentu spełnienia warunku, a przy procesach z udziałem człowieka może czekać na zatwierdzenie. Oczekiwanie nie zajmuje przy tym zasobów wykonawczych, co przy własnym rozwiązaniu wymagałoby trwałego stanu i mechanizmu wznawiania.
Kestra kontra alternatywy
| Rozwiązanie | Opis przepływu | Języki zadań | Kiedy wybrać |
|---|---|---|---|
| Kestra | Dokument YAML | Dowolne | Zespoły mieszane, wiele technologii |
| Prefect | Funkcja w Pythonie | Python | Zespół pythonowy, testowanie przepływów |
| Airflow | Graf w Pythonie | Python plus operatory | Duży zespół, ustalone praktyki |
| Temporal | Kod z gwarancją trwałości | Kilka języków | Długie procesy biznesowe |
Porównanie z drugim wierszem jest tu najbardziej pouczające, bo oba narzędzia rozwiązują ten sam problem przeciwnymi środkami.
Tam przepływ jest funkcją, więc da się go wywołać w teście, a pełna moc języka jest dostępna. Tutaj przepływ jest dokumentem, więc czyta go każdy, a zadania mogą być w czymkolwiek. Wybór sprowadza się do pytania, czy Twoim ograniczeniem jest złożoność logiki, czy różnorodność technologii i osób.
Praktyczna wskazówka: przy zespole pythonowym budującym potoki danych drugi wiersz zwykle wygrywa wygodą. Przy organizacji, w której przepływ dotyka bazy, kontenera, skryptu powłoki i trzech zespołów, pierwszy wygrywa czytelnością.
Czwarty wiersz rozwiązuje inny problem i mylenie ich jest częste. Tam chodzi o procesy trwające dniami z gwarancją przetrwania awarii, tutaj o powtarzalne przetwarzanie z widocznością i ponawianiem.
Uruchomienie i utrzymanie
Do działania potrzebujesz samego serwera oraz bazy danych na stan, zwykle PostgreSQL. Przy większej skali dochodzi kolejka i osobne procesy wykonawcze.
Wdrożenie zaczyna się zwykle od pojedynczego kontenera z bazą wbudowaną, co wystarcza do sprawdzenia narzędzia w godzinę. Do produkcji warto od razu ustawić bazę zewnętrzną, bo migracja stanu później jest pracą, której nikt nie planuje.
Przepływy warto trzymać w repozytorium i wdrażać automatycznie, a nie edytować w interfejsie. Wbudowany edytor jest wygodny do prób i kuszący na produkcji, natomiast zmiana wprowadzona przez interfejs nie przechodzi przez przegląd i nie ma jej w historii projektu.
Warto też od początku ustalić podział na przestrzenie nazw. Przy dwudziestu przepływach wszystko wygląda dobrze niezależnie od struktury, a przy dwustu brak podziału na obszary sprawia, że lista przestaje być użyteczna.
Ostatnia rzecz to zapisywanie wyników zadań. Wyjście zadania trafia do magazynu i jest dostępne dla kolejnych kroków, co jest wygodne i rośnie w czasie. Polityka usuwania starych przebiegów jest tu obowiązkowa, a nie opcjonalna.
Typowe błędy
Pierwszy to wyrażanie skomplikowanej logiki sterującej w dokumencie. Warunki i pętle działają, natomiast rozbudowana logika w YAML staje się nieczytelna, a właściwym miejscem jest wtedy skrypt wewnątrz zadania.
Drugi to edytowanie przepływów produkcyjnych w interfejsie. Zmiana wchodzi natychmiast, nie przechodzi przez przegląd i nie zostawia śladu w historii projektu.
Trzeci to harmonogram tam, gdzie właściwe jest zdarzenie. Przepływ uruchamiany o stałej porze przetwarza dane, które mogły jeszcze nie dotrzeć, i awaria wygląda na losową.
Czwarty to wyzwalacze odpytujące w większej liczbie. System pracuje stale, choć nic się nie dzieje, a obciążenie rośnie liniowo z liczbą takich przepływów.
Piąty to brak polityki usuwania starych przebiegów i wyników. Magazyn rośnie w tempie zależnym od rozmiaru danych, a nie od liczby zadań.
Szósty to instalacja produkcyjna na bazie wbudowanej. Działa do pierwszego restartu przy większym obciążeniu, a przeniesienie stanu później jest osobnym przedsięwzięciem.
Siódmy to przekazywanie dużych zbiorów danych między zadaniami zamiast identyfikatorów. Wszystko przechodzi przez magazyn, więc rozwiązanie działające przy tysiącu rekordów przestaje działać przy milionie, i to bez wyraźnego progu ostrzegawczego.
FAQ
Czym Kestra różni się od Prefecta?
Sposobem opisania przepływu. Tutaj przepływ jest dokumentem w YAML, a zadania mogą być w dowolnym języku, więc czyta go także osoba nieprogramująca. W Prefekcie przepływ jest funkcją w Pythonie, co daje pełną moc języka i możliwość przetestowania przez wywołanie.
Czy wersja otwarta wystarczy na produkcję?
Tak, obejmuje silnik, interfejs i większość wtyczek na licencji Apache 2.0. Wersja komercyjna dokłada logowanie przez firmowy system tożsamości, uprawnienia oparte o role, wtyczki zastrzeżone dla firm i wsparcie z gwarancją czasu reakcji, czyli rzeczy potrzebne organizacji, a nie pojedynczemu zespołowi. Osobno istnieje wariant zarządzany przez producenta, Kestra Cloud.
W jakich językach piszę zadania?
W dowolnym, bo kod siedzi wewnątrz zadania. Jeden przepływ może uruchamiać skrypt Pythona, zapytanie w bazie, polecenie powłoki i kontener, a wtyczek do typowych systemów jest kilkanaście setek.
Czy da się to wersjonować jak kod?
Tak, i tak należy. Przepływy warto trzymać w repozytorium i wdrażać automatycznie, bo edycja w interfejsie omija przegląd i nie zostawia śladu w historii projektu. Wbudowany edytor jest wygodny do prób, a nie do produkcji.
Czego potrzebuję do uruchomienia?
Serwera i bazy danych na stan, w praktyce PostgreSQL. Do prób wystarczy pojedynczy kontener z bazą wbudowaną, natomiast do produkcji warto od razu ustawić bazę zewnętrzną, bo przeniesienie stanu później jest osobnym zadaniem.
Dokumentacja stoi na stronie projektu, a wydania w repozytorium na GitHubie.