Werfga 3 tomonlama birlashish: Helm bilan Kubernetes-ga “steroidlarda” joylashtirish

Biz (nafaqat biz) uzoq vaqtdan beri kutgan narsa yuz berdi: werf, ilovalarni yaratish va ularni Kubernetes-ga yetkazib berish uchun ochiq manbali yordamchi dasturimiz endi 3 tomonlama birlashma yamoqlari yordamida o‘zgarishlarni qo‘llashni qo‘llab-quvvatlaydi! Bunga qo'shimcha ravishda, mavjud K8 resurslarini Helm relizlariga ushbu resurslarni qayta tiklamasdan o'zlashtirish mumkin.

Werfga 3 tomonlama birlashish: Helm bilan Kubernetes-ga “steroidlarda” joylashtirish

Agar u juda qisqa bo'lsa, biz qo'yamiz WERF_THREE_WAY_MERGE=enabled - bizda bo'lgani kabi joylashtirishni olamiz kubectl apply", mavjud Helm 2 o'rnatishlari bilan mos keladi va hatto biroz ko'proq.

Ammo keling, nazariyadan boshlaylik: 3 tomonlama birlashma yamoqlari nima, odamlar ularni yaratishga qanday yondashishdi va nima uchun ular Kubernetesga asoslangan infratuzilma bilan CI/CD jarayonlarida muhim? Shundan so'ng, keling, werfda 3 tomonlama birlashma nima ekanligini, sukut bo'yicha qanday rejimlar ishlatilishini va uni qanday boshqarishni ko'rib chiqamiz.

3 tomonlama birlashma yamog'i nima?

Shunday qilib, keling, YAML manifestlarida tasvirlangan resurslarni Kubernetesga chiqarish vazifasidan boshlaylik.

Resurslar bilan ishlash uchun Kubernetes API quyidagi asosiy operatsiyalarni taklif qiladi: yaratish, tuzatish, almashtirish va oʻchirish. Ularning yordami bilan resurslarni klasterga qulay uzluksiz yo'naltirishni qurish kerak deb taxmin qilinadi. Qanaqasiga?

kubectl imperativ buyruqlari

Kubernetes-da ob'ektlarni boshqarishning birinchi yondashuvi kubectl imperativ buyruqlarini ushbu ob'ektlarni yaratish, o'zgartirish va o'chirish uchun ishlatishdir. Oddiy qilib aytganda:

  • jamoa kubectl run Deployment yoki Jobni ishga tushirishingiz mumkin:
    kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE
  • jamoa kubectl scale - nusxalar sonini o'zgartirish:
    kubectl scale --replicas=3 deployment/mysql
  • va hokazo.

Bu yondashuv birinchi qarashda qulay ko'rinishi mumkin. Biroq, muammolar mavjud:

  1. Bu qiyin avtomatlashtirish.
  2. qanday konfiguratsiyani aks ettiradi Gitda? Klasterda sodir bo'layotgan o'zgarishlarni qanday ko'rib chiqish mumkin?
  3. Qanday ta'minlash takrorlanuvchanlik qayta ishga tushirishda konfiguratsiyalar?
  4. ...

Ushbu yondashuv dastur va infratuzilmani kod sifatida saqlashga mos kelmasligi aniq (IaC; hattoki GitOps zamonaviyroq variant sifatida Kubernetes ekotizimida mashhurlikka erishmoqda). Shuning uchun, bu buyruqlar kubectl-da keyingi rivojlanishni olmadi.

Operatsiyalarni yaratish, olish, almashtirish va o'chirish

Birlamchi bilan yaratish Bu oddiy: manifestni operatsiyaga yuboring create kube api va resurs yaratildi. Manifestning YAML ko'rinishi Git-da saqlanishi va buyruq yordamida yaratilishi mumkin kubectl create -f manifest.yaml.

С olib tashlash ham oddiy: bir xil o'rniga qo'ying manifest.yaml Gitdan jamoaga kubectl delete -f manifest.yaml.

Operatsiya replace resursni qayta yaratmasdan, resurs konfiguratsiyasini to'liq yangisiga almashtirish imkonini beradi. Bu shuni anglatadiki, resursga o'zgartirish kiritishdan oldin operatsiya bilan joriy versiyani so'rash mantiqan to'g'ri keladi get, uni o'zgartiring va operatsiya bilan yangilang replace. kube apiserver o'rnatilgan optimistik qulflash va agar operatsiyadan keyin get ob'ekt o'zgardi, keyin operatsiya replace ishlamaydi.

