Прылада Helm і яго падводныя камяні

Прылада Helm і яго падводныя камяні
Typhon freight hauler concept, Anton Swanepoel

Мяне клічуць Зміцер Сугробаў, я распрацоўшчык у «Леруа Мерлен». У артыкуле распавяду, навошта патрэбен Helm, як ён спрашчае працу з Kubernetes, што памянялася ў трэцяй версіі і як з яго дапамогай абнаўляць прыкладанні ў прадакшэне без прастою.

Гэта канспект па матывах выступлення на канферэнцыі @Kubernetes Conference by Mail.ru Cloud Solutions - Калі не хочаце чытаць, глядзіце відэа.

Чаму мы выкарыстоўваем Kubernetes у прадакшэне

"Леруа Мерлен" – лідэр на рынку DIY-рытэйла ў Расіі і Еўропе. У нашай кампаніі больш за сто распрацоўшчыкаў, 33 унутраных супрацоўнікаў і велізарная колькасць людзей, якія наведваюць гіпермаркеты і сайт. Для таго, каб зрабіць усіх іх шчаслівымі, мы вырашылі прытрымлівацца стандартных падыходаў у індустрыі. Распрацоўваць новыя прыкладанні, выкарыстоўваючы мікрасэрвісную архітэктуру; для ізаляцыі акружэнняў і правільнай дастаўкі выкарыстоўваць кантэйнеры; а для аркестрацыі выкарыстоўваць Kubernetes. Кошт выкарыстання аркестратараў імкліва таннее: на рынку расце колькасць інжынераў, якія валодаюць тэхналогіяй, з'яўляюцца правайдэры, якія прапануюць Kubernetes як сэрвіс.

Усё, што робіць Kubernetes, вядома, можна зрабіць іншымі спосабамі, напрыклад, абшмараваўшы скрыптамі які-небудзь Джэнкінс і docker-compose, але навошта ўскладняць жыццё, калі ёсць гатовае і надзейнае рашэнне? Таму мы прыйшлі да Kubernetes і ўжо год яго выкарыстоўваем у прадакшэне. Цяпер у нас дваццаць чатыры кластары Kubernetes, самаму старому з іх больш за год, у ім каля двухсот падоў.

Праклён вялікай колькасці YAML-файлаў у Kubernetes

Для запуску мікрасэрвісу ў Kubernetes створым па меншай меры пяць YAML-файлаў: для Deployment, Service, Ingress, ConfigMap, Secrets – і адправім у кластар. Для наступнага прыкладання напішам той жа пакет ямлікаў, з трэцім - яшчэ адзін і гэтак далей. Памножым колькасць дакументаў на колькасць асяродкаў, ужо атрымаем сотні файлаў, і гэта яшчэ не ўлічваючы дынамічныя асяроддзі.

Прылада Helm і яго падводныя камяні
Adam Reese, core maintainer Helm, увёў паняццеЦыкл распрацоўкі ў Kubernetes», якое выглядае так:

  1. Copy YAML - капіяваць YAML-файл.
  2. Paste YAML - уставіць яго.
  3. Fix Indents - паправіць водступы.
  4. Repeat - паўтарыць зноўку.

Варыянт працоўны, але даводзіцца шмат разоў капіяваць YAML-файлы. Каб гэты цыкл змяніць, і прыдумалі Helm.

Што такое Helm

Па-першае, Helm - пакетны менеджэр, які дапамагае знаходзіць і ўсталёўваць патрэбныя праграмы. Для ўстаноўкі, напрыклад, MongoDB не трэба заходзіць на афіцыйны сайт і спампоўваць бінарнікі, дастаткова выканаць каманду helm install stable/mongodb.

Па-другое, Helm - шаблонізатар, дапамагае параметрызаваць файлы. Вернемся да сітуацыі з YAML-файламі ў Kubernetes. Прасцей напісаць той жа файл YAML, дадаць у яго некаторыя placeholder-ы, у якія Helm падставіць значэнні. Гэта значыць, замест вялікага набору ямлікаў будзе набор темплейтов (шаблонаў), у якія ў патрэбны момант падставяцца патрэбныя значэння.

Па-трэцяе, Helm майстар па разгортванні. З яго дапамогай можна ўсталёўваць, адкочваць і абнаўляць прыкладанні. Давайце разбяромся, як гэта рабіць.

Прылада Helm і яго падводныя камяні

Як карыстацца Helm для дэплою ўласных прыкладанняў

