Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Све је почело када нас је вођа тима једног од наших развојних тимова замолила да тестирамо њихову нову апликацију, која је дан раније била у контејнерима. Ја сам то објавио. После 20-ак минута стигао је захтев за ажурирање апликације, јер је ту додата веома неопходна ствар. обновио сам. После још пар сати... па, можете да претпоставите шта је следеће почело...

Морам признати да сам прилично лењ (зар нисам то раније признао? Не?), а с обзиром на то да челници тимова имају приступ Џенкинсу, у којем имамо све ЦИ/ЦД, помислио сам: нека се распореди као колико хоће! Сетих се једног вица: дај човеку рибу и он ће јести један дан; назовите особу Фед и она ће бити Фед целог живота. И отишао играјте трикове на послу, који би могао да примени контејнер који садржи апликацију било које успешно уграђене верзије у Кубер и пренесе све вредности у њега ЕНВ (мој деда, филолог, некада професор енглеског, сада би после читања ове реченице завртео прстом на слепоочници и веома изражајно ме погледао).

Дакле, у овој белешци ћу вам рећи како сам научио:

  1. Динамичко ажурирање послова у Џенкинсу из самог посла или из других послова;
  2. Повежите се на клауд конзолу (Цлоуд схелл) из чвора са инсталираним Јенкинс агентом;
  3. Поставите радно оптерећење на Гоогле Кубернетес Енгине.


У ствари, ја сам, наравно, помало неискрен. Претпоставља се да имате бар део инфраструктуре у Гоогле облаку, па сте, према томе, његов корисник и, наравно, имате ГЦП налог. Али ова белешка није о томе.

Ово је моја следећа варалица. Само у једном случају желим да напишем такве белешке: суочио сам се са проблемом, у почетку нисам знао како да га решим, решење није било готово изгуглано, па сам га прогуглао у деловима и на крају решио проблем. И да убудуће, када заборавим како сам то урадио, не морам поново да гуглам све део по део и састављам заједно, пишем себи такве варалице.

odricanje: 1. Белешка је написана „за себе“, за улогу Најбоља пракса не важи. Драго ми је да прочитам опције „било би боље да то урадимо на овај начин“ у коментарима.
2. Ако се примењени део ноте сматра сољу, онда је, као и све моје претходне белешке, и ова слаб раствор соли.

Динамичко ажурирање поставки посла у Џенкинсу

Предвиђам ваше питање: какве везе са тим има динамичко ажурирање посла? Унесите вредност параметра стринга ручно и можете!

Одговарам: баш сам лењ, не волим кад се жале: Миша, рушење размештања, све је нестало! Почнете да тражите, а постоји грешка у куцању у вредности неког параметра покретања задатка. Зато више волим да све радим што ефикасније. Ако је могуће спречити корисника да директно унесе податке давањем листе вредности за избор, онда организујем избор.

План је следећи: креирамо посао у Џенкинсу, у којем бисмо, пре покретања, могли да изаберемо верзију са листе, наведемо вредности за параметре који се преносе у контејнер преко ЕНВ, затим прикупља контејнер и гура га у регистар контејнера. Затим се одатле контејнер покреће у цубер ас оптерећења са параметрима наведеним у послу.

Нећемо разматрати процес стварања и постављања посла у Џенкинсу, ово није тема. Претпоставићемо да је задатак спреман. Да бисмо имплементирали ажурирану листу са верзијама, потребне су нам две ствари: постојећа листа извора са а приори важећим бројевима верзија и променљива као што је Параметар избора у задатку. У нашем примеру нека променљива буде именована БУИЛД_ВЕРСИОН, нећемо се детаљније задржавати на томе. Али хајде да ближе погледамо листу извора.

Нема толико опција. Две ствари су ми одмах пале на памет:

  • Користите АПИ за даљински приступ који Џенкинс нуди својим корисницима;
  • Затражите садржај фолдера удаљеног спремишта (у нашем случају ово је ЈФрог Артифацтори, што није важно).

Јенкинс АПИ за даљински приступ

По устаљеној одличној традицији, радије бих избегао дуга објашњења.
Дозволићу себи само слободан превод дела првог пасуса прва страница АПИ документације:

Јенкинс обезбеђује АПИ за даљински машински читљив приступ његовој функционалности. <…> Даљински приступ се нуди у стилу РЕСТ-а. То значи да не постоји јединствена улазна тачка за све функције, већ УРЛ као што је „.../апи/", Где "..." означава објекат на који су примењене могућности АПИ-ја.

Другим речима, ако је задатак распоређивања о коме тренутно говоримо доступан на http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build, тада су АПИ звиждуци за овај задатак доступни на http://jenkins.mybuild.er/view/AweSomeApp/job/AweSomeApp_build/api/

Затим имамо избор у ком облику да примимо излаз. Хајде да се фокусирамо на КСМЛ, пошто АПИ само у овом случају дозвољава филтрирање.

Хајде само да покушамо да добијемо листу свих послова. Интересује нас само назив скупштине (Показати име) и његов резултат (резултат):

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