Konfiguratsiyani Git-da saqlash va almashtirish yordamida yangilash uchun siz operatsiyani bajarishingiz kerak get, Git-dan konfiguratsiyani biz olgan narsalar bilan birlashtiring va bajaring replace. Odatiy bo'lib, kubectl faqat buyruqdan foydalanishga imkon beradi kubectl replace -f manifest.yamlqayerda manifest.yaml - allaqachon to'liq tayyorlangan (bizning holatlarimizda, birlashtirilgan) o'rnatilishi kerak bo'lgan manifest. Ma'lum bo'lishicha, foydalanuvchi birlashma manifestlarini amalga oshirishi kerak va bu ahamiyatsiz masala emas ...

Shuni ham ta'kidlash joizki, garchi manifest.yaml va Git-da saqlanadi, biz ob'ektni yaratish yoki uni yangilash zarurligini oldindan bila olmaymiz - buni foydalanuvchi dasturiy ta'minoti amalga oshirishi kerak.

Jami: uzluksiz ishlab chiqarishni qura olamizmi? faqat yaratish, almashtirish va o'chirishdan foydalanib, infratuzilma konfiguratsiyasi kod va qulay CI/CD bilan birga Gitda saqlanishini ta'minlaysizmi?

Printsipial jihatdan, biz mumkin ... Buning uchun birlashtirish operatsiyasini amalga oshirishingiz kerak bo'ladi manifestlar va ba'zi bir majburiyatlar:

  • klasterda ob'ekt mavjudligini tekshiradi,
  • dastlabki resurs yaratishni amalga oshiradi,
  • uni yangilaydi yoki o'chiradi.

Yangilashda shuni yodda tuting resurs o'zgargan bo'lishi mumkin oxirgidan beri get va optimistik qulflash holatini avtomatik tarzda boshqaring - takroriy yangilanishga urinishlar qiling.

Biroq, kube-apiserver resurslarni yangilashning yana bir usulini taklif qilganda, nima uchun g'ildirakni qayta kashf qilish kerak: operatsiya patch, bu foydalanuvchini tasvirlangan ba'zi muammolardan xalos qiladi?

yamoq

Endi biz yamoqlarga o'tamiz.

Yamalar Kubernetes-dagi mavjud ob'ektlarga o'zgartirishlarni qo'llashning asosiy usuli hisoblanadi. Operatsiya patch u shunday ishlaydi:

  • kube-apiserver foydalanuvchisi JSON shaklida yamoq yuborishi va ob'ektni ko'rsatishi kerak,
  • va apiserverning o'zi ob'ektning hozirgi holati bilan shug'ullanadi va uni kerakli shaklga keltiradi.

Bu holda optimistik qulflash talab qilinmaydi. Bu operatsiya almashtirishdan ko'ra ko'proq deklarativdir, garchi dastlab bu boshqacha ko'rinishi mumkin.

Shunday qilib:

  • operatsiya yordamida create biz Git manifestiga ko'ra ob'ekt yaratamiz,
  • yordamida delete - agar ob'ekt kerak bo'lmasa, o'chirish;
  • yordamida patch — ob'ektni o'zgartiramiz, uni Gitda tasvirlangan shaklga keltiramiz.

Biroq, buning uchun siz yaratishingiz kerak to'g'ri patch!

Helm 2 da yamalar qanday ishlaydi: 2 tomonlama birlashtirish

Relizni birinchi marta o'rnatganingizda, Helm operatsiyani bajaradi create grafik resurslari uchun.

Har bir resurs uchun Helm versiyasini yangilashda:

  • oldingi diagrammadagi manba versiyasi va joriy grafik versiyasi o'rtasidagi yamoqni ko'rib chiqadi,
  • ushbu yamoqni qo'llaydi.

Biz bu patchni chaqiramiz 2 tomonlama birlashma patchi, chunki uni yaratishda 2 ta manifest ishtirok etadi:

  • oldingi nashrdagi resurs manifestlari,
  • joriy resursdan manifest resurs.

Operatsiyani olib tashlashda delete kube apiserver oldingi versiyada e'lon qilingan, ammo joriy versiyada e'lon qilinmagan resurslar uchun chaqiriladi.

