Vytvárame úlohu na nasadenie v GKE bez pluginov, SMS a registrácie. Jedným okom nahliadneme na Jenkins'a pod sako

Všetko sa začalo, keď vedúci jednej z našich vývojárskych tímov požiadal, aby sme v testovacom režime sprístupnili ich novú aplikáciu, ktorá bola predtým containerizovaná. Sprístupnil som ju. Asi po 20 minútach prišla žiadosť o aktualizáciu aplikácie, lebo tam doplnili veľmi potrebnú funkciu. Aktualizoval som to. Ešte o niekoľko hodín… nuž, určite tušíte, čo sa dialo ďalej…

Priznám sa, som dosť lenivý (už som to predtým priznal? nie?), a berúc do úvahy, že vedúci tímov majú prístup do Jenkinsu, kde máme celý CI/CD, som si pomyslel: nech si to nasadí sám, koľko uzná za vhodné! Spomenul som si na vtip: Daj človeku rybu a bude sýty deň; nazvi človeka Sýt a bude sýty celý život. A šiel som vytvoriť úlohu, ktorá by vedela nasadzovať do kubernetu kontajner s aplikáciou akejkoľvek úspešne zostavenej verzie a prenášať do neho akékoľvek hodnoty ENV (môj dedko, — filológ, bývalý učiteľ angličtiny, — by teraz krútil prstom na spánku a veľmi výstižne by sa na mňa pozrel, keby si prečítal túto vetu).

Takže v poznámke sa podelím o to, ako som sa naučil:

  1. Dynamicky aktualizovať úlohy v Jenkins z jednej úlohy alebo z iných úloh;
  2. Pripojiť sa k cloudovej konzole (Cloud shell) z nody s nainštalovaným agentom Jenkins;
  3. Nasadzovať pracovnú záťaž (workload) do Google Kubernetes Engine.


V skutočnosti, samozrejme, trochu zavádzam. Predpokladá sa, že aspoň časť infraštruktúry máte v google cloudy, a teda ste jeho používateľom a máte samozrejme účet GCP. Ale poznámka nie je o tom.

Toto je ďalšia moja poznámka pre seba. Takéto poznámky píšem len v jednom prípade: stal sa mi problém, spočiatku som nevedel, ako ho vyriešiť, riešenie sa neobjavilo v hotovej podobe, preto som ho hľadal po častiach a nakoniec som problém vyriešil. A aby som do budúcna, keď zabudnem, ako som to spravil, nemusel opäť všetko hľadať po častiach a skladať to dokopy, píšem si takéto poznámky.

Upozornenie: 1. Poznámka bola písaná "pre seba", nepretenderuje na rolu best practice uvítam návrhy "a bolo by lepšie to urobiť takto" v komentároch.
2. Ak považujeme aplikovanú časť poznámky za soľ, tak, ako všetky moje predchádzajúce poznámky, aj táto — je to slabý soľný roztok.

Dynamické aktualizovanie nastavení úloh v Jenkins

Očakávam vašu otázku: aký má význam dynamické aktualizovanie úlohy? Napísal som ručne hodnotu reťazcového parametra a dopredu!

Odpovedám: naozaj som lenivý, nemám rád, keď sa sťažujú: Misha, nasadenie zlyháva, všetko je preč! Začínam sa pozerať, a tam je preklep v hodnote nejakého parametra spúšťania úlohy. Preto preferujem robiť všetko maximálne bezchybne. Ak existuje možnosť zbaviť používateľa možnosti zadávať údaje priamo, a namiesto toho poskytnúť zoznam hodnôt na výber, tak organizujem výber.

Plán je taký: vytvoríme úlohu v Jenkins, v ktorej pred spustením by sa mohla z zoznamu vybrať verzia a zadať hodnoty pre parametre, ktoré sa odovzdávajú do kontajnera cez ENV, potom sa zostaví kontajner a pošle sa do Container Registry. Odtiaľ sa kontajner spustí v kubere ako workload s parametrami určenými v úlohe.

Proces vytvárania a nastavovania úlohy v Jenkins nebudeme zvažovať, to je offtopic. Budeme vychádzať z toho, že úloha je pripravená. Na realizáciu aktualizovaného zoznamu s verziami potrebujeme dve veci: už existujúci zoznam zdrojov s apriórne platnými číslami verzií a premennú typu Choice parameter v úlohe. V našom príklade nech je premenná pomenovaná BUILD_VERSION, na tej sa podrobne zastavovať nebudeme. Ale na zozname zdrojov sa zastavíme podrobnejšie.

