Kodėl apskritai kalbame apie CI/CD įrankius
Prieš kelerius metus dirbau projekte, kur kodas buvo diegiamas rankiniu būdu. Penktadienio vakarais. Taip, būtent taip – penktadieniais po 18 val. Galite įsivaizduoti tą chaosą, kai kažkas sulaužydavo production aplinką ir visi turėdavo likti biure iki vidurnakčio. Tada atsirado CI/CD, ir gyvenimas pasikeitė.
Šiandien continuous integration ir continuous deployment jau nėra prabanga – tai būtinybė. Bet čia ir prasideda dilema: Jenkins ar GitLab CI? Abu įrankiai gali padaryti tą patį darbą, tačiau jų filosofija, prieiga ir kasdienė patirtis labai skiriasi. Esu turėjęs galimybę dirbti su abiem sprendimais įvairiuose projektuose, todėl pasidalinsiu ne tik technine informacija, bet ir realiais įspūdžiais.
Jenkins: senas geras darbo arklys
Jenkins atsirado dar 2011 metais kaip Hudson projekto šaka. Per tą laiką jis tapo de facto standartu daugelyje įmonių. Ir tam yra priežasčių.
Pirmiausia – lankstumas. Jenkins yra kaip tuščias drobė, kurią galite nutapyti bet kokia spalva. Norite integruoti su egzotišku įrankiu, kurį naudoja tik jūsų komanda? Greičiausiai jau yra pluginas tam. O jei nėra – galite parašyti patys. Pluginų ekosistema yra tikrai įspūdinga: daugiau nei 1800 pluginų įvairioms reikmėms.
Bet štai čia ir slypi problema. Kai pradedi naują Jenkins projektą, pirmas dalykas, kurį darai – instaliuoji dešimtis pluginų. Tada dar dešimt. Paskui pradedi spręsti konfliktus tarp pluginų versijų. Vieną kartą praleidau pusę dienos bandydamas suprasti, kodėl pipeline’as nebepasileido po Jenkins atnaujinimo. Paaiškėjo, kad vienas pluginas nebuvo suderinamas su nauja versija.
Jenkins konfigūracija istoriškai buvo daroma per web UI. Spaudinėji mygtukus, užpildai laukelius, ir voilà – turite job’ą. Bet tai reiškia, kad jūsų konfigūracija gyvena Jenkins serveryje, ne versijų kontrolėje. Taip, dabar yra Jenkinsfile ir „Pipeline as Code” koncepcija, bet vis tiek jaučiasi, kad tai buvo pridėta vėliau, ne kaip pagrindinė filosofija.
Štai kaip atrodo paprastas Jenkinsfile:
„`groovy
pipeline {
agent any
stages {
stage(‘Build’) {
steps {
sh ‘npm install’
sh ‘npm run build’
}
}
stage(‘Test’) {
steps {
sh ‘npm test’
}
}
}
}
„`
Groovy sintaksė nėra sudėtinga, bet ji yra… specifinė. Jei nedirbate su Groovy kasdien, kai kurie dalykai gali atrodyti keisti.
GitLab CI: naujosios kartos požiūris
GitLab CI atsirado vėliau ir iš karto buvo suprojektuotas su „everything as code” filosofija. Čia nėra jokių konfigūracijų web sąsajoje – viskas aprašyta `.gitlab-ci.yml` faile, kuris gyvena jūsų repository šaknyje kartu su kodu.
Kai pirmą kartą pradėjau naudoti GitLab CI, mane nustebino, kaip greitai galima pradėti. Sukuri `.gitlab-ci.yml` failą, commit’ini, push’ini – ir jau veikia. Nereikia instaliuoti pluginų, konfigūruoti agentų ar galvoti apie infrastruktūrą. GitLab Runner’iai gali būti paleisti Docker konteineriuose, ir kiekvienas build’as vyksta švariai atskiroje aplinkoje.
Štai analogiškas pipeline GitLab CI:
„`yaml
stages:
– build
– test
build:
stage: build
script:
– npm install
– npm run build
test:
stage: test
script:
– npm test
„`
YAML sintaksė yra paprastesnė ir intuityvesnė. Bet YAML turi savo keblumų – tarpai ir įtraukos gali sukelti galvos skausmą, ypač sudėtingesnėse konfigūracijose.
Infrastruktūros ir paleidimo skirtumai
Čia prasideda tikrasis skirtumas tarp šių įrankių.
Jenkins infrastruktūra reikalauja daugiau dėmesio. Jums reikia serverio, kuriame veiks Jenkins master. Paskui reikia sukonfigūruoti agent’us (anksčiau vadinamus slave’ais), kurie vykdys darbus. Tai reiškia serverių priežiūrą, atnaujinimus, backup’us. Viename projekte turėjome dedikuotą DevOps inžinierių, kurio viena iš pagrindinių užduočių buvo Jenkins priežiūra.
GitLab CI, kita vertus, yra integruotas į GitLab platformą. Jei naudojate GitLab.com, CI/CD funkcionalumas jau yra ten, nereikia nieko diegti. Jei naudojate self-hosted GitLab, CI/CD ateina kartu su pagrindiniu paketu. GitLab Runner’ius galite paleisti bet kur – jūsų serveriuose, cloud’e, net savo nešiojamame kompiuteryje testavimo tikslais.
Praktiškai tai reiškia, kad su GitLab CI galite pradėti dirbti per kelias minutes, o su Jenkins – per kelias valandas ar net dienas, priklausomai nuo jūsų reikalavimų.
Pluginai prieš integruotą funkcionalumą
Jenkins filosofija: pagrindinis funkcionalumas yra minimalus, visa kita – per pluginus. Norite Docker palaikymą? Pluginas. Kubernetes integraciją? Pluginas. Slack pranešimus? Pluginas. Tai suteikia neįtikėtiną lankstumą, bet kartu sukuria priklausomybių pragarą.
Esu matęs Jenkins instaliaciją su 150+ pluginų. Kiekvienas atnaujinimas buvo kaip rusiškas ruletė – niekada nežinai, kas suges. Pluginų tarpusavio suderinamumas yra nuolatinė problema. Kai kurie pluginai nebėra prižiūrimi, bet jūs vis tiek juos naudojate, nes alternatyvos nėra.
GitLab CI turi integruotą funkcionalumą daugumai įprastų use case’ų. Docker palaikymas? Įmontuotas. Kubernetes deployment? Yra. Container registry? Taip pat. Security scanning? Auto DevOps? Viskas jau yra.
Tai nereiškia, kad GitLab CI yra mažiau lankstus. Tiesiog dažniausiai naudojamos funkcijos jau yra ten, ir jos veikia kartu be papildomų konfigūracijų. Jei reikia kažko specifinio, galite naudoti custom Docker images arba rašyti custom scripts.
Kaina ir licencijavimas
Jenkins yra visiškai nemokamas ir open source. Galite jį naudoti kaip tik norite, nereikia mokėti nė cento už licenciją. Bet čia svarbu suprasti pilną kainą. Jums reikės:
– Serverių infrastruktūros (master ir agent’ai)
– Žmonių, kurie prižiūrės tą infrastruktūrą
– Laiko pluginų valdymui ir atnaujinimams
– Galvos skausmo, kai kas nors neveikia
Viename projekte apskaičiavome, kad nors Jenkins pats yra „nemokamas”, infrastruktūros ir priežiūros kaštai siekė apie 3000 eurų per mėnesį.
GitLab CI yra nemokamas GitLab Free tier’e su tam tikrais apribojimais (2000 CI/CD minučių per mėnesį shared runner’iuose). Premium ir Ultimate tier’ai kainuoja, bet kartu gaunate ne tik CI/CD, bet ir visą GitLab platformą su code review, issue tracking, security features ir t.t.
Jei naudojate self-hosted GitLab, galite turėti neribotą CI/CD naudojimą su savo runner’iais. Tai gali būti labai ekonomiška vidutinėms ir didelėms komandoms.
Realios patirties įžvalgos
Dirbau projekte, kur migruojome nuo Jenkins prie GitLab CI. Tai buvo įdomi kelionė. Pirmiausia, komanda buvo skeptiška – Jenkins veikė (daugmaž), kodėl keisti? Bet po kelių savaičių su GitLab CI niekas nenorėjo grįžti atgal.
Kas pasikeitė? Pirmiausia – greitis. GitLab CI pipeline’ai buvo greitesni, nes kiekvienas job’as veikdavo švariai Docker konteineryje su tiksliai tais dependencies, kurių reikia. Jenkins’e turėjome bendrą agent’ą su visomis įmanomomis bibliotekomis, ir kartais atsilikdavo konfliktai.
Antra – paprastumas. Naujas komandos narys galėjo suprasti `.gitlab-ci.yml` failą per kelias minutes. Su Jenkinsfile ir visais tais pluginais tai užtrukdavo daug ilgiau.
Trečia – versijų kontrolė. Kai viskas yra kode, galite matyti, kas pakeitė CI/CD konfigūraciją, kada ir kodėl. Su Jenkins tai buvo sudėtingiau, nors ir įmanoma.
Bet Jenkins turi savo privalumų. Jei jums reikia labai specifinės integracijos su legacy sistemomis, Jenkins greičiausiai turi pluginą tam. Jei jūsų organizacija jau turi didelę Jenkins infrastruktūrą su šimtais job’ų, migracija gali būti per brangi.
Kada rinktis Jenkins, kada GitLab CI
Rinkitės Jenkins, jei:
– Jau turite veikiančią Jenkins infrastruktūrą ir komandą, kuri moka su juo dirbti
– Jums reikia integracijos su labai specifinėmis ar legacy sistemomis
– Turite kompleksinius, ilgalaikius build’us, kuriems reikia specialios infrastruktūros
– Jūsų organizacija naudoja ne GitLab version control (pvz., Bitbucket, GitHub)
– Turite dedikuotą DevOps komandą, kuri gali prižiūrėti infrastruktūrą
Rinkitės GitLab CI, jei:
– Pradedame naują projektą nuo nulio
– Naudojate arba planuojate naudoti GitLab kaip version control
– Norite „all-in-one” sprendimo (code, CI/CD, issue tracking viename)
– Jūsų komanda yra maža ar vidutinė ir neturite dedikuotų DevOps inžinierių
– Vertinate paprastumą ir greitą setup’ą
– Naudojate Docker ir Kubernetes
Praktiškai, daugelis naujų projektų šiandien renkasi GitLab CI arba panašius modernius sprendimus (GitHub Actions, CircleCI). Jenkins lieka populiarus didelėse, nusistovėjusiose organizacijose, kur jau yra investuota į infrastruktūrą ir žinias.
Ką daryti su visa šia informacija
Tiesą sakant, nėra vieno teisingo atsakymo. Aš pats vis dar naudoju Jenkins kai kuriuose projektuose ir GitLab CI kituose. Svarbu suprasti, kad CI/CD įrankis yra tik įrankis – jis neišspręs jūsų problemų, jei neturite gerų praktikų.
Jei dabar renkates tarp šių dviejų, patarčiau pradėti nuo GitLab CI, jei tik galite. Jis paprastesnis, greitesnis pradėti, ir greičiausiai padarys viską, ko jums reikia. Jei vėliau paaiškės, kad jums reikia kažko specifinio, ką tik Jenkins gali pasiūlyti, visada galite migruoti.
O jei jau turite Jenkins ir jis veikia – nebūtinai reikia keisti. „If it ain’t broke, don’t fix it” vis dar yra geras patarimas. Bet jei planuojate modernizaciją ar pradedame naują projektą, tikrai apsvarstykite GitLab CI kaip alternatyvą.
Galiausiai, svarbiausias dalykas yra ne tai, kurį įrankį pasirenkate, bet kaip jį naudojate. Geras CI/CD pipeline’as su Jenkins yra geriau nei prastas su GitLab CI. Investuokite laiką į mokymąsi, eksperimentavimą ir nuolatinį tobulinimą – tai atsipirks šimteriopai.