Ikki tomonlama birlashma patch yondashuvida muammo bor: u olib keladi klasterdagi resursning haqiqiy holati va Gitdagi manifest bilan hamohang emas.

Muammoni misol bilan tasvirlash

  • Git-da diagramma maydon joylashgan manifestni saqlaydi image Joylashtirish muhim ubuntu:18.04.
  • Foydalanuvchi orqali kubectl edit bu maydon qiymatini o'zgartirdi ubuntu:19.04.
  • Helm diagrammasini qayta joylashtirishda patch hosil qilmaydi, chunki maydon image relizning oldingi versiyasida va joriy jadvalda bir xil.
  • Qayta joylashtirishdan keyin image qoldiqlar ubuntu:19.04Garchi grafikda aytilgan bo'lsa-da ubuntu:18.04.

Biz desinxronizatsiya oldik va deklarativlikni yo'qotdik.

Sinxronlashtirilgan resurs nima?

Odatda, to'liq Ishlayotgan klasterdagi resurs manifesti va Git-dan manifest o'rtasida moslikni olish mumkin emas. Chunki haqiqiy manifestda xizmat izohlari/yorliqlari, qo'shimcha konteynerlar va boshqa ma'lumotlar bo'lishi mumkin, ular ba'zi kontrollerlar tomonidan manbaga dinamik ravishda qo'shiladi va o'chiriladi. Biz bu ma'lumotlarni Git-da saqlay olmaymiz va xohlamaymiz. Biroq, biz Git-da aniq ko'rsatgan maydonlar ishga tushirilganda tegishli qiymatlarni olishini xohlaymiz.

Bu juda umumiy bo'lib chiqdi sinxronlashtirilgan resurs qoidasi: resursni ishga tushirishda siz faqat Git-dan manifestda aniq ko'rsatilgan (yoki oldingi versiyada ko'rsatilgan va hozir o'chirilgan) maydonlarni o'zgartirishingiz yoki o'chirishingiz mumkin.

3 tomonlama birlashma patchi

Asosiy g'oya 3 tomonlama birlashma patchi: ishlayotgan klasterdagi manifestning joriy versiyasini hisobga olgan holda Git-dan manifestning so'nggi qo'llaniladigan versiyasi va Git-dan manifestning maqsadli versiyasi o'rtasida yamoq yaratamiz. Olingan yamoq sinxronlashtirilgan manba qoidasiga mos kelishi kerak:

  • maqsadli versiyaga qo'shilgan yangi maydonlar yamoq yordamida qo'shiladi;
  • oxirgi qo'llanilgan versiyada ilgari mavjud bo'lgan va maqsadli versiyada mavjud bo'lmagan maydonlar yamoq yordamida tiklanadi;
  • ob'ektning joriy versiyasidagi manifestning maqsadli versiyasidan farq qiluvchi maydonlar yamoq yordamida yangilanadi.

Aynan shu printsip asosida u yamoqlarni hosil qiladi kubectl apply:

  • manifestning oxirgi qo'llanilgan versiyasi ob'ektning o'zi izohida saqlanadi;
  • maqsad - belgilangan YAML faylidan olingan,
  • joriyi ishlaydigan klasterdan.

Endi biz nazariyani saralab oldik, sizga werfda nima qilganimizni aytib berish vaqti keldi.

O'zgarishlarni werfga qo'llash

Ilgari werf, Helm 2 kabi, ikki tomonlama birlashma yamoqlaridan foydalangan.

Ta'mirlash patchi

Yamoqlarning yangi turiga - 3 tomonlama birlashtirishga o'tish uchun biz birinchi qadam deb atalmishni joriy qildik. yamoqlarni ta'mirlash.

Joylashtirishda standart ikki tomonlama birlashma yamog'idan foydalaniladi, lekin werf qo'shimcha ravishda resursning haqiqiy holatini Git-da yozilgan narsalar bilan sinxronlashtiradigan yamoq ishlab chiqaradi (bunday yamoq yuqorida tavsiflangan bir xil sinxronlangan manba qoidasi yordamida yaratilgan) .

Sinxronizatsiya sodir bo'lsa, o'rnatish oxirida foydalanuvchi tegishli xabar va resursni sinxronlashtirilgan shaklga keltirish uchun qo'llanilishi kerak bo'lgan yamoq bilan OGOHLANTIRISH oladi. Bu yamoq ham maxsus izohda qayd etilgan werf.io/repair-patch. Bu foydalanuvchining qo'llari deb taxmin qilinadi сам bu yamoqni qo'llaydi: werf uni umuman qo'llamaydi.

Ta'mirlash yamoqlarini yaratish vaqtinchalik chora bo'lib, 3 tomonlama birlashtirish printsipiga asoslangan yamoqlarni yaratishni haqiqatda sinab ko'rish imkonini beradi, lekin bu yamoqlarni avtomatik ravishda qo'llamaydi. Ayni paytda ushbu ish rejimi sukut bo'yicha yoqilgan.

3 tomonlama birlashtirish yamog'i faqat yangi versiyalar uchun

1-yil 2019-dekabrdan boshlab werf-ning beta va alfa versiyalari boshlanadi sukut bo'yicha o'zgarishlarni faqat werf orqali chiqarilgan yangi Helm relizlariga qo'llash uchun to'liq 3 tomonlama birlashma yamoqlaridan foydalaning. Mavjud relizlar ikki tomonlama birlashtirish + tuzatish yamoqlari yondashuvidan foydalanishda davom etadi.

Ushbu ish rejimini sozlash orqali aniq yoqish mumkin WERF_THREE_WAY_MERGE_MODE=onlyNewReleases hozir.

nota: funksiya werf-da bir nechta nashrlarda paydo bo'ldi: alfa-kanalda u versiya bilan tayyor bo'ldi v1.0.5-alfa.19, va beta-kanalda - bilan v1.0.4-beta.20.

Barcha relizlar uchun 3 tomonlama birlashtirish yamog'i

15-yil 2019-dekabrdan boshlab werf-ning beta va alfa versiyalari barcha nashrlarga o‘zgartirishlarni qo‘llash uchun sukut bo‘yicha to‘liq 3 tomonlama birlashma yamoqlaridan foydalana boshlaydi.

Ushbu ish rejimini sozlash orqali aniq yoqish mumkin WERF_THREE_WAY_MERGE_MODE=enabled hozir.

Resurslarni avtomatik o'lchash bilan nima qilish kerak?

Kubernetes-da avtomatik o'lchovning 2 turi mavjud: HPA (gorizontal) va VPA (vertikal).

Gorizontal avtomatik ravishda nusxalar sonini, vertikal - resurslar sonini tanlaydi. Resurs manifestida replikalar soni ham, resurslarga bo'lgan talablar ham ko'rsatilgan (Resurs manifestiga qarang). spec.replicas yoki spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и drugie).

Muammo: agar foydalanuvchi diagrammadagi manbani resurslar uchun ma'lum qiymatlarni belgilaydigan tarzda sozlasa yoki ushbu resurs uchun replikalar va avtoskalerlar yoqilgan bo'lsa, u holda har bir joylashtirishda werf ushbu qiymatlarni diagramma manifestida yozilganiga qaytaradi. .

Muammoning ikkita yechimi bor. Boshlash uchun, diagramma manifestida avtomatik o'lchovli qiymatlarni aniq ko'rsatishdan qochish yaxshidir. Agar biron sababga ko'ra ushbu parametr mos bo'lmasa (masalan, dastlabki manba chegaralarini va diagrammadagi nusxalar sonini o'rnatish qulayligi sababli), werf quyidagi izohlarni taklif qiladi:

  • werf.io/set-replicas-only-on-creation=true
  • werf.io/set-resources-only-on-creation=true

Agar bunday izoh mavjud bo'lsa, werf har bir joylashtirishda tegishli qiymatlarni tiklamaydi, lekin ularni faqat resurs dastlab yaratilganda o'rnatadi.

Qo'shimcha ma'lumot olish uchun loyiha hujjatlariga qarang HPA и VPA.

3 tomonlama birlashma yamog'idan foydalanishni taqiqlang

Foydalanuvchi hozirda muhit o'zgaruvchisi yordamida werfda yangi yamoqlardan foydalanishni taqiqlashi mumkin WERF_THREE_WAY_MERGE_MODE=disabled. Biroq, boshlanish 1-yil 2020-martdan boshlab bu taqiq amalda bo‘lmaydi. va faqat 3 tomonlama birlashma yamoqlaridan foydalanish mumkin bo'ladi.

Werfdagi resurslarni qabul qilish

3 tomonlama birlashma yamoqlari bilan o'zgarishlarni qo'llash usulini o'zlashtirish bizga klasterda mavjud resurslarni Helm versiyasiga qabul qilish kabi xususiyatni darhol amalga oshirishga imkon berdi.

Helm 2 da muammo bor: siz ushbu resursni noldan yaratmasdan turib, klasterda allaqachon mavjud bo'lgan diagramma manifestlariga manba qo'sha olmaysiz (qarang. #6031, #3275). Biz werfga mavjud resurslarni chiqarish uchun qabul qilishni o'rgatganmiz. Buni amalga oshirish uchun siz ishlaydigan klasterdan manbaning joriy versiyasiga izoh o'rnatishingiz kerak (masalan, kubectl edit):

"werf.io/allow-adoption-by-release": RELEASE_NAME

Endi resurs diagrammada tasvirlanishi kerak va keyingi safar werf tegishli nomga ega relizni joylashtirganda, mavjud resurs ushbu nashrga qabul qilinadi va uning nazorati ostida qoladi. Bundan tashqari, resursni chiqarish uchun qabul qilish jarayonida werf bir xil 3 tomonlama birlashtirish yamoqlari va sinxronlangan manba qoidasidan foydalangan holda ishlaydigan klasterdan manbaning joriy holatini diagrammada tasvirlangan holatga keltiradi.

nota: sozlash WERF_THREE_WAY_MERGE_MODE resurslarni qabul qilishga ta'sir qilmaydi - qabul qilingan taqdirda, har doim 3 tomonlama birlashma yamog'i qo'llaniladi.

Tafsilotlar - ichida hujjatlar.

Xulosa va kelajak rejalari

Umid qilamanki, ushbu maqoladan keyin 3 tomonlama birlashma yamoqlari nima ekanligi va ular nima uchun ularga kelganligi aniq bo'ldi. Werf loyihasini ishlab chiqishning amaliy nuqtai nazaridan ularning amalga oshirilishi Helm-ga o'xshash joylashtirishni takomillashtirish yo'lidagi yana bir qadam bo'ldi. Endi siz Helm 2-dan foydalanishda tez-tez yuzaga keladigan konfiguratsiya sinxronizatsiyasi bilan bog'liq muammolarni unutishingiz mumkin. Shu bilan birga, Helm versiyasiga allaqachon yuklab olingan Kubernetes resurslarini qabul qilishning yangi foydali xususiyati qo'shildi.

Helm-ga o'xshash joylashtirishda hali ham ba'zi muammolar va qiyinchiliklar mavjud, masalan, Go shablonlaridan foydalanish, biz ularni hal qilishda davom etamiz.

Resurslarni yangilash usullari va qabul qilish haqida ma'lumotni quyidagi manzilda ham topishingiz mumkin ushbu hujjat sahifasi.

Rulda 3

Maxsus e'tiborga loyiq ozod qilingan Yaqinda Helm-ning yangi asosiy versiyasi - v3 - u ham 3 tomonlama birlashma yamoqlaridan foydalanadi va Tillerdan xalos bo'ladi. Helmning yangi versiyasi talab qiladi migratsiya mavjud o'rnatishlarni yangi versiya saqlash formatiga aylantirish uchun.

Werf, o'z navbatida, hozirda Tillerdan foydalanishdan xalos bo'ldi, 3 tomonlama birlashtirishga o'tdi va qo'shdi. ko'proq, Mavjud Helm 2 o'rnatishlari bilan mos bo'lgan holda (migratsiya skriptlarini bajarish shart emas). Shuning uchun, werf Helm 3 ga o'tmaguncha, werf foydalanuvchilari Helm 3 ning Helm 2 ga nisbatan asosiy afzalliklarini yo'qotmaydi (werf ham ularga ega).

Biroq, werf-ning Helm 3 kod bazasiga o'tishi muqarrar va yaqin kelajakda sodir bo'ladi. Ehtimol, bu werf 1.1 yoki werf 1.2 bo'ladi (hozirda werfning asosiy versiyasi 1.0; werf versiyasini yaratish qurilmasi haqida qo'shimcha ma'lumot olish uchun qarang. shu yerda). Bu vaqt ichida Helm 3 barqarorlashishi uchun vaqt topadi.

PS

Shuningdek, bizning blogimizda o'qing:

Manba: www.habr.com

a Izoh qo'shish