CI/CD s CircleCi a Kubernetes

CI (Continuous Integration) je praxe vývoje softwaru, která je založena na časté integraci kódu do sdíleného repositáře. Hlavním cílem CI je dříve a snadněji identifikovat problémy, které se mohou během vývoje SW objevit. Pokud se pravidelně a často spouští testovaný kód, je při kontrole objeveno mnohem méně chyb. Výsledkem je méně času stráveného laděním a více času pro přidání funkcí.

Liftago tým tvoří 4 backendisti, tester a 3 mobilní vývojáři. Backend se u nás skládá z aplikací napsaných v Javě, Kotlinu, JavaScript a chatbot v Golang. I v tak relativně malém týmu vydáváme na produkci několikrát za den. Testy nám běží na CI nástroji v cloudu, kde se i vytváří Docker kontejner, který je automaticky releasnut na testovací prostředí.

Používáme lehce upravený a zjednodušený GitFlow, kde master HEAD je verze na testovacím prostředí a par commitů zpátky je verze běžící na produkci. Nové změny jsou pushnuty do feature větví, po code review jsou mergnuti do master vetvě. Nepoužíváme release větev, protože při tak krátké iteraci, kterou máme, je pro nás jednoduchší udělat hotfix z commitu, který je aktuálně na produkci a pak jej vydat.

CI nástroj

Testy a build nám běží v CircleCI. CircleCI je cloudová služba, kde každý build běží v odděleném Docker kontejneru. Příkazy k buildu jsou nastaveny v YAML souboru v repozitáři. Výhodou verzování je hlavně možnost použití dvou různých konfigurací paralelně na jiných větvích. Můžete tedy psát feature v Javě 8 a ve stejnou chvíli někdo může upgradovat projekt na 11. Při mergi obou větví do masteru se vezme ta nová konfigurace.

Konfigurace se dělí do několika částí. V první je, kde testy mají běžet a jaké mají závislosti (MySQL, PostgreSQL, Redis, …). Další částí je nastavení cashe, spustění testu, build, release… Viditelnost mezi kontejnery má pouze build, který je vytváří. Do cache se mohou uložit závislosti projektu a tím se o dost zrychlí každý build. Pokud jakýkoliv krok selže, tak selže celý build. Následující konfigurace používá v testech MySQL, který se spustí paralelně s buildem a po jeho ukončení se MySQL kontejner zabije. Stav v MySQL a testy běžící v paralelních buildech se vzájemně neovlivňují.

Build & Deployment na QA prostředí

Build a deployment applikace je plně automatizovaný a je součásti CircleCI konfigurace. V předposledních dvou blocích se provádí build a push Docker kontejneru, pouze pro větev master, a nebo pro ty s prefixem hotfix. Poslední krok je přihlášení do Kubernetes clusteru a release kontejneru na testovací prostředí. (Mezikrok s nastavením počtem replik pouze urychluje rolling update na testovacím prostředí.)

Krok store_artefacts slouží pro uložení souborů z buildu, nebo vygenerovaného názvu kontejneru. Každý kontejner je otagován datem a číslem buildu (billing:2018–11–29.5340). Datum se hodí hlavně pro to, abychom viděli, jak stará verze běží na produkci a mohli se podívat detailněji na diff změn. Číslo buildu rozlišuje více buildů ve stejný den a navíc je o dost čitelnější než HASH commitu. Build# odkazuje na samotný commit i PR na GitHubu.

Kubernetes a AWS

Pro test a produkci máme dva oddělené clustery. Oba clustery byly vytvořeny pomocí KOPS, víceméně se stejnou konfiguraci — rozdíly jsou regionální konfigurace a bezpečnostní klíče. Testovací cluster je ještě rozdělen namespaci na test (QA prostředí) a dev (pro různé pokusy backend týmu).

Deployment na produkci

Deployment na produkci provádíme přes námi napsaného Slack Bota. Při poslání zprávy deploy billing:2018–11–29.5340 se spustí deployment na Kubernetes clusteru. Výstup ve Slacku je pak následující:

Závěr

Průměrně build kontejneru s testy a deploymentem trvá okolo 3 minut, ale CI a CD jsou pouze ozubená kolečka v procesu jak vydávat software. Ty se už nastěstí stávají standartem. Nejvíce času nám ale šetří kombinace unit a E2E testů. Díky nim v podstatě dokážeme přeskakovat manuální QA a vydávat „mikro služby“ na produkci denně a bez velkého strachu, nebo release oken.