Možností nie je príliš veľa. Hneď mi napadli dve:

  • Použiť Remote access API, ktoré ponúka Jenkins svojim používateľom;
  • Získať obsah vzdialenej zložky repozitára (v našom prípade to je JFrog Artifactory, čo nie je rozhodujúce).

Jenkins Remote access API

Podľa dlhoročnej tradície sa radšej vyhnem dlhým vysvetleniam.
Dovolím si len voľný preklad kusu prvého odseku prvej stránky dokumentácie API:

Jenkins poskytuje API na vzdialený strojovo čitateľný prístup k svojej funkcionalite. Vzdialený prístup je poskytovaný v štýle podobnom REST. To znamená, že neexistuje jediný vstupný bod ku všetkým možnostiam, ale namiesto toho sa používa URL typu "…/api/", kde "…" predstavuje objekt, na ktorý sa aplikujú možnosti API.

Inými slovami, ak úloha na nasadenie, o ktorej momentálne hovoríme, je prístupná na adrese http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build, API-túry pre toto zadanie sú k dispozícii na adrese http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/

Ďalej máme na výber, akým spôsobom chceme získať výstup. Zastavíme sa pri XML, pretože API v tomto prípade umožňuje použiť filtrovanie.

Poďme si to len tak vyskúšať a získať zoznam všetkých spustení úlohy. Zaujíma nás len názov zostavy (displayName) a jej výsledok (result):

http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]

Podarilo sa?

Teraz filtrovať len tie spustenia, ktoré majú výsledok SUCCESS. Použijeme argument &exclude a ako parameter mu odovzdáme cestu k hodnote, ktorá nie je rovná SUCCESS. Áno, áno. Dvojité zamietnutie — to je potvrdenie. Vylučujeme všetko, čo nás nezaujíma:

http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result!='SUCCESS']

Snímka obrazovky úspešného zoznamu
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

A len tak pre zábavu sa uistíme, že nás filter neoklamal (filter predsa nikdy neklame!) a vypíšeme zoznam 'nie-úspešných':

http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result='SUCCESS']

Snímka obrazovky nie-úspešných
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

Zoznam verzií z priečinka na vzdialenom serveri

Existuje aj druhý spôsob, ako získať zoznam verzií. Tento sa mi páči ešte viac ako volanie API Jenkins. No, pretože ak sa aplikácia úspešne zostavila, znamená to, že ju zabalili a uložili do repozitára do príslušného priečinka. Akoby, repozitár je predvolene úložisko pracovných verzií aplikácií. Tak sa opýtajme, aké verzie sú uložené. Vzdialený priečinok budeme curl'ovať, grep'ovať a awk'ovať. Ak niekoho zaujíma oneliner, je pod spoilerom.

Príkaz jedným riadkom
Všimnite si dve veci: odovzdávam v hlavičke poverenia na pripojenie a nepotrebujem naozaj všetky verzie z priečinka; vyberám len tie, ktoré boli vytvorené za posledný mesiac. Upravte príkaz podľa vašich realít a potrieb:

curl -H "X-JFrog-Art-Api:VeryLongAPIKey" -s http://arts.myre.po/artifactory/awesomeapp/ | sed 's/a href=//g' | grep "$(date +%b)-$(date +%Y)|$(date +%b --date='-1 month')-$(date +%Y)" | awk '{print $1}' | grep -oP '>K[^/]+ )

Nastavenie úloh a konfiguračný súbor úlohy v Jenkins

S tým, ako získať zoznam verzií, sme si už popasovali. Poďme teraz získať získaný zoznam a zapracovať ho do úlohy. Pre mňa bolo zrejmým riešením pridať krok do úlohy na zostavenie aplikácie. Krok, ktorý by sa vykonal v prípade výsledku 'úspech'.

Otvárame nastavenia úlohy na zostavenie a skrolujeme úplne dolu. Klikneme na tlačidlá: Add build step -> Conditional step (single). V nastaveniach kroku vyberáme podmienku Current build status, nastavíme hodnotu SUCCESS, vykonávaná akcia v prípade úspechu Run shell command.

A teraz to najcieklejšie. Konfigurácie úloh Jenkins sa uchovávajú v súboroch. V XML formáte. Na ceste http://cesta-k-úlohe/config.xml Podľa toho je možné stiahnuť súbor s konfiguráciou, upraviť ho požadovaným spôsobom a vrátiť ho na miesto, odkiaľ bol stiahnutý.

