
Čím rýchlejšie je vyvíjanie, tým rýchlejšie sa rozvíja technologická spoločnosť.
Bohužiaľ, moderné aplikácie pracujú proti nám – naše systémy musia byť aktualizované v reálnom čase a pritom nikomu neprekážať, ani nespôsobovať výpadky a prestoje. Nasadenie v takýchto systémoch sa stáva zložitou úlohou a vyžaduje zložitú kontinuitu dodávok aj v malých tímach.
Tieto pipeline majú zvyčajne úzke využitie, pracujú pomaly a nie sú spoľahlivé. Vývojári ich musia najprv vytvoriť manuálne a potom nimi spravovať, pričom spoločnosti často najímajú celé tímy DevOps na túto úlohu.
Na rýchlosti týchto pipeline závisí rýchlosť vývoja. U najlepších tímov trvá nasadenie 5–10 minút, ale zvyčajne to trvá oveľa dlhšie a na jedno nasadenie je potrebných niekoľko hodín.
Na to v Dark je potrebných 50 ms. Päťdesiat. Milisekúnd.. Dark je , vytvorené špeciálne pre kontinuálnu dodávku, a všetky aspekty Dark, vrátane samotného jazyka, sú postavené s ohľadom na bezpečné okamžité nasadenie.
Prečo sú pipeline kontinuálnej dodávky také pomalé?
Predpokladajme, že máme webovú aplikáciu v Pythone a už sme vytvorili skvelý a moderný pipeline kontinuálnej dodávky. Pre vývojára, ktorý sa každý deň zaoberá týmto projektom, bude nasadenie jednej drobnej zmeny vyzerať zhruba takto:
Upravenie zmien
- Vytvorenie novej vetvy v gite
- Upravenie zmien pod prepínačom funkcie
- Modulové testovanie na overenie zmien s prepínačom funkcie a bez neho
Pull request
- Commit zmien
- Odoslanie zmien do vzdialeného repozitára na github
- Pull request
- CI sa automaticky vykonáva na pozadí
- Revize kódu
- Ešte pár revízií, ak je to potrebné
- Spojenie zmien s hlavným gitom.
CI sa vykonáva na hlavnom vetve
- Inštalácia frontendových závislostí cez npm
- Stavba a optimalizácia HTML+CSS+JS zdrojov
- Spustenie modulových a funkčných testov na frontende
- Inštalácia Python závislostí z PyPI
- Spustenie modulových a funkčných testov na backend-e
- Testovanie integrácie na oboch koncoch
- Odoslanie frontendových zdrojov do CDN
- Stavba kontajnera pre Python program
- Odoslanie kontajnera do registra
- Aktualizácia manifestu Kubernetes
Nahradenie starého kódu novým
- Kubernetes spúšťa niekoľko exemplárov nového kontajnera
- Kubernetes čaká, kým sa exempláre stanú funkčnými
- Kubernetes pridáva exempláre do HTTP vyvažovača zaťaženia
- Kubernetes čaká, kým sa staré exempláre prestanú používať
- Kubernetes zastavuje staré exempláre
- Kubernetes opakuje tieto operácie, kým nové exempláre nenahradia všetky staré
Aktivácia nového prepínača funkcií
- Nový kód sa aktivuje iba pre seba, aby sa zabezpečilo, že všetko je v poriadku
- Nový kód sa aktivuje pre 10 % používateľov, sledujú sa prevádzkové a obchodné metriky
- Nový kód sa aktivuje pre 50 % používateľov, sledujú sa prevádzkové a obchodné metriky
- Nový kód sa aktivuje pre 100 % používateľov, sledujú sa prevádzkové a obchodné metriky
- Nakoniec opakujete celý postup, aby ste odstránili starý kód a prepínač
Proces závisí od nástrojov, jazyka a používanej architektúry orientovanej na služby, ale v skratke vyzerá takto. Nespomenul som nasadenia s migráciou databáz, pretože to si vyžaduje dôkladné plánovanie, ale nižšie vysvetlím, ako s tým Dark popracoval.
Je tu veľa komponentov a mnohé z nich môžu ľahko spôsobovať spomalenie, zlyhanie, vyvolávať dočasnú konkurenciu alebo zrútiť pracovný systém.
A keďže tieto pipeliny sú takmer vždy vytvorené na špecifické prípady, ťažko sa na ne spoliahnuť. Mnohí majú dni, keď nie je možné nasadiť kód, pretože sú v Dockerfile problémy, v jednom z desiatok služieb došlo k zlyhaniu, alebo potrebný odborník je na dovolenke.
Horšie je, že mnohé z týchto krokov vôbec nerobia nič užitočné. Potrebovali sme ich v minulosti, keď sme nasadzovali kód priamo pre používateľov, ale teraz máme prepínače pre nový kód, a tieto procesy sa rozdelili. Výsledkom je, že krok, v ktorom sa nasadzuje kód (starý je nahradený novým), sa teraz stal jednoducho zbytočným rizikom.
Samozrejme, že je to veľmi premyslená pipeline. Tím, ktorý ju vytvoril, nešetril časom a peniazmi na rýchle nasadenie. Obvykle sú nasadzovacie pipeliny oveľa pomalšie a menej spoľahlivé.
Implementácia kontinuálnej dodávky v Dark
Nepretržitá dodávka je pre Dark tak dôležitá, že sme sa od začiatku snažili dosiahnuť čas menej než sekundu. Prešli sme všetky kroky pipeline, aby sme odstránili všetko zbytočné, a to, čo zostalo, sme doladili. Tu je, ako sme odstraňovali kroky.
Jessie Frazelle () vytvorila nové slovo deployless (nevyžaduje nasadenie) na konferencii Future of Software Development v Reykjavíku
Okamžite sme sa rozhodli, že Dark bude založený na koncepcii „deployless“ (ďakujem za neologizmus). Deployless znamená, že akýkoľvek kód sa okamžite nasadí a je pripravený na použitie v produkcii. Samozrejme, nezmeškáme chybový alebo neúplný kód (principy bezpečnosti opíšem nižšie).
Na demonštrácii Dark sa nás často pýtali, ako sme sa podarilo tak urýchliť nasadenie. Zvláštny otázka. Ľudia si asi myslia, že sme vymysleli nejakú supertechnológiu, ktorá porovnáva kód, kompiluje ho, balí do kontajnera, spúšťa virtuálnu mašinu, na studeno spúšťa kontajner a to všetko za 50 ms. Určite to nie je možné. Ale vytvorili sme špeciálny nástroj na nasadenie, ktorý to všetko ani nepotrebuje.
Dark spúšťa interpretátory v oblaku. Predpokladajme, že píšete kód vo funkcii alebo spracovateľovi HTTP alebo udalostí. Posielame diff do abstraktného syntaktického stromu (implementácia kódu, ktorú vnútorne využíva náš editor a servery) na naše servery a potom spúšťame tento kód, keď prichádzajú požiadavky. Takže nasadenie vyzerá jednoducho ako skromný záznam do databázy — okamžité a elementárne. Nasadenie prebieha tak rýchlo, pretože zahŕňa najminimum.
V budúcnosti plánujeme urobiť z Dark kompilátor infraštruktúry, ktorý vytvorí a spustí ideálnu infraštruktúru pre vysoký výkon a spoľahlivosť aplikácií. Okamžité nasadenie sa samozrejme nikam nestratí.
Bezpečné nasadenie
Štruktúrovaný editor
Kód v Dark sa píše v editore Dark. Štruktúrovaný editor neumožňuje syntaktické chyby. V podstate, v Dark ani nemáme analyzátor. Kým píšete text, priamo pracujeme s abstraktným syntaktickým stromom (AST), ako , , , a .
Každý nedokončený kód v Dark má prípustnú sémantiku vykonávania, zhruba ako Napríklad, ak změníte volanie funkcie, uchovávame starú funkciu, kým nová nebudú vhodná.
Každý program v Dark má svoj význam, preto neúplný kód nebráni dokončenému fungovať.
Režimy úprav
Kód v Dark píšete v dvoch prípadoch. Po prvé: píšete nový kód a ste jediným používateľom. Napríklad, nachádza sa to v REPL a iní používateľia k nemu nikdy nemajú prístup, alebo je to nová HTTP trasa, na ktorú sa nikde neodkazujete. Tu môžete pracovať bez akýchkoľvek opatrení a teraz presne takto pracujete v prostredí vývoja.
Druhá situácia: kód sa už používa. Ak pre kód prechádza prevádzka (funkcie, spracovatelia udalostí, databázy atď.), treba byť opatrný. Na to blokujeme celý používaný kód a vyžadujeme použitie štruktúrovanejších nástrojov na jeho úpravu. O štruktúrovaných nástrojoch sa rozprávam nižšie: prepínače funkcií pre spracovateľov HTTP a udalostí, výkonne migračné platformy pre databázy a nový spôsob správy verzií pre funkcie a typy.
Prepínače funkcií
Jeden zo spôsobov v Dark je odstrániť niekoľko problémov jedným riešením. Prepínače funkcií vykonávajú mnoho rôznych úloh: nahrádzajú lokálne prostredie vývoja, git vetvy, nasadzovanie kódu a samozrejme tradičné pomalé a kontrolované vydávanie nového kódu.
Vytvorenie a nasadenie prepínača funkcie sa vykonáva v našom editore v jednej operácii. Vytvára prázdny priestor pre nový kód a poskytuje ovládacie prvky na prístup k starému a novému kódu, ako aj tlačidlá a príkazy na postupný prechod na nový kód alebo jeho vylúčenie.
Prepínače funkcií sú zabudované do jazyka Dark, a dokonca aj neúplné prepínače vykonávajú svoju úlohu – ak podmienka v prepínači nie je splnená, bude sa vykonávať starý zablokovaný kód.
Prostredie pre vývoj
Prepínače funkcií nahrádzajú lokálne prostredie vývoja. Dnes majú tímy ťažkosti so zabezpečením toho, aby všetci používali rovnaké verzie nástrojov a knižníc (nástroje na formátovanie kódu, lintery, správca balíkov, kompilátory, predprocesory, testovacie nástroje a pod.) S Dark nie je potrebné inštalovať závislosti lokálne, spravovať lokálnu inštaláciu Dockeru alebo prijímať iné opatrenia na zabezpečenie aspoň akejsi rovnosti medzi vývojovým prostredím a produkciou. , ani sa nebudeme pretvarovať, že sa o ňu snažíme.
Namiesto vytvárania sklonovaného lokálneho prostredia, prepínače v Dark vytvárajú novú pieskovisku v produkcii, ktorá nahrádza vývojové prostredie. V budúcnosti máme v pláne tiež vytvárať pieskovisko pre iné časti aplikácie (napríklad okamžité klony databáz), hoci zatiaľ sa to nezdá až také dôležité.
Vety a nasadenia
V súčasnosti existuje niekoľko spôsobov, ako zaviesť nový kód do systémov: vetvy git, fázy nasadenia a prepínače funkcií. Riešia jeden problém v rôznych častiach pracovného toku: git – vo fázach pred nasadením, nasadenie – v momente prechodu zo starého kódu na nový a prepínače funkcií – pre kontrolované vydanie nového kódu.
Najefektívnejší spôsob sú prepínače funkcií (zároveň najjednoduchšie na pochopenie a použitie). S nimi sa dá úplne vzdať ostatných dvoch metód. Najmä užitočné je odstrániť nasadenie – ak aj tak používame prepínače funkcií na aktiváciu kódu, krok prevodu serverov na nový kód len vytvára zbytočné riziká.
Git je ťažko použiteľný, najmä pre začiatočníkov, a to ho výrazne obmedzuje, ale má pohodlné vetvy. Mnohé nevýhody gitu sme vyhladili. Dark umožňuje úpravy v reálnom čase a spoluprácu v štýle Google Dokumentov, aby sa nemusel kód posielať a aby sa mohlo menej často preberať a zlúčiť.
Prepínače funkcií sú základom bezpečného nasadenia. Spolu s okamžitým nasadením umožňujú rýchlo testovať koncepty v malých fragmentoch s nízkym rizikom, namiesto aplikovania jedinej veľkej zmeny, ktorá môže systém zrútiť.
Verziovanie
Na zmenu funkcií a typov používame verziovanie. Ak chcete zmeniť funkciu, Dark vytvorí novú verziu tejto funkcie. Potom môžete túto verziu zavolať pomocou prepínača v HTTP spracovateľovi alebo udalostiach. (Ak je to funkcia hlboko v grafe volaní, počas procesu sa vytvorí nová verzia každej funkcie. Môže sa to zdať prehnané, ale funkcie sa neprekrývajú, ak ich nepoužívate, takže to ani nezbadáte.)
Z týchto istých dôvodov verzionujeme aj typy. O našom systéme typov sme podrobne hovorili .
Vďaka verziovaniu funkcií a typov môžete vykonávať zmeny v aplikácii postupne. Môžete overiť, že každý jednotlivý spracovateľ funguje s novou verziou, nie je potrebné hneď implementovať všetky zmeny v aplikáciách (ale máme nástroje, ktoré to umožnia rýchlo, ak by ste chceli).
Je to oveľa bezpečnejšie ako plné nasadenie všetkého naraz, ako sa to deje teraz.
Nové verzie balíkov a štandardná knižnica
Keď aktualizujete balík v Dark, okamžite nenahradíme používanie každej funkcie alebo typu v celom kóde. To nie je bezpečné. Kód i naďalej používa tú istú verziu, ktorú používal, a vy aktualizujete používanie funkcií a typov na novú verziu pre každý jednotlivý prípad pomocou prepínačov.
Snímka obrazovky časti automatického procesu v Dark, ukazujúca dve verzie funkcie Dict::get. Dict::get_v0 vracal typ Any (od ktorého sa vzdávame), zatiaľ čo Dict::get_v1 vracia typ Option.
Často poskytujeme novú funkciu štandardnej knižnice a vylučujeme staré verzie. Používatelia so starými verziami v kóde si ich zachovajú, no noví používatelia sa k nim nedostanú. Plánujeme poskytnúť nástroje, aby sme previedli používateľov zo starých verzií na nové v jednom kroku, opäť prostredníctvom prepínačov funkcií.
Dark tiež poskytuje jedinečnú príležitosť: keďže vykonávame váš pracovný kód, môžeme sami testovať nové verzie, porovnávať výstupy pre nové a staré požiadavky, aby sme vám oznámili zmeny. Takže aktualizácia balíkov, ktorá sa často vykonáva naslepo (alebo si vyžaduje dôkladné testovanie kvôli bezpečnosti), predstavuje oveľa menšie riziká a môže prebiehať automaticky.
Nové verzie Dark
Prechod z Python 2 na Python 3 sa natiahol na celé desaťročie a naďalej zostáva problémom. Keďže vytvárame Dark pre nepretržité dodávky, je potrebné zohľadniť tieto zmeny jazyka.
Keď prinesieme malé zmeny do jazyka, vytvárame novú verziu Dark. Starý kód zostáva v starej verzii Dark a nový kód sa používa v novej verzii. Na prechod na novú verziu Dark je možné použiť prepínače alebo verzie funkcií.
To je obzvlášť užitočné, keďže Dark vznikol len nedávno. Mnohé zmeny v jazyku alebo knižnici sa môžu ukázať ako neúspešné. Postupné verziovanie jazyka nám umožňuje vykonávať drobné aktualizácie, teda môžeme sa neponáhľať a odložiť mnohé rozhodnutia o jazyku, až kým nebudeme mať viac používateľov, a teda aj viac informácií.
Migrácie databáz
Pre bezpečnú migráciu databázy existuje :
- Prepisovať kód na podporu nových a starých formátov
- Prekonvertovať všetky dáta do nového formátu
- Odstrániť starý prístup k údajom
Nakoniec migrácia databázy trvá dlhšie a vyžaduje veľa zdrojov. A my zhromažďujeme zastarané schémy, pretože aj jednoduché úlohy, ako napríklad oprava názvu tabuľky alebo stĺpca, neostávajú za vynaložené úsilie.
Dark má efektívnu platformu na migráciu databáz, ktorá (dúfajme) natoľko zjednoduší proces, že sa ho prestanete báť. Všetky úložiská dát v Dark (úložiská párov „kľúč-hodnota“ alebo trvalé hash tabuľky) majú typ. Aby ste preniesli úložisko dát, jednoducho mu priradíte nový typ a funkciu návratu a nakotvenia na prevod hodnôt medzi dvoma typmi.
Prístup k dátovým úložišťám v Dark sa uskutočňuje prostredníctvom verzionovaných názvov premenných. Napríklad, dátové úložisko Users sa pôvodne nazýva Users-v0. Keď sa vytvorí nová verzia s iným typom, názov sa zmení na Users-v1. Ak sú dáta uložené cez Users-v0 a vy k nim pristupujete cez Users-v1, aplikuje sa funkcia návratu. Ak sú dáta uložené cez Users-v1 a vy k nim pristupujete cez Users-v0, aplikuje sa funkcia spätného návratu.
Obrazovka migrácie databázy s názvami polí starého databázového systému, výrazmi návratu a spätného návratu a inštrukciami na aktiváciu migrácie.
Použite prepínače funkcií, aby ste nasmerovali volania z Users-v0 na verziu Users-v1. Môžete to robiť po jednom HTTP spracovateľovi naraz, aby ste znížili riziká, a prepínače fungujú aj pre jednotlivých používateľov, aby ste mohli overiť, že všetko funguje podľa očakávaní. Keď neostane žiadny používateľ Users-v0, Dark v pozadí prevedie všetky zostávajúce dáta zo starého formátu na nový. Ani si to nevšimnete.
Testovanie
Dark je a nemennými hodnotami, takže testovacia plocha je podstatne menšia v porovnaní s objektovo orientovanými jazykmi s dynamickou typizáciou. Ale testovať sa aj tak musí.
V Dark editor automaticky spúšťa modulárne testy v pozadí pre upravený kód a automaticky spúšťa tieto testy pre všetky prepínače funkcií. V budúcnosti chceme pomocou statických typov automaticky vykonávať fuzzing kódu, aby sme našli chyby.
Okrem toho, Dark vykonáva vašu infraštruktúru v produkcii, čo otvára nové možnosti. Automaticky ukladáme HTTP požiadavky v infraštruktúre Dark (kým uchovávame všetky požiadavky, ale neskôr chceme prejsť na vzorkovanie). Testujeme na nich nový kód a vykonávame modulárne testy, a ak budete chcieť, môžete ľahko previesť zaujímavé požiadavky na modulárne testy.
Čo sme odstránili
Keďže nemáme nasadenie, ale máme prepínače funkcií, približne 60 % rozvodového kanála zostáva bokom. Nepotrebujeme git vetvy alebo pull requesty, zostavovanie backendových zdrojov a kontajnerov, odosielanie zdrojov a kontajnerov do registrov alebo kroky nasadenia v Kubernetes.
Porovnanie štandardného pipeline nepretržitého dodávania (vľavo) a Dark nepretržitého dodávania (vpravo). V Dark dodávanie pozostáva z 6 krokov a jedného cyklu, zatiaľ čo tradičná verzia obsahuje 35 krokov a 3 cykly.
V Dark je v nasadení iba 6 krokov a 1 cyklus (kroky, ktoré sa opakujú niekoľkokrát), zatiaľ čo moderný pipeline nepretržitého dodávania pozostáva z 35 krokov a 3 cyklov. V Dark sú testy spúšťané automaticky a vy to ani nevnímate; závislosti sú inštalované automaticky; všetko, čo súvisí s git alebo Github, už nie je potrebné; kompilácia, testovanie a odosielanie Docker kontajnerov nie je potrebné; nasadenie v Kubernetes už nie je potrebné.
Aj zvyšné kroky v Dark sa stali jednoduchšími. Keďže ovládanie funkčných prepínačov je možné jedným krokom, nie je potrebné prechádzať celým pipeline nasadenia druhýkrát, aby ste odstránili starý kód.
Snažili sme sa zjednodušiť dodávanie kódu, znížením času a rizík spojených s nepretržitým dodávaním. Navyše sme výrazne zjednodušili aktualizáciu balíkov, migrácie databáz, testovanie, správu verzií, inštaláciu závislostí, rovnosť medzi prostredím pre vývoj a produkciou a rýchle a bezpečné aktualizácie jazykových verzií.
Na otázky k tomu odpovedám na .
Aby ste sa dozvedeli viac o zariadení Dark, prečítajte si , (alebo na ) alebo . Ak sa chystáte na StrangeLoop v septembri, .
Zdroj: habr.com
