Kohandame ülesande GKE-deployimiseks ilma pistikprogrammide, SMSide ja registreerimiseta. Üks silm heidame Jenkins'ile pilgu alla.

Kõik algas sellest, et meie arendustiimi tiimijuht palus testrežiimis nende uut rakendust välja panna, mis eelmisel päeval oli konteineriseeritud. Ma panin selle välja. Umbes 20 minuti möödudes tuli palve rakendust uuendada, kuna sinna lisati väga vajalik funktsioon. Ma uuendasin. Veel paar tundi hiljem... noh, te kujutate juba ette, mis edasi juhtuma hakkas...

Pean tunnistama, et olen üsna laisk (kas ma ei ole seda juba varem tunnistanud? Ei?), ja kui arvestada, et tiimijuhid pääsevad Jenkinsisse, kus meil on kogu CI/CD, siis mõtlesin: las nad ise deploogeerivad, kui palju tahavad! Meenus anekdoot: anna inimesele kala ja ta on söönud päeva; nimeta inimene Söögiks ja ta on Söögine kogu elu. Ja läksin töötama ülesannet, mis oskab deploida kuberisse konteineri rakendusega mistahes edukalt kokku pandud versioonist ja edastada sellele kõik väärtused. ENV (mu vanaisa, - filoloog, endine inglise keele õpetaja, - keeraks nüüd sõrme kõrval pead ja vaataks mulle väga väljendusrikkalt otsa, kui ta selle lause loeks).

Nii et, märkmes jutustan, kuidas ma õppisin:

  1. Dünaamiliselt uuendama ülesandeid Jenkins'is kas otseselt ülesandest või teistest ülesannetest;
  2. Ühenduma pilvekonsooliga (Cloud shell) node'ist, kus on Jenkins'i agent paigaldatud;
  3. Deploima töökoormust Google Kubernetes Engine'is.


Tegelikult ma, muidugi, natuke üle dramatiseerin. Eeldatakse, et vähemalt osa infrastruktuurist on teil Google'i pilves, ja seega olete te pilve kasutaja ja teil on kindlasti GCP konto. Kuid märkme teema ei ole selles.

See on jällegi minu nö. spikker. Taolisi märkmeid tahan ma kirjutada vaid ühes olukorras: mul oli probleem, ma ei teadnud algselt, kuidas seda lahendada, lahendus ei olnud kohe googeldades saadaval, seega otsisin ma selle välja tükkhaaval ja lõpuks lahendasin probleemi. Ja et tulevikus, kui ma unustan, kuidas ma seda tegin, ei peaks ma uuesti kõike tükkideks googeldama ja kokku panema, kirjutan endale selliseid spikreid.

Käesoleva artikli sisu: 1. Märkus kirjutati "enda jaoks", rolli parim praktika ei pretendeeri. Hea meelega loen kommentaarides üleskutseid "aga oleks olnud parem teha nii".
2. Kui arvestada märkuse rakenduslikku osa soolana, siis nagu kõik minu varasemad märkused, on see — nõrk soolalahus.

Jenkinsis tööülesannete seadete dünaamiline värskendamine

Eeldan teie küsimust: mis seost on dünaamilisel värskendamisel tööga? Kirjutasin stringi parameetri väärtuse käsitsi ja edasi!

Vastan: ma olen tõesti laisk, ei armasta, kui keegi kurtma tuleb: Miša, deploy kukub kokku, kõik on kadunud! Alustad vaatamist ja seal on mingi parameetri käivitamisel vale väärtus. Seetõttu eelistan teha kõik võimalikult veatuks. Kui on võimalik, et kasutaja ei saaks andmeid otse sisestada, andes selle asemel valikute nimekirja, siis korraldan valiku.

Plaani on selline: loome Jenkinsis tööülesande, kus enne käivitamist saab nimekirjast valida versiooni, määrata väärtused parameetritele, mis edastatakse konteinerisse läbi ENV, seejärel kogub see konteineri ja pushib selle Container Registry'sse. Sealt käivitub konteiner Kuberneteses kui workload , parameetritega, mis on määratud tööülesandes.

