We starten onze blog met publicaties gebaseerd op de laatste toespraken van onze technisch directeur (Dmitry Stolyarov). Ze vonden allemaal plaats in 2016 op verschillende professionele evenementen en waren gewijd aan het onderwerp DevOps en Docker. We hebben al een video gezien van de Docker Moskou-bijeenkomst op het Badoo-kantoor. op de site. De nieuwe berichten zullen vergezeld gaan van artikelen die de essentie van de rapporten weergeven. Dus…
31 mei op de conferentie , dat plaatsvond als onderdeel van het Russian Internet Technologies Festival (RIT++ 2016), opende de sectie Continuous Deployment and Deployment met het rapport "Best Practices of Continuous Delivery with Docker". Het rapport vatte de best practices voor het bouwen van een Continuous Delivery (CD)-proces met Docker en andere open-sourceproducten samen en systematiseerde deze. We werken met deze oplossingen in productie, waardoor we kunnen vertrouwen op praktische ervaring.

Als je de mogelijkheid hebt om een uurtje te besteden aan , raden we aan om de film volledig te bekijken. Anders vindt u hieronder de samenvatting in tekstvorm.
Continue levering met Docker
onder Continue levering We begrijpen de keten van gebeurtenissen waardoor de applicatiecode uit de Git-repository eerst in productie komt en vervolgens in het archief terechtkomt. Het ziet er als volgt uit: Git → Bouwen → Testen → Release → Uitvoeren.

Het grootste deel van het rapport is gewijd aan de build-fase (assemblage van de applicatie), terwijl de onderwerpen release en operate in een overzicht worden behandeld. We zullen praten over problemen en patronen waarmee we deze kunnen oplossen. De specifieke implementaties van deze patronen kunnen variëren.
Waarom is Docker hier überhaupt nodig? Het is niet voor niets dat we besloten hebben om te praten over Continuous Delivery-praktijken in de context van deze open source-tool. Hoewel het hele rapport gewijd is aan het gebruik ervan, worden er al veel redenen onthuld wanneer we kijken naar het hoofdpatroon van de uitrol van applicatiecode.
Hoofduitrolpatroon
Wanneer we dus nieuwe versies van de applicatie uitrollen, komen we onvermijdelijk problemen tegen downtime-probleem, die gegenereerd wordt tijdens het overschakelen van de productieserver. Verkeer van de oude versie van de applicatie naar de nieuwe kan niet direct worden overgeschakeld: eerst moeten we ervoor zorgen dat de nieuwe versie niet alleen succesvol gedownload is, maar ook "opgewarmd" (d.w.z. volledig klaar om verzoeken te verwerken).

Zo zullen beide versies van de applicatie (oud en nieuw) een tijdje gelijktijdig werken. Wat automatisch leidt tot conflict van gemeenschappelijke hulpbronnen: netwerken, bestandssystemen, IPC, enz. Met Docker is dit probleem eenvoudig op te lossen door verschillende versies van de applicatie in aparte containers te draaien, waarbij de resource-isolatie binnen één host (server/virtuele machine) gegarandeerd is. Natuurlijk kun je isolatie helemaal vermijden met een paar trucjes, maar als er een kant-en-klare en handige tool bestaat, is er ook een omgekeerde reden: verwaarlozing ervan is essentieel.
Containerisatie brengt vele andere voordelen met zich mee bij de implementatie. Elke applicatie is afhankelijk van een specifieke versie (of reeks versies) tolk, de aanwezigheid van modules/extensies, enz., evenals hun versies. En dit geldt niet alleen voor de directe uitvoerbare omgeving, maar voor de gehele omgeving, inclusief systeemsoftware en de versies ervan (tot aan de gebruikte Linux-distributie). Omdat containers niet alleen applicatiecode bevatten, maar ook vooraf geïnstalleerde systeem- en applicatiesoftware van de vereiste versies, kunnen problemen met afhankelijkheden worden vergeten.
Laten we samenvatten belangrijkste uitrolpatroon nieuwe versies rekening houdend met de genoemde factoren:
- In eerste instantie draait de oude versie van de applicatie in de eerste container.
- De nieuwe versie wordt vervolgens uitgerold en "opgewarmd" in de tweede container. Het is opmerkelijk dat deze nieuwe versie zelf niet alleen bijgewerkte applicatiecode kan bevatten, maar ook alle bijbehorende afhankelijkheden, evenals systeemcomponenten (bijvoorbeeld een nieuwe versie van OpenSSL of de volledige distributie).
- Zodra de nieuwe versie volledig gereed is om verzoeken te verwerken, wordt het verkeer van de eerste container naar de tweede overgeschakeld.
- Nu kan de oude versie worden gestopt.
Deze aanpak, waarbij verschillende versies van de applicatie in afzonderlijke containers worden geïmplementeerd, biedt nog een ander gemak: snelle terugdraaiing naar de oude versie (het is immers voldoende om het verkeer naar de gewenste container over te zetten).