Усталюем Helm кліент на кампутар, прытрымліваючыся афіцыйнай інструкцыі. Затым створым набор YAML-файлаў. Замест указання канкрэтных значэнняў пакінем плэйсхолдэры, якія ў будучыні Helm запоўніць інфармацыяй. Набор такіх файлаў называецца Helm чарт. У кансольны кліент Helm яго можна адправіць трыма спосабамі:

  • пазначыць татачку з шаблонамі;
  • спакаваць у .tar архіў і паказаць на яго;
  • пакласці шаблон у выдалены рэпазітар і дадаць спасылку на рэпазітар у Helm кліент.

Яшчэ патрэбен файл са значэннямі - values.yaml. Дадзеныя адтуль будуць падстаўляцца ў шаблон. Створым і яго.

Прылада Helm і яго падводныя камяні
У другой версіі Helm ёсць дадатковы серверны дадатак – Tiller. Яно вісіць звонку Kubernetes і чакае запыты ад Helm-кліента, а пры выкліку падстаўляе патрэбныя значэнні ў шаблон і адпраўляе ў Kubernetes.

Прылада Helm і яго падводныя камяні
Helm 3 уладкованы прасцей: замест апрацоўкі шаблонаў на серверы, інфармацыя зараз апрацоўваецца цалкам на боку Helm-кліента і адпраўляецца напроста ў Kubernetes API. Гэта спрашчэнне павялічвае бяспеку кластара і палягчае схему выкату.

Як усё гэта працуе

Запускаем каманду helm install. Укажам назву рэлізу прыкладання, дадзім шлях да values.yaml. У канцы пакажам рэпазітар, у якім ляжыць чарт і назва чарта. У прыкладзе гэта "lmru" і "bestchart" адпаведна.

helm install --name bestapp --values values.yaml lmru/bestchart

Выкананне каманды магчыма толькі аднойчы, пры паўторным выкананні замест install трэба выкарыстоўваць upgrade. Для прастаты замест дзвюх каманд можна выконваць каманду upgrade з дадатковым ключом --install. Пры першым выкананні Helm адправіць каманду на ўстаноўку рэлізу, а ў далейшым будзе яго абнаўляць.

helm upgrade --install bestapp --values values.yaml lmru/bestchart

Падводныя камяні дэплою новых версій прыкладання з Helm

У гэтым месцы апавядання я гуляю з залай у «Хто хоча стаць мільянерам», і мы высвятляем, як прымусіць Helm абнавіць версію прыкладання. глядзець відэа.

Калі я вывучаў працу Helm, мяне здзівілі дзіўныя паводзіны пры спробе абнаўлення версій запушчаных прыкладанняў. Код прыкладання абнавіў, у докер-рэджыстры загрузіў новую выяву, адправіў каманду на дэплой - і нічога не адбылося. Ніжэй некалькі не зусім удалых спосабаў абнаўлення дадаткаў. Вывучаючы кожны з іх больш падрабязна, пачынаеш разумець унутраную прыладу прылады і чыннікі такіх не відавочных паводзін.

Спосаб 1. Не мяняць інфармацыю з моманту апошняга запуску

Як абвяшчае афіцыйны сайт Helm, "Kubernetes чарты бываюць вялікімі і складанымі, таму Helm імкнецца лішні раз нічога не чапаць". Таму, калі абнавіць latest-версію выявы прыкладання ў docker registry і выканаць каманду helm upgrade, то нічога не адбудзецца. Helm будзе думаць, што нічога не памянялася і пасылаць у Kubernetes каманду на абнаўленне прыкладання не трэба.

Тут і далей тэг latest паказаны выключна ў якасці прыкладу. Пры ўказанні гэтага тэга Kubernetes будзе кожны раз спампоўваць выяву з docker registry, па-за залежнасцю ад параметра imagePullPolicy. Выкарыстанне latest ў прадакшэне непажадана і выклікае пабочныя эфекты.

Спосаб 2. Абнаўляць LABEL у image

Як напісана ў той жа дакументацыі, «Helm будзе абнаўляць прыкладанне, толькі калі яно памянялася з моманту апошняга рэлізу». Лагічным варыянтам для гэтага здасца абнаўленне пазнакі LABEL у самім докер-выяве. Аднак Helm не зазірае ў выявы прыкладанняў і не мае паняцці аб якія-небудзь зменах у іх. Адпаведна, пры абнаўленні метак у выяве Helm пра іх не пазнае, і каманда абнаўлення прыкладання ў Kubernetes не паступіць.