Pamätajte, vyššie sme sa dohodli, že pre zoznam verzií vytvoríme parameter BUILD_VERSION?

Stiahnime si súbor s konfiguráciou a pozrime sa dovnútra. Len aby sme sa uistili, že parameter je na svojom mieste a je skutočne v správnom formáte.

Screenshot pod spoilerom.

Váš uvedený fragment config.xml by mal vyzerať rovnako. S tým rozdielom, že obsah elementu choices zatiaľ chýba.
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

Uistili ste sa? Tak píšeme skript, ktorý sa vykoná v prípade úspešného zostavenia.
Skript získa zoznam verzií, stiahne súbor s konfiguráciou, zapíše do neho na požadované miesto zoznam verzií a potom ho vráti späť. Áno. Všetko je správne. Zapísať zoznam verzií do XML na miesto, kde už je zoznam verzií (to bude v budúcnosti, po prvom spustení skriptu). Viem, že na svete stále žijú vášniví milovníci regulárnych výrazov. Ja k nim nepatrím. Nainštalujte, prosím, xmlstarlet na ten stroj, kde sa bude konfig upravovať. Myslím, že to nie je taká veľká daň za to, aby sme sa vyhli úprave XML pomocou sed.

Pod spoilerom uvádzam kód, ktorý vykonáva vyššie popísanú sekvenciu v celku.

Píšeme do konfigurácie zoznam verzií z priečinka na vzdialenom serveri

#!/bin/bash
############## Скачиваем конфиг
curl -X GET -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml -o appConfig.xml

############## Удаляем и заново создаем xml-элемент для списка версий
xmlstarlet ed --inplace -d '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' appConfig.xml

xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]' --type elem -n a appConfig.xml

xmlstarlet ed --inplace --insert '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a' --type attr -n class -v string-array appConfig.xml

############## Читаем в массив список версий из репозитория
readarray -t vers < <( curl -H "X-JFrog-Art-Api:Api:VeryLongAPIKey" -s http://arts.myre.po/artifactory/awesomeapp/ | sed 's/a href=//' | grep "$(date +%b)-$(date +%Y)|$(date +%b --date='-1 month')-$(date +%Y)" | awk '{print $1}' | grep -oP '>K[^/]+' )

############## Пишем массив элемент за элементом в конфиг
printf '%sn' "${vers[@]}" | sort -r | 
                while IFS= read -r line
                do
                    xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' --type elem -n string -v "$line" appConfig.xml
                done

############## Кладем конфиг взад
curl -X POST -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml --data-binary @appConfig.xml

############## Приводим рабочее место в порядок
rm -f appConfig.xml

Ak sa vám viac páčila verzia so získavaním verzií z Jenkinsu a ste rovnako leniví ako ja, pod spoilerom je ten istý kód, ale zoznam z Jenkinsu:

Píšeme do konfigurácie zoznam verzií z Jenkinsu
Len berte do úvahy moment: moje meno zostavenia pozostáva z poradového čísla a čísla verzie, oddelených dvojbodkou. Podľa toho, awk odstraňuje nepotrebnú časť. Túto čiaru si upravte podľa svojich potrieb.

#!/bin/bash
############## Скачиваем конфиг
curl -X GET -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml -o appConfig.xml

############## Удаляем и заново создаем xml-элемент для списка версий
xmlstarlet ed --inplace -d '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' appConfig.xml

xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]' --type elem -n a appConfig.xml

xmlstarlet ed --inplace --insert '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a' --type attr -n class -v string-array appConfig.xml

############## Пишем в файл список версий из Jenkins
curl -g -X GET -u username:apiKey 'http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/xml?tree=allBuilds[displayName,result]&exclude=freeStyleProject/allBuild[result!=%22SUCCESS%22]&pretty=true' -o builds.xml

############## Читаем в массив список версий из XML
readarray vers < <(xmlstarlet sel -t -v "freeStyleProject/allBuild/displayName" builds.xml | awk -F":" '{print $2}')

############## Пишем массив элемент за элементом в конфиг
printf '%sn' "${vers[@]}" | sort -r | 
                while IFS= read -r line
                do
                    xmlstarlet ed --inplace --subnode '/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition[name="BUILD_VERSION"]/choices[@class="java.util.Arrays$ArrayList"]/a[@class="string-array"]' --type elem -n string -v "$line" appConfig.xml
                done