De laatste eerste aanbeveling klinkt zo goed dat zelfs de kapitein er geen fout in kan vinden: “[bij het organiseren van continue levering met Docker] Gebruik Docker [en begrijp wat het oplevert]Bedenk dat dit geen wondermiddel is dat elk probleem oplost, maar een hulpmiddel dat een goede basis biedt.
Reproduceerbaarheid
Met "reproduceerbaarheid" bedoelen we een algemene reeks problemen die zich voordoen bij het gebruik van applicaties. We hebben het over de volgende gevallen:
- Scenario's die door de kwaliteitsafdeling in de staging-fase worden getest, moeten in de productie nauwkeurig worden gereproduceerd.
- Toepassingen worden gepubliceerd op servers die pakketten kunnen ontvangen van verschillende repository-mirrors (deze worden in de loop van de tijd bijgewerkt, en daarmee ook de versies van de geïnstalleerde toepassingen).
- "Alles werkt lokaal voor mij!" (... en ontwikkelaars mogen de productie niet in.)
- Er moet nog iets gecontroleerd worden in de oude (gearchiveerde) versie.
- ...
Hun algemene essentie komt neer op het feit dat de gebruikte omgevingen volledig consistent moeten zijn (en de afwezigheid van de menselijke factor). Hoe kan reproduceerbaarheid worden gegarandeerd? Docker-images maken gebaseerd op code van Git, en deze vervolgens voor welke taken dan ook gebruiken: op testsites, in productie, op lokale machines van programmeurs... Het is belangrijk om de acties die worden uitgevoerd tot een minimum te beperken na Beeldmontage: hoe eenvoudiger het is, hoe kleiner de kans op fouten.
Infrastructuur is code
Als de infrastructuurvereisten (beschikbaarheid van serversoftware, de versie ervan, enz.) niet geformaliseerd en niet "geprogrammeerd" zijn, kan de uitrol van elke applicatie-update tragische gevolgen hebben. Bijvoorbeeld, als je in de staging-omgeving al bent overgestapt op PHP 7.0 en de code dienovereenkomstig hebt herschreven, dan zal het verschijnen ervan in productie met wat oude PHP (5.5) zeker iemand verrassen. Laten we een grote wijziging in de interpreterversie niet vergeten, maar "de duivel zit in de details": een verrassing kan al snel schuilen in een kleine update van een afhankelijkheid.
De aanpak om dit probleem op te lossen staat bekend als IaC (Infrastructuur als Code) en omvat het opslaan van infrastructuurvereisten samen met de applicatiecode. Ontwikkelaars en DevOps-specialisten kunnen hiermee met één Git-repository van de applicatie werken, maar met verschillende delen ervan. Vanuit deze code in Git wordt een Docker-image gemaakt waarin de applicatie wordt geïmplementeerd, rekening houdend met alle specifieke kenmerken van de infrastructuur. Simpel gezegd: de scripts (regels) voor het bouwen van images moeten zich in dezelfde repository bevinden als de broncodes en samengevoegd worden.

In het geval van een meerlaagse applicatiearchitectuur — bijvoorbeeld, er is nginx die vóór de applicatie staat die al in een Docker-container draait — moeten Docker-images worden gemaakt op basis van de code in Git voor elke laag. De eerste image bevat dan de applicatie met de interpreter en andere "naaste" afhankelijkheden, en de tweede de upstream nginx.
Docker-images, communicatie met Git
We verdelen alle Docker-images die met Git zijn gebouwd in twee categorieën: tijdelijk en release. Tijdelijke afbeeldingen worden getagd met de branchnaam in Git, kunnen worden overschreven door de volgende commit en worden alleen uitgerold voor preview (niet voor productie). Dit is hun belangrijkste verschil met releaseversies: je weet nooit welke specifieke commit erin zit.
Het is zinvol om te verzamelen in tijdelijke images: de master branch (deze kan automatisch worden uitgerold naar een apart platform zodat u altijd de huidige versie van de master kunt zien), branches met releases en branches van specifieke innovaties.

