Падтрымка monorepo і multirepo у werf і пры чым тут Docker Registry
Тэма монорепозитория абмяркоўвалася ўжо не раз і, як правіла, выклікае вельмі актыўныя спрэчкі. Ствараючы werf як Open Source-інструмент, закліканы палепшыць працэсы зборкі кода прыкладанняў з Git у Docker-выявы (і іх наступнай дастаўкі ў Kubernetes), мы мала разважаем на тэму таго, які выбар лепш. Для нас першасна забяспечыць усё неабходнае для прыхільнікаў розных меркаванняў (калі гэта не супярэчыць разумнаму сэнсу, вядома).
Якая з'явілася нядаўна падтрымка mono-repo у werf добры таму прыклад. Але для пачатку давайце разбяромся, як гэтая падтрымка наогул злучана з выкарыстаннем werf і пры чым тут Docker Registry…
Праблематыка
Уявім такую сітуацыю. У кампаніі ёсць мноства каманд распрацоўшчыкаў, якія займаюцца незалежнымі праектамі. Большасць прыкладанняў функцыянуюць у Kubernetes, а адпаведна - кантэйнезуюцца. Для захоўвання кантэйнераў, выяў, неабходны рэестр (registry). У якасці такога рэестра ў кампаніі выкарыстоўваецца Docker Hub з адзіным акаўнтам. COMPANY. Па аналогіі з большасцю сістэм захоўвання зыходнага кода, Docker Hub не дазваляе ствараць укладзеную іерархію рэпазітараў, такую як COMPANY/PROJECT/IMAGE. У такім выпадку… як жа з гэтым абмежаваннем захоўваць у рэестры неманалітныя прыкладанні, не ствараючы асобны акаўнт пад кожны праект?
Магчыма, апісаная сітуацыя камусьці не па чутках знаёмая, але давайце разгледзім пытанне арганізацыі захоўвання прыкладанняў увогуле, г.зн. без прывязкі да вышэйапісанага прыкладу і Docker Hub.
Шляхі рашэння
Калі дадатак маналітна, пастаўляецца ў адным вобразе, то пытанняў не ўзнікае і мы проста захоўваем выявы ў рэестр кантэйнераў праекта.
Калі дадатак прадстаўлена ў выглядзе некалькіх кампанентаў, мікрасэрвісаў, то патрабуецца абраць пэўны падыход. На прыкладзе тыпавога web-прыкладанні, які складаецца з двух выяў: frontend и backend - магчымыя варыянты такія:
Захоўваць выявы ў асобных укладзеных рэпазітарах:
Захоўваць усё ў адным рэпазітары, а імя выявы ўлічваць у тэгу, да прыкладу, наступным чынам:
NB: Наогул, ёсць яшчэ варыянт з захаваннем у розных рэпазітарах, PROJECT-frontend и PROJECT-backend, але яго мы не будзем разглядаць з-за складанасці падтрымкі, арганізацыі і размеркаванні правоў паміж карыстальнікамі.
Падтрымка ў werf
Першапачаткова werf абмежаваўся ўкладзенымі рэпазітарамі - балазе, большасць рэестраў падтрымліваюць такую магчымасць. Пачынаючы з версіі v1.0.4-alpha.3, дададзена праца з рэестрамі, у якіх не падтрымліваецца ўкладзенасць, і Docker Hub – у іх ліку. З гэтага моманту ў карыстальніка з'явіўся выбар, як захоўваць выявы прыкладання.
Рэалізацыя даступна ў рамках опцыі --images-repo-mode=multirepo|monorepo (па змаўчанні multirepo, г.зн. захоўванне ва ўкладзеных рэпазітарах). Яна вызначае шаблоны, па якіх выявы захоўваюцца ў рэестры. Досыць абраць патрэбны рэжым пры выкарыстанні асноўных каманд, а ўсё астатняе застанецца нязменным.
Паколькі большасць опцый werf можна задаваць зменнымі асяроддзі, у CI/CD-сістэмах рэжым захоўвання, як правіла, лёгка задаць глабальна для ўсяго праекта. Напрыклад, у выпадку з GitLab дастаткова дадаць зменную асяроддзі ў наладах праекта: Settings -> CI / CD -> Variables: WERF_IMAGES_REPO_MODE: multirepo|monorepo.
Калі казаць аб публікацыі выяў і выкаце прыкладанняў (аб гэтых працэсах можна падрабязна прачытаць у адпаведных артыкулах дакументацыі: Publish process и Deploy process), то рэжым выключна вызначае шаблон, па якім можна працаваць з выявай.
Д'ябал у дэталях
Адрозненне і асноўная складанасць пры даданні новага спосабу захоўвання - падчас ачысткі registry (магчымасці чысткі, якія падтрымліваюцца ў werf, гл. Працэс чысткі).
Пры ачыстцы werf улічвае выкарыстоўваныя ў кластарах Kubernetes выявы, а таксама палітыкі, якія наладжваюцца карыстачом. У аснове палітык ляжыць падзел тэгаў на стратэгіі. Стратэгіі, якія падтрымліваюцца ў сапраўдны момант:
3 стратэгіі, звязаныя Git-прымітывамі, такімі як тэг, галінка і коміт;
1 стратэгія для адвольных карыстацкіх тэгаў.
Інфармацыю аб стратэгіі тэга мы захоўваем пры публікацыі выявы ў лэйблах канчатковай выявы. Само значэнне - так званы метатэг - Неабходны для прымянення часткі палітык. Напрыклад, пры выдаленні галінкі ці тэга з Git-рэпазітара лагічна выдаляць і злучаныя. невыкарыстоўваныя выявы з рэестра, што і пакрываецца часткай нашых палітык.
Пры захаванні ў адным рэпазітары (monorepo), у тэгу выявы, акрамя метатэга таксама можа захоўвацца імя выявы: PROJECT:frontend-META-TAG. Для іх падзелу мы не сталі ўводзіць нейкі спецыфічны падзельнік, а проста дадалі неабходнае значэнне ў лэйбл канчатковай выявы пры публікацыі.
NB: Калі цікава паглядзець на ўсё апісанае ў зыходным кодзе werf, то адпраўной кропкай можа служыць PR 1684.
У гэтым артыкуле мы не будзем надаваць больш увагі праблематыцы і абгрунтаванню нашага падыходу: пра стратэгію тэгавання, захоўвання дадзеных у лэйблах і працэс публікацыі ў цэлым — пра ўсё гэта падрабязна расказана ў нядаўнім дакладзе Дзмітрыя Сталярова: «werf – наш інструмент для CI/CD у Kubernetes.
Рэзюмуючы
Адсутнасць падтрымкі рэестраў без укладзенасці не з'яўлялася блакавальным фактарам для нас ці вядомых нам карыстачоў werf — бо заўсёды можна падняць асобны рэестр выяў (ці перайсці на ўмоўны Container Registry у Google Cloud)… Аднак зняцце такога абмежавання выглядала лагічным для таго, каб прылада была зручная больш шырокаму DevOps-супольнасці. Рэалізуючы яго, мы сутыкнуліся з галоўнай складанасцю ў перапрацоўцы механізма ачысткі рэестра кантэйнераў. Цяпер, калі ўсё гатова, прыемна ўсведамляць, што камусьці стала лягчэй, а ў нас (як галоўных распрацоўшчыкаў праекта) прыкметных складанасцяў у далейшай падтрымцы гэтай фічы не прадбачыцца.
Заставайцеся з намі і зусім хутка мы раскажам пра іншыя новаўвядзенні ў werf!