Jenkinsis tööülesande loomise ja seadistamise protsessi me ei käsitle, see on teema kõrvale kaldumine. Eeldame, et tööülesanne on valmis. Uuendatava versioonide loendi rakendamiseks on meil vaja kahte asja: juba olemasolevat allikaloendit, kus on eelnevalt kehtivad versiooninumbrid, ja muutuja tüüpi Valiku parameeter tööülesandes. Meie näites olgu muutuja nimeks BUILD_VERSION, millele me ei jää peatumiseks pikalt rääkima. Kuid allikaloendi kohta peatume pikemalt.

Valikuid ei ole nii palju. Mulle meenub kohe kaks:

  • Kasutada Jenkins'i Remote access API-d, mida Jenkins oma kasutajatele pakub;
  • Küsimine kauge hoidla kausta sisu (meie puhul on see JFrog Artifactory, mis ei ole põhimõtteliselt oluline).

Jenkins Remote access API

Hea traditsiooni kohaselt eelistan ma vältida mahukaid selgitusi.
Lubage mul vaid vabalt tõlkida osa esimesest lõigust esimese lehe dokumentatsioonist API kohta:

Jenkins pakub API kaugmasinaga arusaadavat juurde pääsu oma funktsioonidele. Kaugjuurdepääs on REST’i sarnases stiilis. See tähendab, et kõikidele võimalustele ei ole ühtset sissepääsupunkti, vaid kasutatakse URL-i vormingus ".../api/", kus "" tähistab objekti, millele API funktsioone rakendatakse.

Teisisõnu, kui meie käimasolev deploy ülesanne on saadaval aadressil http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build, siis selle ülesande API-punktid on kättesaadavad aadressil http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/

Edasi on meil valik, millises vormingus me väljundit saame. Peatume XML-il, kuna API lubab filterdamist ainult sellel juhul.

Proovime lihtsalt saada nimekirja kõigist ülesande käivitustest. Meid huvitab ainult ehituse nimi (displayName) ja selle tulemus (tulemus):

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

Kas see õnnestus?

Nüüd filtreerime välja ainult need käivitused, millel on tulemus SUCCESS. Kasutame argumenti &exclude ja parametritena anname talle tee väärtuse, mis ei ole võrdsed SUCCESS. Jah, jah. Topelt eitamine on kinnitamine. Ei huvitavat, välistame kõik, mis meid ei kõneta:

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

Ekraanipilt edukate tulemuste loendist
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

Ja lihtsalt huvi pärast veendume, et filter meid ei petnud (filtrid ei valeta kunagi!) ja kuvame nimekirja "ebaõnnestunutest":

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

Ekraanipilt ebaõnnestunutest
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

Versioonide nimekiri kaustast kaugserveris

On ka teine viis versioonide nimekirja saamiseks. See meeldib mulle isegi rohkem kui Jenkins API poole pöördumine. Sest kui rakendus on edukalt koostatud, tähendab, et see on pakendatud ja paigutatud vastavasse kausta repos. Tüüpiliselt on repository vaikimisi rakenduste tööversioonide hoidla. Nii et küsime, millised versioonid on säilitamisel. Kaugkausta kütame curl’iga, grep’ime ja awk’ime. Kui keegi on huvitatud ühe rea lahendusest, siis see on spoileris.

Ühe read käsu
Pange tähele kahte asja: edastan päises ühenduse üksikasjad ja mulle ei ole üldse vaja kõikide versioonide nimekirja kaustast, vaid valin vaid need, mis on loodud kuu jooksul. Kohandage käsku vastavalt oma reaalsustele ja vajadustele:

curl -H "X-JFrog-Art-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[^/]+

Ülesannete seadistamine ja ülesande konfiguratsioonifail Jenkinsis

Oleksime nüüd allika versioonide nimekirja lahendanud. Liigume edasi ja lisame saadud nimekirja ülesandesse. Minu jaoks oli ilmne lahendus lisada samm rakenduse ülesande koostamiseks. Samm, mis täidetaks juhul, kui tulemus on "edukas".

Avame koostamisülesande seaded ja kerime kõige alla. Vajutame nuppudele: Lisa koostamissamm -> Tingimuslik samm (üksiku). Sammuseadetes valime tingimuse Praegune koostamise olek, määrame väärtuse SUCCESS, teostatav tegevus eduka tulemuse korral Käivita shell-käsk.

Ja nüüd kõige huvitavam. Jenkinsi ülesande konfiguratsioonid salvestatakse failides. XML-formaadis. Tee leidmine http://tee-ülesandeni/config.xml Seega on võimalik alla laadida konfiguratsioonifail, redigeerida seda vajalikul viisil ja panna tagasi sinna, kust see võeti.