############## Кладем конфиг взад
curl -X POST -u username:apiKey http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_k8s/config.xml --data-binary @appConfig.xml

############## Приводим рабочее место в порядок
rm -f appConfig.xml

V podstate, ak ste otestovali kód napísaný na základe vyššie uvedených príkladov, mali by ste mať v úlohe na nasadenie už rozbaľovací zoznam s verziami. Takto to vyzerá na screene pod spoilerom.

Správne vyplnený zoznam verzií
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

Ak všetko fungovalo, tak skopírujte skript do Run shell command a uložte zmeny.

Pripojenie k Cloud shell

Naši skladatelji sú v kontajneroch. Ako prostriedok na dodávanie aplikácií a manažéra konfigurácií používame Ansible. Keď sa teda hovorí o zostavovaní kontajnerov, napadajú ma tri možnosti: nainštalovať Docker vo vnútri Dockeru, nainštalovať Docker na stroj s Ansible alebo skladať kontajnery v cloudovej konzole. O pluginov pre Jenkins sme sa v tejto poznámke dohodli mlčať. Pamätáte si?

Rozhodol som sa: ak sa kontajnery "z krabice" dajú zostaviť v cloudovej konzole, tak načo si komplikovať život? Keep it clean, že? Chcem zostavovať kontajnery pomocou Jenkins v cloudovej konzole a potom ich odtiaľ posielať do Kubernetu. O to viac, že v rámci infraštruktúry má Google veľmi silné kanály, čo blahodarne vplýva na rýchlosť nasadzovania.

Na pripojenie k cloudovej konzole sú potrebné dve veci: gcloud a práva prístupu k Google Cloud API pre konkrétny VM instance, z ktorej bude toto pripojenie vykonané.

Pre tých, ktorí sa plánujú pripojiť úplne nie z Google Cloud
Google umožňuje možnosť vypnúť interaktívnu autorizáciu vo svojich službách. To umožní pripojiť sa k konzole aj z kávovaru, pokiaľ beží na *nixoch a má aj svoju konzolu.

Ak je potrebné, aby som tento problém bližšie osvetlil v rámci tejto poznámky — píšte do komentárov. Ak sa nazbiera dostatočný počet hlasov — napíšem aktualizáciu na toto téma.

Najjednoduchší spôsob, ako udeliť práva — cez webové rozhranie.

  1. Zastavte VM instance, z ktorej sa bude ďalej pripájať k cloudovej konzole.
  2. Otvorí sa informácia o instance a kliknite na Upraviť.
  3. Na úplnom spodku stránky vyberte rozsah prístupu instance Úplný prístup ku všetkým Cloud API.

    Screenshot
    Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

  4. Uložte zmeny a spustite instance.

Po skončení načítania VM sa k nej pripojte cez SSH a uistite sa, že pripojenie prebieha bez chýb. Využite príkaz:

gcloud alpha cloud-shell ssh

Úspešné pripojenie vyzerá približne takto
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

Nasadenie do GKE

Keďže sa usilovne snažíme úplne prejsť na IaC (Infrastuktúra ako kód), naše Dockerfile sú uložené v Gite. To je z jednej strany. A nasadenie do Kubernetu je popísané yaml súborom, ktorý sa používa len pre túto úlohu, ktorý sám o sebe je tiež akosi kód. To je z druhej strany. V podstate tým chcem povedať, že plán je taký:

  1. Bereme hodnoty premenných BUILD_VERSION a voliteľne hodnoty premenných, ktoré budú odovzdané cez ENV.
  2. Sťahujeme Dockerfile z Gitu.
  3. Generujeme yaml pre nasadenie.
  4. Oba tieto súbory nahráme pomocou SCP do cloudovej konzoly.
  5. Tam postavíme kontajner a posunieme ho do Container registry
  6. Použijeme súbor na nasadenie záťaže v Kubernetes.

Buďme konkrétnejší. Keď už sme o tom hovorili, ENVpredpokladajme, že budeme musieť odovzdať hodnoty dvoch parametrov: PARAM1 a PARAM2. Pridáme ich ako úlohu na nasadenie, typ — String Parameter.

Screenshot
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

Yaml vygenerujeme jednoduchým priamym presmerovaním echo do súboru. Predpokladáme, samozrejme, že v Dockerfile máte prítomné PARAM1 a PARAM2že názov záťaže bude awesomeappa zostavený kontajner s aplikáciou uvedenej verzie je uložený v Container registry na ceste gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION, kde $BUILD_VERSION bol práve vybraný z rozbaľovacieho zoznamu.