Испоставило се?

Хајде сада да филтрирамо само оне рунде које заврше са резултатом СУЦЦЕСС. Хајде да искористимо аргумент &искључи а као параметар ћемо му проследити путању до вредности која није једнака СУЦЦЕСС. Да да. Двоструки негатив је изјава. Искључујемо све што нас не занима:

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

Снимак екрана листе успешних
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Па, из забаве, хајде да се уверимо да нас филтер није преварио (филтери никада не лажу!) и прикажемо листу „неуспешних“:

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

Снимак екрана листе неуспешних
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Листа верзија из фасцикле на удаљеном серверу

Постоји други начин да добијете листу верзија. Свиђа ми се чак и више од приступа Јенкинс АПИ-ју. Па, јер ако је апликација успешно направљена, то значи да је упакована и смештена у спремиште у одговарајућој фасцикли. На пример, спремиште је подразумевано складиште радних верзија апликација. Као. Па, хајде да га питамо које су верзије у складишту. Ми ћемо савијати, греп и авк удаљену фасциклу. Ако је неко заинтересован за онелајнер, онда је испод спојлера.

Команда у једној линији
Имајте на уму две ствари: преносим детаље везе у заглављу и не требају ми све верзије из фасцикле, а бирам само оне које су направљене у року од месец дана. Уредите команду тако да одговара вашим реалностима и потребама:

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[^/]+' )

Подешавање послова и конфигурационе датотеке послова у Јенкинсу

Открили смо извор листе верзија. Хајде да сада уградимо резултујућу листу у задатак. За мене је очигледно решење било додавање корака у задатак израде апликације. Корак који би се извршио ако би резултат био „успех“.

Отворите подешавања задатка склапања и померите се до самог дна. Кликните на дугмад: Додај корак изградње -> Условни корак (један). У подешавањима корака изаберите услов Тренутни статус израде, поставите вредност СУЦЦЕСС, радња која ће се извршити ако је успешна Покрените команду љуске.

А сада забавни део. Џенкинс складишти конфигурације послова у фајловима. У КСМЛ формату. Успут http://путь-до-задания/config.xml Сходно томе, можете преузети конфигурациону датотеку, уредити је по потреби и вратити је тамо где сте је добили.

Запамтите, горе смо се договорили да ћемо креирати параметар за листу верзија БУИЛД_ВЕРСИОН?

Хајде да преузмемо конфигурациону датотеку и завиримо у њу. Само да бисте били сигурни да је параметар на месту и жељеног типа.

Снимак екрана испод спојлера.

Ваш цонфиг.кмл фрагмент би требало да изгледа исто. Осим што још недостаје садржај елемента избора
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Јеси ли сигуран? То је то, хајде да напишемо скрипту која ће се извршити ако градња буде успешна.
Скрипта ће добити листу верзија, преузети конфигурациону датотеку, уписати листу верзија у њу на место које нам је потребно, а затим је вратити. Да. Тако је. Напишите листу верзија у КСМЛ-у на месту где већ постоји листа верзија (биће у будућности, након првог покретања скрипте). Знам да у свету још увек има жестоких љубитеља регуларних израза. Ја не припадам њима. Молимо инсталирајте кмлстарлер на машину где ће се конфигурација уређивати. Чини ми се да ово није тако велика цена да бисте избегли уређивање КСМЛ-а помоћу сед-а.

Испод спојлера представљам код који у целини изводи горњи низ.

Напишите листу верзија из фасцикле на удаљеном серверу у конфигурацију

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

Ако више волите опцију да добијете верзије од Џенкинса и лењи сте као ја, онда је испод спојлера исти код, али списак од Џенкинса:

Напишите листу верзија од Џенкинса у конфигурацију
Само имајте ово на уму: моје име склопа се састоји од редног броја и броја верзије, одвојених двотачком. Сходно томе, авк одсеца непотребан део. За себе, промените ову линију да одговара вашим потребама.

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

У теорији, ако сте тестирали код написан на основу горњих примера, онда би у задатку имплементације већ требало да имате падајућу листу са верзијама. Као на снимку испод спојлера.

Тачно попуњена листа верзија
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Ако је све функционисало, копирајте и залепите скрипту Покрените команду љуске и сачувајте промене.

Повезивање на Цлоуд схелл

Имамо сакупљаче у контејнерима. Користимо Ансибле као наш алат за испоруку апликација и менаџер конфигурације. Сходно томе, када је у питању прављење контејнера, три опције падају на памет: инсталирајте Доцкер у Доцкер, инсталирајте Доцкер на машини на којој ради Ансибле или направите контејнере у конзоли у облаку. Договорили смо се да ћутимо о додацима за Џенкинса у овом чланку. Запамтити?

Одлучио сам: па, пошто се контејнери „из кутије“ могу сакупљати у конзоли у облаку, зашто се онда мучити? Нека буде чисто, зар не? Желим да прикупим Џенкинсове контејнере у клауд конзоли, а затим да их одатле покренем у цубер. Штавише, Гугл има веома богате канале у оквиру своје инфраструктуре, што ће благотворно утицати на брзину примене.