Спосаб 3. Выкарыстоўваць ключ --force

Прылада Helm і яго падводныя камяні
Звернемся да мануалаў і пашукаем патрэбны ключык. Больш за ўсё па сэнсе падыходзіць ключ --force. Нягледзячы на ​​размаўлялую назву, паводзіны адрозніваюцца ад чаканага. Замест фарсіраванага абнаўлення прыкладання, яго рэальнае прызначэнне - аднаўленне які знаходзіцца ў статусе FAILED рэлізу. Калі не выкарыстоўваць гэты ключ, тое трэба паслядоўна выконваць каманды helm delete && helm install --replace. Замест гэтага прапануецца выкарыстоўваць ключ --force, які аўтаматызуе паслядоўнае выкананне гэтых каманд. Больш інфармацыі ў гэтым пул-рэквест. Для таго каб сказаць Helm усёткі абнавіць версію прыкладання, нажаль, гэты ключ не падыдзе.

Спосаб 4. Змяняць labels напрамую ў Kubernetes

Прылада Helm і яго падводныя камяні
Абнаўленне label напрамую ў кластары з дапамогай каманды kubectl edit - дрэнная ідэя. Гэта дзеянне прывядзе да некансістэнтнасці інфармацыі паміж працуючым дадаткам і тым, што першапачаткова адправілася на дэплой. Паводзіны Helm пры дэплоі ў гэтым выпадку адрозніваецца ад яго версіі: Helm 2 нічога рабіць не будзе, а Helm 3 задэплоіць новую версію прыкладання. Для разумення прычыны трэба зразумець, як працуе Helm.

Як уладкованы Helm

Для вызначэння, ці змянілася прыкладанне з моманту апошняга рэлізу, Helm можа скарыстацца:

  • запушчаным дадаткам у Kubernetes;
  • новым values.yaml і актуальным чартам;
  • унутранай інфармацыяй Helm аб рэлізах.

Для самых дапытлівых: дзе Helm захоўвае ўнутраную інфармацыю аб рэлізах?Выканаўшы каманду helm history, мы атрымаем усю інфармацыю аб версіях, устаноўленых з дапамогай Helm.

Прылада Helm і яго падводныя камяні
Яшчэ ёсць падрабязная інфармацыя аб адпраўленых шаблонах і значэннях. Мы можам яе запытаць:

Прылада Helm і яго падводныя камяні
У другой версіі Helm гэтая інфармацыя ляжыць у тым жа неймспейсе, дзе запушчаны Tiller (па змаўчанні - kube-system), у ConfigMap, пазначаным пазнакай «OWNER=TILLER»:

Прылада Helm і яго падводныя камяні
У момант з'яўлення трэцяй версіі Helm інфармацыя пераехала ў сакрэты, прычым у той жа неймспейс, дзе запушчана дадатак. Дзякуючы гэтаму стала магчыма запускаць адначасова некалькі прыкладанняў у розных неймспейсах з аднолькавай назвай рэлізу. У другой версіі гэта быў моцны галаўны боль, калі неймспейсы ізаляваныя, але могуць сябар на сябра ўплываць.

Прылада Helm і яго падводныя камяні

Другі Helm, калі спрабуе зразумець, ці трэба абнаўленне, выкарыстоўвае толькі дзве крыніцы інфармацыі: тое, што яму падалі цяпер, і ўнутраную інфармацыю аб рэлізах, якая ляжыць у ConfigMap.

Прылада Helm і яго падводныя камяні
Трэці Helm выкарыстоўвае стратэгію three-way merge: у дадатак да той інфармацыі ўлічвае яшчэ і дадатак, якое працуе прама зараз у Kubernetes.

Прылада Helm і яго падводныя камяні
Па гэтым чынніку старая версія Helm не будзе нічога рабіць, бо не ўлічвае інфармацыю прыкладання ў кластары, а вось Helm 3 атрымае змены і адправіць новае прыкладанне на дэплой.

Спосаб 5. Выкарыстоўваць ключ -recreate-pods

З дапамогай ключа --recreate-pods можна дасягнуць таго, што першапачаткова планавалася атрымаць з дапамогай ключа --force. Кантэйнеры перазапусцяць і, паводле палітыкі imagePullPolicy: Always для тэга latest (пра гэта ў зносцы вышэй), Kubernetes запампуе і запусціць новую версію выявы. Рабіць будзе гэта не самай лепшай выявай: не ўлічваючы StrategyType дэплойменту, рэзка выключыць усе старыя інстансы прыкладання і пайдзе запускаць новыя. Падчас перазапуску сістэма не будзе працаваць, карыстачы будуць пакутаваць.