Pidage meeles, et eelnevalt leppisime kokku, et loome versioonide nimekirja jaoks parameetri. BUILD_VERSION?

Laadime alla konfiguratsioonifaili ja kiigame selle sisse. Ainult et veenduda, et parameeter on kohal ja tõeliselt vajalikus vormis.

Kuvamine pildi all.

Teie config.xml fragment peab välja nägema samamoodi. Erandiks on see, et valikute elementide sisu on veel puudulik.
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

Olete kindel? Noh, kirjutame skripti, mis käivitatakse, kui kogumine on edukas.
Skripti ülesanne on saada versioonide nimekiri, alla laadida konfigureerimisfail, kirjutada sinna vajalikku kohta versioonide nimekiri ja seejärel asetada see tagasi. Jah. Kõik on õige. Kirjutame versioonide nimekirja XML-i sinna kohta, kus see juba on (see juhtub tulevikus pärast skripti esmakordset käivitamist). Tean, et maailmas on veel karvased regulaaravaldiste fännid. Mina sinna ei kuulu. Palun installige xmlstarlet sinna masinasse, kus konfi redigeeritakse. Tundub, et see ei ole nii suur hind, et vältida XML-i redigeerimist sed'iga.

Spoileri all jagan koodi, mis täidab eespool kirjeldatud järjestuse täielikult.

Kirjutame konfi versioonide nimekirja kaugserveri kaustast.

#!/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

Kui teile meeldib rohkem variant versioonide saamiseks Jenkins'ist ja olete samuti nii laisk nagu mina, siis spoileri all on sama kood, aga nimekiri Jenkins'ist:

Kirjutame konfi versioonide nimekirja Jenkins'ist.
Pidage meeles, et minu versiooni nimi koosneb järjestikku numbrist ja versiooninumbrist, mis on eraldatud kooloniga. Seetõttu kärbib awk ebavajaliku osa. Kohandage see rida oma vajadustele vastavaks.

#!/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

Ideaalis, kui olete katsetanud koodi, mis on kirjutatud eespooltoodud näidete põhjal, peaksid teil juba olema versioonide rippmenüüde valikud deploy ülesande puhul. Näiteks nagu ekraanipildil spoileris.

Korrektselt täidetud versioonide nimekiri
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

Kui kõik töötas, siis kopeerige skript Käivita shell-käsk ja salvestage muudatused.

Ühendamine Cloud shelliga

Meie kogujad asuvad konteinerites. Rakenduste kohaletoimetamise ja konfiguratsioonihalduri vahendina kasutame Ansible't. Seetõttu, kui jutt on konteinerite koostamisest, tuleb meelde kolm võimalust: paigaldada Docker Dockerisse, paigaldada Docker masinasse Ansible'iga või koostada konteinerid pilvekonsoolis. Jenkins'i pistikprogrammide kohta oleme selles märkmes vaikinud. Kas mäletate?

Ma otsustasin: kuna konteinerid on "kastist väljas" kogutud pilvekonsoolis, siis miks üldse vaeva näha? Hoidis puhtana, eks? Soovin koguda konteinerid Jenkinsiga pilvekonsoolis ja seejärel saadetada need Kubernetesse. Eriti kuna Google'i infrastruktuuris on tohutud kiiruskanalid, mis parandavad deploy kiirus.

Pilvekonsooliga ühendamiseks on vajalikud kaks asja: gcloud ja juurdepääsuõigused Google Cloud API selle VM-i eksemplari jaoks, millega ühendus luuakse.

Kellele, kes plaanib ühendada mitte Google'i pilvest
Google lubab võimalust deaktiveerida interaktiivne autoriseerimine oma teenustes. See võimaldab ühendust luua isegi kohvimasinast, kui see töötab *nix-süsteemidega ja tal on enda konsool.

Kui on vajadus, et ma selgitaksin seda küsimust üksikasjalikult selles märkmes — kirjutage kommentaaridesse. Kui hääli koguneb piisavalt — kirjutan selle teema kohta värskenduse.