Nadat de preview van tijdelijke afbeeldingen is voltooid en de vertaling naar productie nodig is, plaatsen ontwikkelaars een specifieke tag. Deze tag wordt automatisch verzameld. afbeelding vrijgeven (de tag komt overeen met de tag van Git) en wordt uitgerold naar de staging-omgeving. Als de kwaliteitsafdeling de code succesvol controleert, gaat deze naar productie.
Dapp
Alles wat beschreven staat (uitrol, image-assemblage, daaropvolgend onderhoud) kan onafhankelijk worden geïmplementeerd met behulp van Bash-scripts en andere "geïmproviseerde" tools. Maar als je dit doet, zal de implementatie op een gegeven moment leiden tot grote complexiteit en beperkte beheersbaarheid. Met dit in gedachten, zijn we tot de ontwikkeling van ons eigen gespecialiseerde Workflow-hulpprogramma voor het bouwen van CI/CD gekomen. Dapp.
De broncode is geschreven in Ruby, open source en gepubliceerd op Helaas is de documentatie momenteel het zwakste punt van de tool, maar we werken eraan. We zullen meer dan eens over dapp schrijven en erover vertellen, omdat we oprecht ongeduldig zijn om de mogelijkheden ervan met de hele geïnteresseerde community te delen. In de tussentijd kunt u uw problemen en pull-requests indienen en/of de ontwikkeling van het project volgen op GitHub.
Bijgewerkt op 13 augustus 2019: momenteel een project Dapp hernoemd naar , de code is geheel herschreven in Go en de documentatie is aanzienlijk verbeterd.
Kubernetes
Een andere kant-en-klare Open Source-tool die al aanzienlijke erkenning heeft gekregen in de professionele gemeenschap is Kubernetes, een cluster voor het beheer van Docker. Het gebruik ervan bij de uitvoering van projecten die op Docker zijn gebouwd, valt buiten het bestek van dit rapport, dus de presentatie beperkt zich tot een overzicht van enkele interessante functies.
Voor implementatie biedt Kubernetes:
- gereedheidstest — controleren van de gereedheid van een nieuwe versie van de applicatie (om het verkeer ernaartoe over te schakelen);
- rolling update — sequentiële update van een afbeelding in een cluster van containers (uitschakelen, bijwerken, voorbereiden voor lancering, verkeer omschakelen);
- synchrone update - het bijwerken van de afbeelding in het cluster met een andere aanpak: eerst op de helft van de containers, daarna op de rest;
- canary releases - start een nieuwe image op een beperkt (klein) aantal containers om te controleren op anomalieën.
Omdat Continuous Delivery niet zomaar een nieuwe versie is, beschikt Kubernetes over een aantal functies voor daaropvolgend infrastructuuronderhoud: ingebouwde monitoring en logging voor alle containers, automatische schaalbaarheid, enzovoort. Dit alles werkt al en wacht alleen nog op een correcte implementatie in uw processen.
Laatste aanbevelingen
- Gebruik Docker.
- Maak Docker-images van uw applicatie voor al uw behoeften.
- Volg het principe "Infrastructuur is code".
- Git koppelen aan Docker.
- Regel de uitrolprocedure.
- Gebruik een kant-en-klaar platform (Kubernetes of een ander).
Video's en dia's
Video van de voorstelling (ongeveer een uur) (het verslag zelf begint bij de 5e minuut - volg de link om vanaf dat moment af te spelen).
Presentatie van het rapport:
PS
Andere verslagen over dit onderwerp in onze blog:
- «» (Dmitry Stolyarov; 27 mei 2019 op DevOpsConf);
- «» (Dmitry Stolyarov; 8 november 2018 op HighLoad++);
- «» (Dmitry Stolyarov; 7 november 2017 op HighLoad++);
- «» (Dmitry Stolyarov; 6 juni 2017 bij RootConf).
Bron: www.habr.com