Zoznam príkazov

touch deploy.yaml
echo "apiVersion: apps/v1" >> deploy.yaml
echo "kind: Deployment" >> deploy.yaml
echo "metadata:" >> deploy.yaml
echo "  name: awesomeapp" >> deploy.yaml
echo "spec:" >> deploy.yaml
echo "  replicas: 1" >> deploy.yaml
echo "  selector:" >> deploy.yaml
echo "    matchLabels:" >> deploy.yaml
echo "      run: awesomeapp" >> deploy.yaml
echo "  template:" >> deploy.yaml
echo "    metadata:" >> deploy.yaml
echo "      labels:" >> deploy.yaml
echo "        run: awesomeapp" >> deploy.yaml
echo "    spec:" >> deploy.yaml
echo "      containers:" >> deploy.yaml
echo "      - name: awesomeapp" >> deploy.yaml
echo "        image: gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION:latest" >> deploy.yaml
echo "        env:" >> deploy.yaml
echo "        - name: PARAM1" >> deploy.yaml
echo "          value: $PARAM1" >> deploy.yaml
echo "        - name: PARAM2" >> deploy.yaml
echo "          value: $PARAM2" >> deploy.yaml

Agentovi Jenkins po pripojení pomocou gcloud alpha cloud-shell ssh interaktívny režim nie je k dispozícii, preto prenášame príkazy do cloudovej konzoly pomocou parametra --command.

Vyčistíme domovský adresár v cloudovej konzole od starého Dockerfile:

gcloud alpha cloud-shell ssh --command="rm -f Dockerfile"

Uložíme čerstvo stiahnutý Dockerfile do domovského adresára cloudovej konzoly pomocou SCP:

gcloud alpha cloud-shell scp localhost:./Dockerfile cloudshell:~

Skladujeme, značkujeme a posielame kontajner do Container registry:

gcloud alpha cloud-shell ssh --command="docker build -t awesomeapp-$BUILD_VERSION ./ --build-arg BUILD_VERSION=$BUILD_VERSION --no-cache"
gcloud alpha cloud-shell ssh --command="docker tag awesomeapp-$BUILD_VERSION gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION"
gcloud alpha cloud-shell ssh --command="docker push gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION"

Rovnako postupujeme so súborom nasadenia. Všimnite si, že v príkazoch nižšie sú použité fiktívne názvy klastra, do ktorého sa nasadzuje (awsm-cluster) a názov projektu (awesome-project), kde sa nachádza klaster.

gcloud alpha cloud-shell ssh --command="rm -f deploy.yaml"
gcloud alpha cloud-shell scp localhost:.\/deploy.yaml cloudshell:~
gcloud alpha cloud-shell ssh --command="gcloud container clusters get-credentials awsm-cluster --zone us-central1-c --project awesome-project && 
kubectl apply -f deploy.yaml"

Spúšťame úlohu, otvárame výstup z konzoly a dúfame, že uvidíme úspešnú zostavu kontajnera.

Screenshot
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

A ďalej úspešný deployment zostaveného kontajnera

Screenshot
Pripravujeme úlohu na deployment do GKE bez pluginov, SMS a registrácie. Jednou očkom nahliadneme Jenkinsovi pod kabát.

Úmyselne som sa nezameral na konfiguráciu Ingress. Z jedného jednoduchého dôvodu: raz nastavený s workload určitým menom, zostane funkčný bez ohľadu na to, koľko deploymentov s týmto menom uskutočníte. A vlastne, to je trochu mimo rámca príbehu.

Namiesto záverov

Všetky vyššie uvedené kroky, asi nemuseli byť uskutočnené, mohli ste jednoducho nainštalovať nejaký plugin pre Jenkins, je ich milión. Ale ja nejako nemám rád pluginy. No, presnejšie, uchyľujem sa k nim len z bezradnosti.

A navyše ma jednoducho baví skúmať nejakú novú pre mňa tému. Text vyššie je aj spôsob, ako sa podeliť o poznatky, ktoré som získal pri riešení opísanej na začiatku úlohy. Podeliť sa s tými, ktorí, ako ja, nie sú úplne začiatočníci vo devopse. Ak aspoň niekomu moje poznatky pomôžu – budem spokojný.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster