Nəhayət, çox gözlədiyimiz bir şey baş verdi: , açıq mənbə kodlu tətbiq qurma və Kubernetes-də çatdırma üçün proqramımız indi 3-way-merge-patch-larla dəyişiklərin tətbiqini dəstəkləyir! Bununla yanaşı, mövcud K8s resurslarını Helm buraxılışlarına qəbul etmək imkanı da var, bu resursların yenidən yaradılması olmadan.

Qısa desək, WERF_THREE_WAY_MERGE=enabled qoyuruq — " kubectl applykimi", Helm 2-yə uyğun mövcud quraşdırmalara uyğun bir "deploy" əldə edirik, hətta bir az daha çox.
Amma gəlin nəzəriyyədən başlayaq: 3-way-merge-patch-lar nədir, insanlar onların yaradılmasına necə gəliblər və niyə bunlar Kubernetes-in CI/CD proseslərində vacibdir? Sonra da jam-lar nədir, adətən hansı rejimlərin istifadə edildiyini və bunun necə idarə olunacağını nəzərdən keçirəcəyik.
3-way-merge-patch nədir?
Beləliklə, YAML manifestlərində təsvir olunan resursları Kubernetes-də yaymaq məsələsinə başlayırıq.
Kubernetes API ilə işləmək üçün əsas əməliyyatlar: create, patch, replace və delete. Onların köməyi ilə klasterdə rahat davamlı resurs yayımını necə qurmaq olar?
İmperativ kubectl əmrələri
Kubernetes-də obyektləri idarə etməyin birinci yanaşması — bu obyektlərin yaradılması, dəyişdirilməsi və silinməsi üçün imperativ kubectl əmrələrindən istifadə etməkdir. Başqa dildə desək:
- əmri ilə
kubectl runDeployment və ya Job başlada bilər:kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE - əmri ilə
kubectl scalereplika sayını dəyişdirir:kubectl scale --replicas=3 deployment/mysql - və s.
Bu yanaşma ilk baxışda rahat görünə bilər. Ancaq problemləri vardır:
- Onu avtomatlaşdırmaq çətindir.
- Necə konfiqurasiyanı Git-də əks etdirmək? Klasterdə baş verən dəyişikləri necə nəzərdən keçirmək olar?
- Konfiqurasiyanın təkrarlanmasını yenidən başlatmalarda necə təmin edək?
- …
Bu yanaşmanın kodla birləşdirmək və infrastruktur kodu (IaC; və ya daha müasir bir variant kimi, Kubernetes ekosistemində populyarlıq qazanan) ilə pis əlaqələrlə olduğu açıqdır. Buna görə də, bu əmrların kubectl-də daha da inkişafı olmadi. Create, get, replace və delete əməliyyatları
İlkin
yaratmada hər şey sadədir: manifesti kube API-ya göndərərək resursu yaradırıq. Manifestin YAML tərtibi Git-də saxlanıla bilər, yaradılmaq üçün isə kubectl create -f manifest.yaml Böyük disk obrazını yaradan bu əmr 40 GB ölçüsündə test şəkilini yaradacaq. İndi bu, hər hansı bir virtual maşınla qoşulmağa uyğundur. silinməsi də sadədir: eyni.
olarq manifest.yaml Git-dən götürərək kubectl delete -f manifest.yaml replace resursun konfiqurasiyasını tamamilə yeni ilə əvəz etməyə imkan verir, resursu yenidən yaratmadan. Bu, resursda dəyişiklik etmədən əvvəl cari versiyanı soruşmağın, onu dəyişdirərək və sonra yeniləmək üçün.
Operasyon bizim üçün məntiqli olduğunu göstərir. kube apiserver-də getoptimistic locking bizim üçün məntiqli olduğunu göstərir.var və, əgər əmrdən sonra obyekt dəyişərsə, əməliyyat Konfiqurasiyanı Git-də saxlamaq və replace ilə yeniləmək üçün əməliyyatı yerinə yetirmək lazımdır. get объект поменялся, то операция bizim üçün məntiqli olduğunu göstərir. не пройдет.
Чтобы хранить конфигурацию в Git и обновлять с помощью replace, надо делать операцию get, Git-dan aldığımızla konfiqurasiyanı birləşdirir və icra edirik bizim üçün məntiqli olduğunu göstərir.. Normalda, kubectl yalnız kubectl replace -f manifest.yaml, burada kubectl delete -f manifest.yaml — artıq tam hazırlanmış (bizim halımızda — birləşdirilmiş) manifestdir, onu quraşdırmaq lazımdır. Beləliklə, istifadəçi manifestləri birləşdirməlidir ki, bu da asan iş deyil...
Həmçinin qeyd etmək lazımdır ki, kubectl delete -f manifest.yaml Git-də saxlanmasına baxmayaraq, biz əvvəlcədən bilmirik, obyekt yaratmaq lazımdır, yoxsa onu yeniləmək — bunu istifadəçi proqramı etməlidir.
Sonuç olarak: davamlı yayımlamaq yalnız create, replace və delete ilə mümkündürmü, infrastruktura konfiqurasiyasını Git-də kodla birlikdə saxlayaraq, rahat CI/CD təmin edərək?
Əslində, mümkündür... Bunun üçün manifestlərin birləşdirilməsi və bir növ abşlama reallaşdırılmalıdır ki, bu da:
- klasterdə obyekti yoxlayır,
- resursun ilkin yaradılmasını həyata keçirir,
- onu yeniləyir və ya silir.
Yeniləmə zamanı nəzərə alınmalıdır ki, resurs sonuncu dəfə dönənə qədər dəyişmiş ola bilər get və optimistik kilidləmə halını avtomatik olaraq emal edir — yeniləməyi təkrarlamağa çalışır.
Amma niyə təkər ixtira etməliyik ki, kube-apiserver resursları yeniləməyin başqa bir yolunu təklif edir: patch, bu da istifadəçinin bəzi problemlərini aradan qaldırır?
Patch
Budur, biz patch-lərə gəldik.
Patch-lər — Kubernetes-də mövcud obyektlərə dəyişikliklərin tətbiqinin əsas üsuludur. Bu əməliyyat patch belə işləyir ki:
- kube-apiserver istifadəçidən JSON formatında patch göndərməsini tələb edir və obyekti göstərməsini,
- apiserver isə cari obyekt vəziyyətini başa düşərək onu tələb olunan formada tənzimləyir.
Bu halda optimistik kilidləmə lazım deyil. Bu əməliyyat replace ilə müqayisədə daha deklarativdir, baxmayaraq ki, əvvəlcə əksinə görünə bilər.
Beləliklə:
- patch əməliyyatı vasitəsilə
Böyük disk obrazını yaradan bu əmr 40 GB ölçüsündə test şəkilini yaradacaq. İndi bu, hər hansı bir virtual maşınla qoşulmağa uyğundur.biz Git-dən manifest üzrə obyekt yaradırıq, - ilə
delete— obyekti silirik, əgər artıq lazım deyilsə, - ilə
patch— obyekti dəyişdiririk, onu Git-də təsvir olunan formada gətiririk.
Amma bunu etmək üçün düzgün patch yaratmaq lazımdır.!
Helm 2-də patch-lərin işləmə prinsipi: 2-yolda birləşdirmə
Helm ilk buraxılışı quraşdırarkən Böyük disk obrazını yaradan bu əmr 40 GB ölçüsündə test şəkilini yaradacaq. İndi bu, hər hansı bir virtual maşınla qoşulmağa uyğundur. çart resursları üçün əməliyyat edir.
Buraxılışı yenilədikdə, Helm hər bir resurs üçün:
- keçmiş çartdan resurs versiyası ilə cari çart versiyası arasında patch hesablayır
- və bu patch-i tətbiq edir.
Biz bu patch-i 2-yolda birləşmə patch-i, çünki onun yaradılmasında 2 manifest iştirak edir:
- keçmiş buraxılışdan resurs manifesti,
- cari resursun manifesti.
Silinmə zamanı delete kube-apiserver-in əməliyyatı, keçmiş buraxılışda elan edilmiş, lakin cari buraxılışda elan edilməmiş resurslar üçün çağırılır.
2 yol birləşmə patch yanaşmasının bir problemi var: bu, klasterdə real resurs vəziyyəti ilə Git-dəki manifest arasında qarışıqlığa səbəb olur..
Problemin təsviri nümunəsi
- Git-də, çartda bir manifest var, onun sahəsi
imageDeployment-da dəyəriubuntu:18.04. - İstifadəçi vasitəsilə
kubectl editbu sahənin dəyərini dəyişdirdiubuntu:19.04. - Helm chart-ın təkrar yerləşdirməsində patch yaratmır, çünki
imagekeçmiş versiyasında və cari chart-da eynidir. - Təkrar yerləşdirdikdən sonra
imageqalıqubuntu:19.04, halbuki chart-da yazılıb ki,ubuntu:18.04.
Biz asimmetriya yaşadıq və deklarativliyi itirdik.
Senkronizasiya olunmuş resurs nədir?
Ümumiyyətlə, resursun manifesti ilə işləyən klasterdəki manifest arasında tam uyğunluq əldə etmək mümkün deyil. Çünki real manifestdə müvafiq annotasiyalar/etiketlər, əlavə konteynerlər və digər dinamik olaraq idarəçilər tərəfindən əlavə olunan və silinən məlumatlar ola bilər. Bu məlumatları biz Git-də saxlamaq istəmirik və istəmirik. Ancaq, yerləşdirdikdə, Git-də açıq şəkildə göstərdiyimiz sahələrin müvafiq dəyərləri almasını istəyirik.
Beləliklə, senkronizasiya olunmuş resursunümumi qaydasıdır: resurs yerləşdirilən zaman yalnız Git manifestində açıq şəkildə göstərilən sahələri dəyişmək və ya silmək olar (və ya əvvəlki versiyasında göstərilmiş diskin sahələri).
3-yolda birləşdirmə patch
Əsas fikir : Git-in tətbiq edilən ən son versiyası ilə Git-dəki hədəf versiyası arasında patch yaradılır, işləyən klasterdəki cari versiya da nəzərə alınır. Nəticə patch senkronizasiya olunmuş resursun qaydasına uyğun olmalıdır:
- hədəf versiyaya əlavə edilmiş yeni sahələr patch vasitası ilə əlavə olunur;
- son tətbiq olunan versiyadakı mövcud sahələr və hədəfdə olmayanlar patch vasitası ilə sıfırlanır;
- mövcud versiyadakı hədəf versiyadan fərqlənən sahələr patch vasitəsilə yenilənir.
Patch-lar məhz bu prinsipə görə yaradılır kubectl apply:
- tətbiq olunan ən son versiya obyektin annotasiyasında saxlanılır,
- hədəf - göstərilmiş YAML faylından götürülür,
- mövcud - işləyən klasterdən.
İndi, nəzəriyyə ilə tanış olduqdan sonra, werf-də nə etdiyimizi izah etməyə vaxtıdır.
werf-də dəyişikliklərin tətbiqi
Əvvəllər werf, Helm 2 kimi, 2-yolda birləşdirmə patch-lərindən istifadə edirdi.
Repair patch
Yeni patch tipinə - 3-yolda birləşdirməyə keçmək üçün ilk addım, belə adlandırılan repair-patch-ləri daxil etdik.
Yerləşdirmə zamanı standart 2-yolda birləşdirmə patch-ı istifadə edilir, lakin werf əlavə olaraq resursun real vəziyyətini Git-də yazılmışa uyğunlaşdıran bir patch yaradır (bu patch evvelki sekronizasiya qaydasını tətbiq edərək yaradılır, yuxarıda izah edilib).
Asimmetriya baş verərsə, yerləşdirmənin sonunda istifadəçi müvafiq mesajla WARNING alır və resursu senkronizasiya olunmuş vəziyyətə gətirmək üçün tətbiq edilməsi gərəkən patch təqdim olunur. Bu patch eyni zamanda xüsusi bir annotasiyaya yazılır werf.io/repair-patch. İstifadəçinin özü öz bu patch tətbiq edin: werf bunu tətbiq etməkdə əsasən maraqlı olmayacaq.
Repair patch-lərin yaradılması müvəqqəti bir tədbirdir ki, bu da 3-way-merge prinsipinə uyğun olaraq patch-lərin yaradılmasını praktiki olaraq yoxlamağa imkan verir; lakin avtomatik olaraq bu patch-ləri tətbiq etmir. Hazırda bu iş rejimi standart olaraq aktivdir.
3-way-merge patch yalnız yeni buraxılışlar üçün
1 dekabr 2019-cu ildən etibarən beta və alpha versiyaları werf başlayır başlanğıc olaraq tam 3-way-merge-patch-lərdən istifadə etməyə yalnız yeni Helm buraxılışlarına dəyişiklikləri tətbiq etmək üçün, werf vasitəsilə yayımlanır. Artıq mövcud buraxılışlar 2-way-merge + repair patch yanaşmasını istifadə etməyə davam edəcək.
Bu iş rejimini açıq şəkildə aktivləşdirmək mümkündür WERF_THREE_WAY_MERGE_MODE=onlyNewReleases indidən.
Qeyd: bu xüsusiyyət werf-də bir neçə versiyadan etibarən genəldilmişdir: alpha kanalında version , beta kanalında - ilə .
3-way-merge patch bütün buraxılışlar üçün
15 dekabr 2019-cu ildən etibarən beta və alpha versiyaları werf standart olaraq bütün buraxılışlar üçün tam 3-way-merge-patch-lərdən istifadə etməyə başlayır.
Bu iş rejimini açıq şəkildə aktivləşdirmək mümkündür WERF_THREE_WAY_MERGE_MODE=enabled indidən.
Resursların avtomatik miqyası necə olmaq lazımdır?
Kubernetes-də 2 növ avtomatik miqyaslama var: HPA (üfüqi) və VPA (şaquli).
Üfüqi avtomatik olaraq replikaların sayını seçir, şaquli isə resursların miqdarını. Həm replikaların, həm də resurslar üçün tələblər resurs manifestində göstərilir (baxın. spec.replicas və spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory və ).
Problem: əgər istifadəçi resursu çartda konfiqurasiya edərsə ki, orada resurslar və replikalar üçün müəyyən dəyərlər qeyd olunubsa və bu resurs üçün avtomatik miqyaslayıcılar aktivdirsə, werf hər dəfə yerləşdirmədə bu dəyərləri çart manifestində qeyd olunanlara sıfırlayacaq.
Problemin iki həlli var. İlk növbədə, çart manifestində avtomatik miqyasa bilən dəyərlərin açıq göstərilməsindən imtina etmək daha yaxşıdır. Əgər bu variant hansısa səbəblərdən uyğun deyilsə (məsələn, çartda ilkin resurs limitlərini və replikaların sayını təyin etmək rahat olduqda), o zaman werf aşağıdakı annotasiyaları təklif edir:
-
werf.io/set-replicas-only-on-creation=true -
werf.io/set-resources-only-on-creation=true
Belə bir annotasiya varsa werf hər dəfə yerləşdirmədə müvafiq dəyərləri sıfırlamayacaq, yalnız resursun ilkin yaradılması zamanı onları təyin edəcək.
Daha ətraflı - layihənin dokumentasiyasında baxın və .
3-way-merge patch istifadəsini qadağan etmək
İstifadəçi hələ də werf-də yeni patchlərin istifadəsini ətraf mühit dəyişəni vasitəsilə qadağan edə bilər WERF_THREE_WAY_MERGE_MODE=disabled. Lakin, 1 mart 2020-ci ildən etibarən bu qadağa qüvvədən düşəcək və yalnız 3-way-merge-patch-lərin istifadəsi mümkün olacaq. werf-də resursların qəbul edilməsi
3-way-merge-patch-lərlə dəyişikliklərin tətbiqində yeni metodun əldə edilməsi, bizə klasterdə mövcud resursların Helm buraxılışına adoption edilə bilən belə bir xüsusiyyəti dərhal həyata keçirməyə imkan verdi.
3-way-merge-patch-lərlə dəyişikliklərin tətbiqi metodunu mənimsədikdən sonra, bizə klasterdə mövcud resursların Helm buraxılışına adoption etməyə imkan verən belə bir xüsusiyyəti dərhal həyata keçirməyə imkan verdi.
Helm 2-də bir problem var: artıq klasterdə olan resursu manifestlərə əlavə etmək mümkün deyil, bu resursu sıfırdan yenidən yaratmadan (bax. , ). Biz werfi mövcud resursları buraxılışa qəbul etməyə öyrətdik. Bunun üçün işləmiş klasterdəki resursun cari versiyasına annotasiya əlavə etmək lazımdır (məsələn, kubectl edit):
"werf.io/allow-adoption-by-release": RELEASE_NAMEİndi resursu çartda təsvir etmək lazımdır və werf buraxılışı müvafiq adla növbəti yerləşdirmədə mövcud resursu bu buraxılışa qəbul edəcək və onun idarəsindən çıxmayacaq. Üstəlik, resurs buraxılışa qəbul edilərkən, werf işləmiş klasterdəki resursun cari vəziyyətini çartda təsvir olunan vəziyyətə gətirəcək, eyni 3-way-merge-patch-lərdən və sinxronizasiya edilmiş resurs qaydasından istifadə edəcək.
Qeyd: konfiqurasiya WERF_THREE_WAY_MERGE_MODE resursların qəbuluna təsir etmir — qəbul halında həmişə 3-way-merge-patch istifadə olunur.
Təfərrüatlar — .
Nəticələr və gələcək planlar
Ümid edirəm ki, bu yazıdan sonra 3-way-merge-patch-lərin nə olduğu və niyə bunlara gəldiyimiz daha aydın oldu. Praktik baxımdan werf layihəsinin inkişafında bunların tətbiqi, Helm-ə bənzər yerləşdirilmənin yaxşılaşdırılması yolunda daha bir addım oldu. İndi Helm 2 istifadə edərkən tez-tez baş verən konfiqurasiya sinxronizasiyası problemlərini unutmaq olar. Eyni zamanda, artıq yüklənmiş Kubernetes resurslarının Helm buraxılışlarına qəbul edilməsi ilə bağlı yeni faydalı bir xüsusiyyət əlavə edildi.
Helm-ə bənzər yerləşdirmədə hələ də bəzi problemlər və çətinliklər qalır, məsələn, Go şablonlarının istifadəsi və biz bu məsələləri həll etməyə davam edəcəyik.
Resursların yeniləmə metodları və qəbul prosesi haqqında məlumatı da .
Helm 3
Xüsusi qeyd edilməyə layiqdir ki, yeni əsas versiya Helm — v3, — 3-way-merge-patch-ləri istifadə edir və Tilleri aradan qaldırır. Yeni Helm versiyası artıq mövcud quraşdırmaları yenilik vəzifəsiylə yeni buraxılış formatına çevirmək üçün tələb edir.
Werf, öz tərəfindən, hal-hazırda Tilleri istifadə etməmişdir, 3-way-merge sisteminə keçdi və , eyni zamanda, əvvəllər yaradılmış Helm 2 quraşdırmaları ilə uyğun qaldı (miqrasiya skriptləri yerinə yetirmək lazım deyil). Buna görə, werf hələ Helm 3-ə keçirilmədiyi müddətcə, werf istifadəçiləri Helm 3-ün Helm 2-yə nisbətən əsas üstünlüklərini itirmirlər (werf-də bunlar da mövcuddur).
Buna baxmayaraq, werf-in Helm 3 kod bazasına keçidi qaçılmazdır və yaxın gələcəkdə baş verməlidir. Təxminən bu, werf 1.1 və ya werf 1.2 olacaq (hazırda, werf-in baş versiyası 1.0-dır; werf versiya strukturu haqqında daha ətraflı baxın.) ). Bu dövr ərzində Helm 3 stabil hala gələcək.
P.S.
Blogumuzda oxuyun:
- werf-də yeniliklərə dair qeydlər dövrü:
- «»;
- «»;
- «».
- «»;
- «»;
- «».
Mənbə: habr.com