У самым Kubernetes падобная праблема таксама існавала працяглы час. І вось, праз 4 гады пасля адкрыцця Пытанне, праблему выправілі, і пачынальна з 1.15 версіі Kubernetes з'яўляецца магчымасць rolling-restart подаў.

Helm жа проста выключае ўсе прыкладанні і запускае побач новыя кантэйнеры. У прадакшэне так рабіць нельга, каб не выклікаць просты прыкладанні. Такое трэба толькі для патрэб распрацоўкі, можна выконваць толькі ў stage-акружэннях.

Як абнавіць версію прыкладання з дапамогай Helm?

Будзем мяняць значэння, якія адпраўляюцца ў Helm. Як правіла, гэта значэння, якія падстаўляюцца на месца тэга выявы. У выпадку latest, часта выкарыстоўванага для непрадуктыўных асяродкаў, у ролі змянянай інфармацыі выступае анатацыя, якая для самога Kubernetes бескарысная, а для Helm будзе выступаць сігналам да неабходнасці абнаўлення прыкладання. Варыянты запаўнення значэння анатацыі:

  1. Рандомнае значэнне з дапамогай стандартнай функцыі - {{ randAlphaNum 6 }}.
    Ёсць нюанс: пасля кожнага дэплою з выкарыстаннем чарта з такой зменнай значэнне анатацыі будзе ўнікальным, і Helm будзе меркаваць, што ёсць змены. Атрымліваецца, заўсёды будзем перазапускаць дадатак, нават калі не памянялі яго версію. Гэта не крытычна, бо прастою не будзе, але ўсё ж непрыемна.
  2. Устаўляць бягучую дату і час - {{ .Release.Date }}.
    Варыянт падобны на рандомнае значэнне з стала ўнікальнай зменнай.
  3. Больш правільны спосаб - выкарыстоўваць кантрольныя сумы. Гэта SHA выявы або SHA апошняга комміта ў гіце {{ .Values.sha }}.
    Іх трэба будзе падлічваць і адпраўляць у Helm кліент на задзірлівым боку, напрыклад у Джэнкінсе. Калі дадатак памянялася, то і кантрольная сума памяняецца. Такім чынам, Helm будзе абнаўляць дадатак толькі тады, калі трэба.

Падагульнім нашы спробы

  • Helm робіць змены найменш інвазіўным спосабам, таму любая змена на ўзроўні выявы прыкладання ў Docker Registry не прывядзе да абнаўлення: пасля выканання каманды нічога не адбудзецца.
  • ключ --force выкарыстоўваецца для аднаўлення праблемных рэлізаў і не злучаны з прымусовым абнаўленнем.
  • ключ --recreate-pods прымусова абновіць прыкладанні, але зробіць гэта вандальным спосабам: рэзка выключыць усе кантэйнеры. Ад гэтага пацерпяць карыстачы, на продзе так рабіць не варта.
  • Напрамую ўносіць змены ў кластар Kubernetes з дапамогай каманды kubectl edit не трэба: парушым кансістэнтнасць, а паводзіны будуць адрознівацца ў залежнасці ад версіі Helm.
  • З выхадам новай версіі Helm з'явілася шмат нюансаў. Issues у рэпазітары Helm апісаны зразумелай мовай, яны дапамогуць разабрацца ў дэталях.
  • Даданне змененай анатацыі ў чарт зробіць яго больш гнуткім. Гэта дазволіць выкочваць прыкладанне правільна, без прастою.

Думка з разраду "мір ва ўсім свеце", якая працуе ва ўсіх сферах жыцця: чытайце інструкцыю перад ужываннем, а не пасля. Толькі валодаючы поўнай інфармацыяй, атрымаецца будаваць надзейныя сістэмы і рабіць карыстачоў шчаслівымі.

Іншыя спасылкі па тэме:

  1. Знаёмства з шлем 3
  2. Афіцыйны сайт Helm
  3. Рэпазітар Helm на GitHub
  4. 25 карысных інструментаў Kubernetes: разгортванне і кіраванне

Гэты даклад упершыню прагучаў на @Kubernetes Conference by Mail.ru Cloud Solutions. Глядзіце відэа іншых выступаў і падпісвайцеся на анонсы мерапрыемстваў у Telegram Вакол Kubernetes у Mail.ru Group.

Крыніца: habr.com

Дадаць каментар