Lihtsaim viis õiguste andmiseks on veebiliidese kaudu.

  1. Seiskage VM-i eksemplar, millega hiljem ühendus pilvekonsooliga luuakse.
  2. Avage eksemplari üksikasjad ja klõpsake Muuda.
  3. Lehe allosas valige eksemplari juurdepääsu ulatus Täielik juurdepääs kõikidele Cloud API-dele.

    Kuvamine
    Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

  4. Salvestage muudatused ja käivitage eksemplar.

Kui VM on laadimine lõpetanud, ühendage see SSH kaudu ja veenduge, et ühendus toimub tõrgeteta. Kasutage käsku:

gcloud alpha cloud-shell ssh

Eduka ühenduse näidis näeb välja umbes nii
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

Tõstmine GKE-sse

Kuna me püüame täielikult üleminekut IaC-le (Infrastructure as Code), hoitakse meie Dockerfile'e git'is. See on ühelt poolt. Tõstmine Kubernetesesse on kirjeldatud yaml-failis, mida kasutatakse ainult käesoleva ülesande tarbeks ja mis on ka iseenesest nagu kood. See on teiselt poolt. Ühesõnaga, plaan on järgmine:

  1. Võtame muutujate väärtused BUILD_VERSION ja vajadusel muutujate väärtused, mis edastatakse läbi ENV.
  2. Laadime git'ist alla Dockerfile.
  3. Genereerime yaml tõstmiseks.
  4. Üles laadime need kaks faili SCP kaudu pilvekontrolli.
  5. Seal ehitame konteineri ja push'ime selle Container registry'sse
  6. Kohaldame koormuse tõstmise faili Kubernetesesse.

Olgu, rääkides konkreetselt. Kuna oleme juba rääkinud ENV, siis eeldame, et peame edastama kahe parameetri väärtused: PARAM1 ja PARAM2. Lisame nende ülesande juurutamise, tüüp — String Parameter.

Kuvamine
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

YAML-i genereerime lihtsa suunamisega echo faili. Eeldatakse, et dockerefailis on olemas PARAM1 ja PARAM2, et koormuse nimi on awesomeapp, ja et kokku pandud konteiner antud versiooniga asub Container registry teel gcr.io/awesomeapp/awesomeapp-$BUILD_VERSION, kus $BUILD_VERSION oli just see, mis valiti rippmenüüst.

Käskude loetelu

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

Jenkins'i agendile, pärast ühendamist gcloud alpha cloud-shell ssh interaktiivne režiim ei ole saadaval, seega saadame käsud pilvekonsoli kaudu parameetriga —command.

Puhastame pilves konsoli kodukausta vanast dokkerfailist:

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

Asetame värskelt allalaaditud dokkerfaili pilves konsoli kodukausta scp abil:

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

Kogume, märgistame ja pushime konteineri Container registry'sse:

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"

Sarnast lähenemist kasutame ka deploy faili puhul. Palun märkige, et allpool kasutatavad käsklused viitavad väljamõeldud klastrite nimedele, kuhu toimub deploy (awsm-cluster) ja projekti nimele (awesome-project), kus klaster asub.

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"

Käivitame ülesande, vaatame konsoli väljundit ja loodame näha edukat konteineri koostamist.

Kuvamine
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

Ja sealt edasi ka edukat koostatud konteineri väljatõstmist

Kuvamine
Valmistame ülesande GKE-deploymiseks ilma pluginateta, SMS-ideta ja registreerimiseta. Ühe silmaga piilume Jenkins'i all sallist

Olen teadlikult jätnud tähelepanuta seadistamise Ingress. Üks lihtne põhjus: kui oled selle kord valmis seadistanud workload antud nimega, see jääb toimivaks, ükskõik kui palju selle nimega deploy'e teete. Ja üldiselt on see natuke ajaloost väljas.

Kokkuvõtte asemel

Kõiki eeltoodud samme oleks ilmselt võinud vältida ja lihtsalt paigaldada mingi Jenkins'i plugina, neid on miljoneid. Aga ma mingil põhjusel ei armasta pluginaid. Täpsemalt, kasutan neid ainult väljapääsu puudumisel.

Ja mulle lihtsalt meeldib uurida mõnd uut teemat. Ülalolev tekst on ka viis jagada avastusi, mille ma tegin, lahendades alguses kirjeldatud ülesande. Jagada neid, kes pole üldse karmid devopsis. Kui minu avastustest on kasu vähemalt ühelegi inimesele — olen rahul.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster