Kontinuerlig leveranspraxis med Docker (granskning och video)

Vi kommer att starta vår blogg med publikationer baserade på de senaste talen från vår tekniska chef distol (Dmitry Stolyarov). Alla av dem ägde rum under 2016 vid olika professionella evenemang och var dedikerade till ämnet DevOps och Docker. En video från Docker Moskva-mötet på Badoo-kontoret har vi redan publiceras Uppkopplad. Nya kommer att åtföljas av artiklar som förmedlar kärnan i rapporterna. Så…

31 maj på konferensen RootConf 2016, som hölls som en del av festivalen "Russian Internet Technologies" (RIT++ 2016), öppnades avsnittet "Continuous Deployment and Deployment" med rapporten "Best Practices of Continuous Delivery with Docker". Den sammanfattade och systematiserade de bästa metoderna för att bygga en kontinuerlig leveransprocess (CD) med Docker och andra produkter med öppen källkod. Vi arbetar med dessa lösningar i produktionen, vilket gör att vi kan lita på praktisk erfarenhet.

Kontinuerlig leveranspraxis med Docker (granskning och video)

Om du har möjlighet att spendera en timme video av rapporten, vi rekommenderar att du tittar på den i sin helhet. I övrigt finns nedan huvudsammanfattningen i textform.

Kontinuerlig leverans med Docker

nedanför Kontinuerlig leverans vi förstår händelsekedjan som ett resultat av att applikationskoden från Git-förvaret först kommer till produktion och sedan hamnar i arkivet. Det ser ut så här: Git → Bygg → Test → Släpp → Kör.

Kontinuerlig leveranspraxis med Docker (granskning och video)
Det mesta av rapporten ägnas åt byggstadiet (applikationssammansättning), och ämnena som släpps och fungerar berörs kort. Vi kommer att prata om problem och mönster som gör att du kan lösa dem, och de specifika implementeringarna av dessa mönster kan vara annorlunda.

Varför behövs Docker här överhuvudtaget? Det är inte för inte som vi bestämde oss för att prata om metoder för kontinuerlig leverans i samband med detta verktyg med öppen källkod. Även om hela rapporten ägnas åt dess användning, avslöjas många orsaker när man överväger huvudmönstret för utbyggnaden av applikationskoder.

Huvudutbyggnadsmönster

Så när vi rullar ut nya versioner av applikationen står vi verkligen inför stilleståndsproblemgenereras under byte av produktionsservern. Trafik från den gamla versionen av applikationen till den nya kan inte byta omedelbart: först måste vi se till att den nya versionen inte bara laddas ned utan också "uppvärmd" (dvs. helt redo att betjäna förfrågningar).

Kontinuerlig leveranspraxis med Docker (granskning och video)
Under en tid kommer alltså båda versionerna av applikationen (gamla och nya) att fungera samtidigt. Vilket automatiskt leder till konflikt med delad resurs: nätverk, filsystem, IPC, etc. Med Docker löses detta problem enkelt genom att köra olika versioner av applikationen i separata behållare, för vilka resursisolering garanteras inom samma värd (server/virtuell maskin). Naturligtvis kan du klara dig med några knep utan isolering alls, men om det finns ett färdigt och bekvämt verktyg, så finns det den motsatta anledningen - att inte försumma det.

Containerisering ger många andra fördelar när den används. Varje ansökan beror på specifik version (eller versionsintervall) tolk, tillgänglighet av moduler/tillägg etc. samt deras versioner. Och detta gäller inte bara den omedelbara körbara miljön, utan även hela miljön, inklusive systemmjukvara och dess version (upp till den använda Linux-distributionen). På grund av det faktum att behållare inte bara innehåller applikationskod, utan också förinstallerad system- och applikationsprogramvara av de nödvändiga versionerna, kan du glömma problem med beroenden.

Låt oss generalisera huvudsakliga utbyggnadsmönster nya versioner med hänsyn till följande faktorer:

  1. Till en början körs den gamla versionen av programmet i den första behållaren.
  2. Den nya versionen rullas sedan ut och "värms upp" i en andra behållare. Det är anmärkningsvärt att denna nya version i sig kan innehålla inte bara uppdaterad applikationskod, utan också alla dess beroenden, såväl som systemkomponenter (till exempel en ny version av OpenSSL eller hela distributionen).
  3. När den nya versionen är helt redo att betjäna förfrågningar växlar trafiken från den första behållaren till den andra.
  4. Den gamla versionen kan nu stoppas.

Det här tillvägagångssättet att distribuera olika versioner av applikationen i separata behållare ger en annan bekvämlighet - snabb återställning till den gamla versionen (det räcker trots allt att byta trafik till önskad behållare).

Kontinuerlig leveranspraxis med Docker (granskning och video)
Den sista första rekommendationen låter som något som inte ens kaptenen kunde hitta fel på: "[när du organiserar kontinuerlig leverans med Docker] Använd Docker [och förstå vad det ger]" Kom ihåg att detta inte är en silverkula som löser alla problem, utan ett verktyg som ger en underbar grund.

Reproducerbarhet

Med "reproducerbarhet" menar vi en generaliserad uppsättning problem som uppstår vid drift av applikationer. Vi talar om sådana fall:

  • Skript som kontrolleras av kvalitetsavdelningen för iscensättning måste återges korrekt i produktionen.
  • Applikationer publiceras på servrar som kan ta emot paket från olika repository-speglar (med tiden uppdateras de, och med dem versionerna av installerade applikationer).
  • "Allt fungerar för mig lokalt!" (...och utvecklare är inte tillåtna i produktion.)
  • Du måste kontrollera något i den gamla (arkiverade) versionen.
  • .

Deras allmänna väsen kokar ner till det faktum att full överensstämmelse med de miljöer som används (liksom frånvaron av den mänskliga faktorn) är nödvändig. Hur kan vi garantera reproducerbarhet? Gör Docker-bilder baserat på kod från Git, och använd dem sedan för alla uppgifter: på testplatser, i produktion, på lokala maskiner hos programmerare... Samtidigt är det viktigt att minimera de åtgärder som utförs efter sammansättning av bilden: ju enklare det är, desto mindre sannolikt finns det fel.

Infrastruktur är kod

Om infrastrukturkraven (tillgängligheten av serverprogramvara, dess version etc.) inte är formaliserade och "programmerade" kan utrullningen av en programuppdatering resultera i katastrofala konsekvenser. Till exempel, i iscensättning har du redan bytt till PHP 7.0 och skrivit om koden därefter - då kommer dess utseende i produktion med något gammalt PHP (5.5) säkert att överraska någon. Du kanske inte glömmer en stor förändring i tolkversionen, men "djävulen är i detaljerna": överraskningen kan vara i en mindre uppdatering av något beroende.

Ett tillvägagångssätt för att lösa detta problem är känt som IaC (Infrastruktur som kod, "infrastruktur som kod") och innebär lagring av infrastrukturkrav tillsammans med applikationskoden. Med hjälp av det kan utvecklare och DevOps-specialister arbeta med samma Git-applikationsförråd, men på olika delar av det. Från denna kod skapas en Docker-avbildning i Git, där applikationen distribueras med hänsyn till alla detaljer i infrastrukturen. Enkelt uttryckt bör skripten (reglerna) för sammansättning av bilder finnas i samma arkiv som källkoden och slås samman.

Kontinuerlig leveranspraxis med Docker (granskning och video)

I fallet med en applikationsarkitektur med flera lager - till exempel finns det nginx, som står framför en applikation som redan körs inuti en Docker-behållare - Docker-bilder måste skapas från kod i Git för varje lager. Då kommer den första bilden att innehålla en applikation med en tolk och andra "nära" beroenden, och den andra bilden kommer att innehålla uppströms nginx.

Docker-bilder, kommunikation med Git

Vi delar in alla Docker-bilder som samlats in från Git i två kategorier: temporära och släppta. Tillfälliga bilder taggade med namnet på filialen i Git, kan skrivas över av nästa commit och rullas ut endast för förhandsvisning (inte för produktion). Det här är deras viktigaste skillnad från release: du vet aldrig vilken specifik commit som finns i dem.

Det är vettigt att samla in i tillfälliga bilder: mastergrenen (du kan automatiskt rulla ut den till en separat webbplats för att ständigt se den aktuella versionen av master), grenar med utgåvor, grenar av specifika innovationer.

Kontinuerlig leveranspraxis med Docker (granskning och video)
Efter att förhandsgranskningen av tillfälliga bilder kommer till behovet av översättning till produktion, sätter utvecklarna en viss tagg. Samlas automatiskt av tagg släpp bilden (dess tagg motsvarar taggen från Git) och rullas ut till staging. Om det framgångsrikt verifieras av kvalitetsavdelningen går det till produktion.

Dapp

Allt som beskrivs (utrullning, bildmontering, efterföljande underhåll) kan implementeras oberoende med hjälp av Bash-skript och andra "improviserade" verktyg. Men om du gör detta kommer implementeringen någon gång att leda till stor komplexitet och dålig styrbarhet. När vi förstod detta kom vi att skapa vårt eget specialiserade Workflow-verktyg för att bygga CI/CD - Dapp.

Dess källkod är skriven i Ruby, öppen källkod och publicerad på GitHub. Tyvärr är dokumentation för närvarande verktygets svagaste punkt, men vi jobbar på det. Och vi kommer att skriva och prata om dappen mer än en gång, för... Vi kan verkligen inte vänta med att dela dess kapacitet med hela den intresserade communityn, men under tiden skicka dina frågor och dra förfrågningar och/eller följ utvecklingen av projektet på GitHub.

Uppdaterad 13 augusti 2019: för närvarande ett projekt Dapp bytt namn till werf, dess kod har skrivits om helt i Go, och dess dokumentation har förbättrats avsevärt.

Kubernetes

Ett annat färdigt verktyg med öppen källkod som redan har fått betydande erkännande i den professionella miljön är Kubernetes,ett Docker-hanteringskluster. Ämnet för dess användning i driften av projekt byggda på Docker ligger utanför rapportens omfattning, så presentationen är begränsad till en översikt av några intressanta funktioner.

För lansering erbjuder Kubernetes:

  • beredskapssond — kontrollera beredskapen för en ny version av applikationen (för att byta trafik till den);
  • rullande uppdatering - sekventiell bilduppdatering i ett kluster av behållare (avstängning, uppdatering, förberedelse för lansering, trafikväxling);
  • synkron uppdatering - uppdatering av en bild i ett kluster med ett annat tillvägagångssätt: först på hälften av behållarna, sedan på resten;
  • canary releases - lanserar en ny bild på ett begränsat (litet) antal behållare för att övervaka anomalier.

Eftersom Continuous Delivery inte bara är releasen av en ny version, har Kubernetes ett antal möjligheter för efterföljande infrastrukturunderhåll: inbyggd övervakning och loggning för alla containrar, automatisk skalning, etc. Allt detta fungerar redan och väntar bara på ordentligt implementering i dina processer.

Slutliga rekommendationer

  1. Använd Docker.
  2. Skapa Docker-bilder av applikationer för alla dina behov.
  3. Följ principen "Infrastruktur är kod."
  4. Länka Git till Docker.
  5. Reglera utrullningsordningen.
  6. Använd en färdig plattform (Kubernetes eller annan).

Videor och bilder

Video från föreställningen (ungefär en timme) publiceras på YouTube (Själva rapporten börjar från den 5:e minuten - följ länken för att spela från detta ögonblick).

Presentation av rapporten:

PS

Andra rapporter om ämnet på vår blogg:

Källa: will.com

Lägg en kommentar