Да бисте се повезали са клауд конзолом, потребне су вам две ствари: гцлоуд и права приступа Гоогле Цлоуд АПИ за ВМ инстанцу са којом ће се ова иста веза успоставити.

За оне који планирају да се повежу не из Гоогле облака уопште
Гоогле дозвољава могућност онемогућавања интерактивне ауторизације у својим услугама. Ово ће вам омогућити да се повежете на конзолу чак и са апарата за кафу, ако ради *ник и има саму конзолу.

Ако постоји потреба да ово питање детаљније покријем у оквиру ове белешке, напишите у коментарима. Ако добијемо довољно гласова, написаћу ажурирање на ову тему.

Најлакши начин да доделите права је преко веб интерфејса.

  1. Зауставите ВМ инстанцу са које ћете се накнадно повезати на клауд конзолу.
  2. Отворите Детаљи о инстанци и кликните Н · н РјРμРЅРоС, СЊ.
  3. На самом дну странице изаберите опсег приступа инстанци Потпун приступ свим Цлоуд АПИ-јима.

    Сцреенсхот
    Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

  4. Сачувајте промене и покрените инстанцу.

Када се ВМ заврши са учитавањем, повежите се са њим преко ССХ-а и уверите се да се веза одвија без грешке. Користите команду:

gcloud alpha cloud-shell ssh

Успешна веза изгледа отприлике овако
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Поставите у ГКЕ

Пошто на све могуће начине тежимо да у потпуности пређемо на ИаЦ (Инфрастуктура као код), наши доцкер фајлови се чувају у Гиту. Ово је с једне стране. А примена у кубернетес-у је описана иамл датотеком, коју користи само овај задатак, који је сам по себи такође као код. Ово је са друге стране. Генерално, мислим, план је следећи:

  1. Узимамо вредности променљивих БУИЛД_ВЕРСИОН и, опционо, вредности променљивих кроз које ће бити прослеђене ЕНВ.
  2. Преузмите доцкер фајл са Гита.
  3. Генеришите иамл за примену.
  4. Обе ове датотеке отпремамо преко сцп-а на клауд конзолу.
  5. Тамо правимо контејнер и гурамо га у регистар контејнера
  6. Примењујемо датотеку за примену учитавања на цубер.

Хајде да будемо конкретнији. Једном када смо почели да причамо о ЕНВ, онда претпоставимо да треба да пренесемо вредности два параметра: ПАРАМ1 и ПАРАМ2. Додамо њихов задатак за примену, укуцајте - Стринг Параметер.

Сцреенсхот
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Ми ћемо генерисати иамл једноставним преусмеравањем одјек да поднесе. Претпоставља се, наравно, да имате у свом доцкер фајлу ПАРАМ1 и ПАРАМ2да ће назив оптерећења бити авесомеапп, а састављени контејнер са апликацијом наведене верзије лежи у Регистар контејнера успут гцр.ио/авесомеапп/авесомеапп-$БУИЛД_ВЕРСИОНГде $БУИЛД_ВЕРСИОН је управо изабран са падајуће листе.

Списак тима

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

Јенкинс агент након повезивања користећи гцлоуд алфа цлоуд-схелл ссх интерактивни режим није доступан, па шаљемо команде у клауд конзолу помоћу параметра --команда.

Очистимо почетну фасциклу у клауд конзоли из старог доцкер фајла:

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

Поставите свеже преузету доцкер датотеку у почетну фасциклу клауд конзоле користећи сцп:

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

Прикупљамо, означавамо и гурамо контејнер у регистар контејнера:

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"

Исто радимо са датотеком за примену. Имајте на уму да наредбе у наставку користе измишљена имена кластера у којем се одвија имплементација (авсм-цлустер) и назив пројекта (супер-пројекат), где се налази кластер.

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"

Покрећемо задатак, отварамо излаз конзоле и надамо се да ћемо видети успешно склапање контејнера.

Сцреенсхот
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

А онда успешно постављање састављеног контејнера

Сцреенсхот
Креирамо задатак постављања у ГКЕ без додатака, СМС-а или регистрације. Хајде да завиримо испод Џенкинсове јакне

Намерно сам игнорисао поставку Улаз. Из једног једноставног разлога: када га поставите оптерећења са датим именом, остаће оперативан, без обзира на то колико распоређивања са овим именом извршите. Па, генерално, ово је мало ван оквира историје.

Уместо закључака

Сви горе наведени кораци вероватно нису могли бити урађени, већ једноставно инсталиран неки додатак за Џенкинса, њихов мууулион. Али из неког разлога не волим додатке. Па, тачније, прибегавам им само из очаја.

И само волим да отворим неку нову тему за себе. Горњи текст је такође начин да поделим налазе до којих сам дошао док сам решавао проблем описан на самом почетку. Поделите са онима који, попут њега, уопште нису страшни вук у девопсу. Ако моји налази помогну бар некоме, биће ми драго.

Извор: ввв.хабр.цом

Додај коментар