Låt oss bekanta oss med de viktigaste funktionerna i Docker. Docker: behållare är bara Docker-bildskapande

Faktum är att Docker verkligen är ett måste-verktyg för utvecklare och administratörer av alla stora projekt. Men även om så inte är fallet behöver du fortfarande känna till Docker: inom en mycket snar framtid kommer det att finnas överallt, från en stationär Linux-distribution till en pool av servrar på AWS. Och det bästa är att det är ganska lätt att förstå Docker, om du förstås korrekt förstår principen för dess funktion.

Passa på att komma in i en värld av virtuella miljöer

Docker är baserad på namnutrymmen och cgroups-teknologier (den första tillhandahåller isolering, den andra tillhandahåller processgruppering och resursbegränsning), så när det gäller virtualisering är det inte mycket annorlunda än LXC/OpenVZ vi är vana vid, och det finns inte mycket att prata om här. Samma inbyggda hastighet, samma isoleringsmetoder baserade på Linux-kärnmekanismer. Men på en högre nivå börjar en helt annan historia. Höjdpunkten med Docker är att den låter dig distribuera en fullfjädrad virtuell miljö och köra en applikation i den lika enkelt som att till exempel starta om webbservern.

Låt oss abstrahera från detaljerna i specifika distributioner och föreställa oss att vi har ren CentOS och vi vill köra ett visst kommando i det i en helt virtuell miljö utan tillgång till huvudsystemet. Måste du ladda ner distributionsbilder, distribuera dem till systemet och konfigurera en virtuell miljö? Inte alls, allt du behöver göra är att köra två kommandon:

$sudo mums installera docker-io $ sudo docker kör -t ubuntu:senaste /usr/bin/top

Och det är allt. Vi har precis lanserat toppverktyget i en behållare med en miljö baserad på den senaste versionen av Ubuntu, som matar ut information till den aktuella terminalen. Och allt detta med ett enkelt kommando (installation räknas inte). Inte illa, eller hur? I allmänhet kan vi till och med "gå in i" den här behållaren och göra allt som vanligtvis görs med ett nyinstallerat system:

$ sudo docker run -t -i ubuntu:senaste /bin/bash # apt-get update # apt-get install nginx #

Som du kan se är allt OK med nätverket, så vi kan uppdatera systemet, installera och konfigurera vilken programvara som helst. Det ser lite ut som magi, men det är faktiskt väldigt enkelt. Docker är ett slags apt-get i containervärlden, bara istället för paket finns filsystemavbildningar, och istället för officiella Debian/Ubuntu-förråd - molnlagring, kallad Docker Hub.

När vi körde "docker run..." gjorde systemet följande:

  1. Docker-verktyget kontaktade dockerd-demonen på vår lokala dator, sa hej från oss och bad oss ​​att köra den senaste versionen av Ubuntu (detta indikeras av den senaste taggen i kommandot) i en isolerad behållare.
  2. Dockerd-demonen kontrollerade sin anteckningsbok, gick till katalogen /var/lib/docker och fick reda på att det inte fanns någon filsystemavbildning från den senaste Ubuntu på vår maskin, så den bestämde sig för att kontakta Docker Hub för att ta reda på om en sådan bild var där.
  3. Efter att ha pratat med Docker Hub var han övertygad om att bilden fortfarande fanns och bad att få skicka den till oss.
  4. Efter att ha mottagit den önskade bilden, monterade dockerd sitt filsystem, chrootade det och körde kommandot som specificerades i det sista argumentet, vilket begränsade dess "omfång" med hjälp av namnutrymmen (i huvudsak avbröt dess åtkomst till huvud-FS, värdsystemprocesser, IPC, etc. , låste den i en sandlåda), men överförde enhetsfilerna för den nuvarande terminalen till den (-t-flaggan) så att vår topp kunde rita dess pseudografiska gränssnitt.

Höjdpunkten med denna modell är att Docker Hub är öppen för alla och alla kan förbereda sin egen bild (mer om det senare) och publicera den för installation på en annan maskin och/eller av en annan person. I skrivande stund publicerades mer än 45 tusen bilder på Docker Hub för alla tillfällen, allt från bilder av "bara" distributioner till bilder med förkonfigurerade server- och skrivbordsapplikationer som körs i en minimalistisk Linux-miljö.

Vad händer om vi vill köra Firefox i en virtuell miljö? Det finns inget enklare, öppna Docker Hub i webbläsaren, klicka på Bläddra & Sök och skriv firefox. En lista med resultat visas på skärmen. Låt oss se, kennethkl/firefox verkar vara ganska passande. Vi klickar på den och ser information om hur man lanserar det hela. Författaren säger åt oss att köra följande kommando:

$ sudo docker run -d --name firefox -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix kennethkl/firefox

Låt oss försöka. Ja, verkligen, efter en kort nedladdning av bilden får vi standard Firefox på skärmen. Med samma exempel kan du förresten bekanta dig med fyra mer användbara alternativ för docker run-kommandot:

  • -d - "demoniserar" behållaren, det vill säga den kopplar helt enkelt bort Docker från STDOUT i den virtuella miljön och låter den köras i bakgrunden;
  • --name - namnet på behållaren som den kommer att ta emot istället för identifieraren;
  • -e - låter dig "vidarebefordra" en miljövariabel till den virtuella maskinen;
  • -v - vidarebefordrar den angivna filen eller katalogen (format /fil/på/värd/system:/fil/i/virtuell eller helt enkelt /fil/på/värd/system om sökvägarna matchar).

I det här fallet behövs variabeln och filen så att Firefox kan komma åt den lokala maskinens skärm. Detta är ganska osäkert, eftersom alla processer i behållaren inte bara kommer att kunna köra vilken programvara som helst på ditt skrivbord, utan även till exempel fånga upp tangenttryckningar eller markörrörelser. Men det räcker som ett exempel.

Det finns ett enklare sätt att söka efter Docker-bilder med dockningskommandot:

$ sudo docker sök nginx

INFO

Alla Docker-användare kan köra sin egen privata Hub. Det kallas ett "register" och finns som en färdig bild. Allt du behöver göra är att köra det: docker run -p 5555:5555 registret.

Docker-demonen är tillgänglig inte bara med hjälp av en klient, utan också med ett RESTful API, både lokalt och från en fjärrdator. Standard Docker-portar är tcp/2375 och tcp/2376.

Docker-avbildningen behöver inte startas omedelbart efter nedladdning, du kan först ladda ner den till din lokala dator med kommandot docker pull, och först sedan köra: docker pull ubuntu.

Lagertårta

Docker låter dig göra arbetet med virtuella miljöer så bekvämt som möjligt, vilket förenklar både processen för att distribuera miljöer och ställa in deras interaktion med värdsystemet (vilket bara är det sista exemplet). Men detta är inte dess enda höjdpunkt.

Om du redan har spelat med Ubuntu-bilden från de två första exemplen, har du förmodligen märkt att varje ny start av behållaren sker "från grunden", och alla ändringar som gjorts under den senaste sessionen går förlorade. Detta är inte en bugg alls, det är en av de nyckelfunktioner Docker-arkitektur, vilket gör det till en ännu mer intressant och attraktiv lösning.

Faktum är att i de allra flesta fall är en "Docker-bild" inte alls en monolitisk filsystemsbild, utan en sorts lagerkaka som består av flera bilder filsystem på basis av vilken behållaren bildas. Samtidigt är individuella FS-avbildningar inte alls ansvariga för vissa delar av katalogstrukturen (som t.ex. vid uppdelning av en disk under Linux i /home, /var, /boot-partitioner), utan är skiktade ovanpå varandra med hjälp av AUFS-kärnmekanismen Linux (det finns också stöd för samma funktionalitet genom användning av btrfs, enhetsmappare och overlay).

För att förstå hur detta fungerar, låt oss gå tillbaka till vår containeriserade Ubuntu. Vi startar behållaren och installerar nginx, som visas i det andra exemplet i början av artikeln, men slutför det inte. Istället lanserar vi en annan terminal och tittar på listan över körande containrar:

$ sudo docker ps

Det här kommandot kommer att visa alla körande behållare tillsammans med deras ID, bild som används, kommandot lanserat, drifttid och mer. Vi är intresserade av värdet i kolumnen CONTEINER ID. Kopiera det och kör följande kommando:

$ sudo docker commit ubuntu-nginx container ID

När den har slutfört sitt arbete kan du lämna behållaren och på så sätt slutföra sitt arbete. Och sedan startar vi helt enkelt ubuntu-nginx-behållaren och ser att nginx inte har försvunnit någonstans och är på sin plats:

$ sudo docker kör -i -t ubuntu-nginx /bin/bash # som nginx /usr/sbin/nginx

Vad har vi gjort? Vi skapade ytterligare ett lager, det vill säga en extra FS-bild, och genererade en ny Docker-bild baserad på den redan befintliga Ubuntu Docker-bilden, inklusive vår FS-bild, som innehåller nginx. Låter lite förvirrande, eller hur? Det är faktiskt ganska enkelt.

Vi har redan fått reda på att varje Docker-bild består av flera FS-bilder. När vi startar en container monteras dessa bilder och sätts ihop till en enda katalogstruktur med hjälp av AUFS. Till exempel kan den första bilden bara innehålla basen installera Ubuntu, den andra lägger till en uppsättning standarddemoner till den, den tredje lägger till administrationsverktyg och så vidare. Docker monterar alla lager i skrivskyddat läge, men för att vi ska kunna ändra innehållet i bilden monteras ytterligare ett initialt tomt lager ovanpå i läs/skrivläge.


Som standard, efter att behållaren avslutas (vilket inträffar efter att den sista processen som körs i den avslutas), raderas det sista lagret och alla våra ändringar går förlorade. Men med kommandot docker commit kan vi "commit" ändringarna genom att skapa en ny Docker-bild baserat på befintliga FS-bilder plus FS-bilden med våra ändringar. På så sätt kommer ändringarna vi gör att sparas. Om vi ​​vill kan vi starta ubuntu-nginx-behållaren, göra ändringar i den och spara den på samma sätt i en ny Docker-bild med commit, lägga till ytterligare ett lager. För att se en lista över alla resulterande bilder (och mottagna från Docker Hub), kan du använda kommandot docker images, och för att se historiken för bildandet av lager, använd kommandot docker history:

$ sudo docker historik ubuntu-nginx

Detta tillvägagångssätt för att skapa bilder ger större flexibilitet vid hantering av behållare, sparar mycket tid och gör att du enkelt kan överföra redan konfigurerade Docker-avbildningar mellan maskiner (bilden kan laddas upp till Docker Hub och sedan distribueras till en annan dator). En mindre uppenbar fördel är att spara diskutrymme. Om vi ​​distribuerar ett helt zoo med containrar på en maskin, som var och en initialt kommer att baseras på en basbild (samma Ubuntu, till exempel) - kommer de alla att referera till denna basbild och inte duplicera dess innehåll.


Docker utanför Linux

Det enda sättet att köra Docker på OS X eller Windows är att installera det i en virtuell maskin. Det är inte nödvändigt att göra detta manuellt, du kan använda en färdig lösning, till exempel boot2docker. Detta är en uppsättning skript som låter dig snabbt distribuera en virtuell maskin med Linux och Docker inuti VirtualBox och köra den med automatisk åtkomst via SSH. Instruktioner för dess användning och själva installationsprogrammet finns på den officiella Docker-webbplatsen.

Nätverkskonfiguration

För att containrar ska kunna kommunicera med varandra och med världen utanför,Docker höjer automatiskt en virtuell nätverksbrygga och konfigurerar maskeringsregler (NAT) för det externa nätverksgränssnittet. Det gör att det inte kommer att vara möjligt att nå containrarna utifrån. Däremot kan vi konfigurera portvidarebefordran så att en begäran till vissa portar på maskinens externa nätverksgränssnitt automatiskt vidarebefordras till de angivna portarna i containern. Till exempel, på Mirantis, körs huvudbränslenoden (detta är ett GUI för att distribuera och konfigurera OpenStack) i Docker och använder portvidarebefordransfunktionen för att öppna åtkomst till ful/nginx-behållaren (port 8000):

$ sudo docker run -d -p 8000:8000 fuel/nginx_6.0:latest /usr/local/bin/start.sh

Vi skulle kunna vidarebefordra port 8000 till vilken annan containerport som helst genom att helt enkelt ändra det andra numret i alternativet -p, men i den här konfigurationen är det inte vettigt.

Filvidarebefordran och Dockerfile

I början av artikeln bekantade vi oss redan med flaggan -v, som låter dig vidarebefordra vilken fil eller katalog som helst från värdsystemet till behållaren. Detta är en mycket bekväm funktion, den kan användas både för att lagra eventuella temporära data och för att dela filer mellan flera behållare. I Mirantis används den här funktionen för att vidarebefordra konfigurationsfiler för Fuel/astute-tjänsten (/etc/astute) inuti behållaren:

$ sudo docker kör -d -v /etc/astute fuel/astute_6.0:latest /usr/local/bin/start.sh

Detsamma kan göras med kommandot VOLUME i Dockerfilen. Dockerfilen i sig är den lokala motsvarigheten till en Makefile, men medan den senare är avsedd för att bygga applikationer från källan låter Dockerfilen dig bygga bilder för Docker. Dess syfte är att förenkla skapandet av nya bilder utan att behöva starta en behållare, utföra vissa operationer i den och begå. Du kan bara skriva en Dockerfil och Docker kommer att göra allt åt dig. Tänk till exempel på Dockerfilen för att bygga bränsle/insikt:

FRÅN bränsle/centos UNDERHÅLLARE Matthew Mosesohn [e-postskyddad] KÖR rm -rf /etc/yum.repos.d/*;\ echo -e "\nname=Nailgun Local Repo\nbaseurl=http://$(route -n | awk "/^0.0.0.0/ ( print $2 )"):_PORT_/os/x86_64/\ngpgcheck=0" > /etc/yum.repos.d/nailgun.repo;\ yum clean all;\ yum --quiet install -y ruby21-nailgun-mcagents sysstat ADD etc /etc ADD start.sh /usr/local/bin/start.sh KÖR marionett tillämpa --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/astute-only.pp; [[$? == 0 || $? == 2 ]] KÖR chmod +x /usr/local/bin/start.sh;\ echo -e "\nname=Nailgun Local Repo\nbaseurl=file:/var/www/nailgun/centos/x86_64\ngpgcheck=0 " > /etc/yum.repos.d/nailgun.repo; mums rengör alla VOLYM /etc/astute CMD /usr/local/bin/start.sh

Det är inte svårt att förstå vad den är avsedd för. Den skapar en bild baserad på fuel/centos, kör flera kommandon för att förbereda bilden, lägger till filer från den aktuella katalogen till bilden, tillämpar Puppet-manifestet, ändrar behörigheterna för vissa filer, släpper /etc/asture/-katalogen från värdsystemet in i behållaren och kör behållaren med kommandot /usr/local/bin/start.sh.

För att bygga en behållare, lägg bara Dockerfilen och alla filer som kommer att läggas till den i någon katalog och kör följande kommando:

$ sudo docker build fuel/astute_6.0:senaste

I det här fallet valde vi namnet fuel/astute_6.0:latest, även om det kan vara vad som helst.

Nyanserna av att arbeta med Docker

Docker är byggd kring idén att varje container bara ska ha en tjänst igång. Du paketerar Apache, MySQL, nginx, Varnish och allt du kan behöva för ett projekt i olika behållare och använder sedan Docker för att sätta ihop allt. Detta tillvägagångssätt ger större flexibilitet, eftersom det gör att du enkelt kan ändra konfigurationer, testa uppdateringar och migrera enskilda tjänster till andra maskiner.

Av samma anledning används Docker inte ofta för att starta fullfjädrade Linux-miljöer med init-demonen, cron- och syslog-demonerna och andra. Istället lanserar vi helt enkelt tjänsten vi behöver, och den körs i en virtuell miljö helt ensam:

$ sudo docker kör -d -p 80 ubuntu-nginx /usr/sbin/nginx

Men det finns ett litet problem här. Docker avslutar behållaren omedelbart efter att processen som körs i den (i det här fallet nginx) har avslutats, och eftersom nginx är demoniserad som standard, det vill säga, den gafflar en ny process och avslutar den vi startade manuellt, avslutas Docker omedelbart efter detta och en container, spika en gaffelformad Docker.

I fallet med nginx kan du komma runt det här problemet genom att lägga till demon off; den första raden i hans konfiguration. Andra demoner kommer att kräva sina egna inställningar, och vissa kan förhindras från att demoniseras direkt från kommandorad. Till exempel tillhandahåller sshd flaggan -D för detta:

$ sudo docker kör -d -p 22 ubuntu-ssh /usr/sbin/sshd -D

Du kan när som helst ansluta till containern med kommandot docker exec för att visa loggar eller ändra inställningar (nedan är container-ID antingen det ID som kan ses i docker ps-utgången eller namnet som anges vid start i --name alternativet ):

$ sudo docker exec -ti container ID /bin/bash

Men det finns en liten hake här också. Som vi vet kommer all information som ackumulerats under driften av den virtuella miljön att gå förlorad om vi stänger av den virtuella miljön, och tillsammans med det försvinner loggarna och ändringarna i inställningarna. Vi kan inte heller skapa lager i oändlighet (om så bara för att det inte kan finnas fler än 127 av dem), men vi kan gå en lite annan väg och använda logaggregationssystemet inbyggt i Docker. Docker kan naturligtvis inte samla in loggar från enskilda applikationer, men den kan samla STDOUT-utdata, det vill säga vilken konsolutdata som helst. Allt som återstår för oss är att ändra nginx-konfigurationen så att loggarna hälls i /dev/stdout, och sedan visa dem med kommandot docker logs:

$ sudo docker loggar container-ID

Ett annat och mer korrekt alternativ är att helt enkelt överföra loggarna (och vid behov inställningarna) till värdsystemet med det redan beskrivna alternativet -v:

$ sudo mkdir /root/logs $ sudo docker kör -d -v /root/logs:/var/logs -p 80 ubuntu-nginx /usr/sbin/nginx

Vid behov kan behållaren stoppas korrekt genom att avsluta tjänsten som körs i den med kommandot docker stop:

$ sudo docker stop container ID

Och om det inte fungerar att stoppa korrekt av någon anledning, kan du döda det med kill:

$ sudo docker kill container ID

Detta gör en viktig sak som många nybörjare glömmer: Docker lagrar metainformation om behållaren. I själva verket betyder detta att om du startar till exempel nginx, anger dess namn, kataloger som måste vidarebefordras till behållaren, portar, miljövariabler, etc. med hjälp av docker run-kommandot, så kommer all denna information att sparas när behållaren avslutas och , för att starta den nästa gång, behöver du inte längre specificera den, utan kör bara följande kommando (du kan använda namnet istället för ID):

$ sudo docker start container ID

Om det inte finns något behov av att spara tillstånd (till exempel för att testa eller verifiera någon funktionalitet), kan du använda flaggan --rm, vilket kommer att tvinga Docker att fullständigt förstöra behållaren efter att den är klar (med bilden bevarad):

$ sudo docker kör --rm -i -t busybox /bin/bash

Du kan förstöra alla tidigare sparade behållare med följande kommando:

# docker rm $(docker ps -a -q)

Docker kan självständigt starta om containrar om de kraschar och till och med starta dem under systemstart. Allt du behöver göra är att helt enkelt använda alternativet --restart:

$ sudo docker kör --restart=alltid \ -d -v /root/logs:/var/logs -p 80 \ ubuntu-nginx /usr/sbin/nginx

När som helst kan bilden exporteras till en enda fil och sedan importeras till en annan maskin. Docker spara och docker återställning kommandon tillhandahålls för detta. Att använda dem är väldigt enkelt, export görs så här:

$ sudo docker spara -o ubuntu-nginx.img ubuntu-nginx

Och importen är så här:

$ sudo docker ladda -i ubuntu-nginx.img

Slutsatser

Docker är ett utmärkt verktyg. För en oinvigd person kan det verka som en leksak som inte lämpar sig för något annat än att köra programvara i en sandlåda, men med dess hjälp kan du lösa ett stort antal problem, som vi kommer att prata om i nästa artikel.

Fördelar med Docker över LXC, OpenVZ och andra virtualiseringslösningar på OS-nivå

  1. Docker använder ett bärbart, universellt bildformat. Detta innebär att dessa bilder kan överföras till en annan maskin utan problem och delas för användning av andra användare.
  2. En bild kan fungera som underlag för andra bilder. I Docker är det normalt att använda flera lager för att bilda den slutliga bilden. Du kan börja med en bas Ubuntu-bild och sedan lägga till Apache 2.4 för att skapa en Ubuntu + Apache-mikrotjänst.
  3. Vid committing kan bilden versioneras, precis som det görs i GIT.
  4. Docker har en stor community och ett omfattande ekosystem, som inkluderar ett stort antal verktyg för skalning, gruppering, övervakning, driftsättning och hantering av containrar.

Inuti Docker finns bara Linux och, experimentellt, FreeBSD. Körs inbyggt under Linux och experimentellt under FreeBSD. Under MacOSX, Windows - genom en virtuell maskin.

Docker är dubbelisolerad. Isolera vad som finns inuti Docker-behållaren från operativsystemet och isolera operativsystemet från vad som finns inuti Docker. Isolering innebär isolering av alla filer, portar, prioriteringar.

Det är nästan en virtuell maskin. Nästan, men inte riktigt.

Det finns något sådant som "beroendehelvete". Alla program installerade på en dator, för med sig beroenden(konfigurationsfiler, statiska filer som vanligtvis kallas tillgångar, hjälpprogram/tjänster, bibliotek, etc.). Ett antal av dessa bibliotek/verktyg/tjänster oförenliga med varandra. Och med tanke på att vart och ett av dessa bibliotek/verktyg/tjänster har sina egna beroenden är situationen ännu värre.

Till exempel använder vi Yandex.Cocaine, som normalt bara kompileras på Ubuntu 14.04 (och, tydligen, på Debian 7). Men inte under CentOS 6, 7, Debian 8, FreeBSD 9, 10, Ubuntu 15, 16, etc. - det är omöjligt att kompilera det. Vi lanserar i dessa operativsystem i Docker.

Å andra sidan, och samtidigt, måste du installera annan, modernare programvara. Och samtidigt äldre. Och vi pratar inte ens om allvarligt olika versioner av Linux. Till exempel kräver en programvara minst Ubuntu 14.10, medan en annan kräver minst Linux 14.04.

Docker är ett program inom en enskild miljö med en individuell version av operativsystemet. På grund av puffbehållare, om du använder en rot för allt, då storleken på Docker-behållaren bara är några kilobyte större än storleken på den binära filen, körs under Docker.

Således har vi en binär fil som körs som i sitt eget operativsystem.

Man kan säga – bah, men detta har varit känt länge virtuell maskin. Men nej, det är inte sant. Dessa är de så kallade containrarna. Nej virtuell maskin det luktar inte där. Bakom förutom Windows och MacOSX, där arbete utan en virtuell maskin fortfarande bara är experimentellt möjligt, och normen i dessa operativsystem är att använda Docker i en fullfjädrad virtuell maskin.

Docker virtuella maskiner används endast för utveckling. För att köras i produktion används inte virtuella maskiner med Docker.

Docker använder operativsystembehållare. LXC på Linux, Jails på FreeBSD. En behållare är ett område i operativsystemet som är isolerat från huvuddelen av operativsystemet. Behållaren har sitt eget katalogträd (inklusive systemet /dev, /bin, /sbin, etc.), sitt eget nätverksportar osv osv.

Men den använder inte full virtualisering. Vilket sparar resurser avsevärt. Starta 100 fullfjädrade virtuella maskiner Det är osannolikt att det fungerar ens på en kraftfull server. Och här köra 100 Docker-containrar även på en svag hemdator- Kanske.

Det är sant att användningen av ofullständig virtualisering begränsar användningen av operativsystem inuti behållare. Typiskt är detta speciellt förberedd Linux-versioner eller FreeBSD. Exakt speciellt förberedda sådana. Windows - i princip är det omöjligt att köra i en container.

Containers fanns före Docker. Docker, strängt taget, är bara en mycket bekväm uppsättning verktyg, samlade för att hantera containervirtualisering. Men väldigt bekväm.

Varför används detta?

Killar från alla sorters Dropbox, Facebook och andra jättar, som lanserade 1 miljon olika program i sina tjänster, ställdes inför det faktum att Det är omöjligt att garantera identiska operativsysteminställningar överallt. Och detta är kritiskt.

Till den grad att ett perfekt skrivet och testat program på en riktig server börjar bete sig oförutsägbart.

Därför födde en av dessa smarta killar ett nytt koncept - varje program på servrarna körs i sin egen individuella miljö, med individuella operativsysteminställningar.

Dessutom - ursprungligen utvecklaren programvaratesta ett program i en Docker-behållare, med vissa inställningar. OCH i samma (eller med samma inställningar) Docker-behållare går programmet till servern.

Detta låter dig garantera mycket större identitet mellan utvecklingsmiljön och runtime-miljön.

Innan detta led folk, kom på listiga installatörer...

Efter de spottade på försök att effektivisera miljön i operativsystemet- och nu är konceptet detta - installera program på servrar tillsammans med deras individuellt konfigurerade operativsystem- det vill säga inuti containrar. 1 behållare = 1 OS-inställning = 1 program inuti.

Med andra ord:

  • Docker-behållaren ska användas för felsökning.
  • Samma Docker-behållare måste användas på servern.

Detta gör att du inte besvärar dig med inställningar "under servern" lokalt på utvecklarens maskin. Detta gör att du kan utveckla på utvecklarens maskin helt olika program samtidigt, vilket kräver inkompatibla operativsysteminställningar. Detta gör att vi kan ge mycket fler garantier för att programmet på servern kommer att bete sig på samma sätt som på utvecklarens maskin. Detta gör att du kan utveckla under Windows/MacOSX med bekväm "transparent" testning under Linux.

Docker är tillämplig för skapande/anpassning endast serverprogramvara för Linux(experimentellt under FreeBSD). Inte för smartphones. Och om stationära datorer används, då endast programvara utan GUI.

Så länge Docker tillåter i ett slag, förenkla arbetet för utvecklare och administratörer och förbättra kvaliteten på resultatet– nu är det en boom i Docker. Ett stort berg av verktyg har uppfunnits för att hantera distributionen av applikationer skapade med Docker. Om du tidigare, för att köra 10 000 program på 1 000 servrar, behövde minst 3 högt kvalificerade devops-specialister som skrev en massa beskrivningar av hur detta kan göras på Puppet, Salt, Chef, Ansible, och även då fanns det inga garantier, allt testades i månader. Nu med Docker kan även en kvalificerad devops hantera miljontals program på tiotusentals servrar. Med en mycket större garanti för att allt startar normalt.

Det kan finnas ett felaktigt intryck av att utvecklaren förbereder behållare i Docker och sedan lämnar över dem till administratören.
Den korrekta metoden är fortfarande annorlunda:

Utvecklaren bidrar med all sin produktion till CI-systemet (vanligtvis via git)
För varje ny commit skapar CI en bild för testning med Docker.
Om testerna lyckas skickas samma Docker-avbildning för distribution till produktion.
Eller, lite annorlunda i kompilerade system, där källorna inte behövs i produktionen: i Docker distribueras en miljö för kompilering, och för testning distribueras en andra bild med de redan kompilerade grejerna, som redan skickas till produktion.

Det vill säga med rätt organisation av ärendet kan/bör utvecklaren inte påverka hur bilden kommer att se ut.
Men i testmiljön (lanserad på servern, otillgänglig för utvecklaren i stora team) och i produktionen används den exakt samma bild.

Huvudtanken är att det vi testade är precis det vi lanserar på produktionsservern. En-till-en, inklusive samma filer (inte samma, men exakt samma).

Jag har använt Docker i flera månader nu för att strukturera utvecklings-/leveransprocessen för webbprojekt. Jag erbjuder Habrakhabr-läsare en översättning av den inledande artikeln om hamnarbetare - "Understanding docker".

Vad är docker?

Docker är en öppen plattform för att utveckla, leverera och driva applikationer. Docker är utformad för att leverera dina applikationer snabbare. Med docker kan du frikoppla din applikation från din infrastruktur och behandla infrastrukturen som en hanterad applikation. Docker hjälper dig att skicka din kod snabbare, testa snabbare, skicka applikationer snabbare och minska tiden mellan att skriva kod och körning av kod. Docker gör detta genom en lättviktigm, med hjälp av processer och verktyg som hjälper dig att hantera och vara värd för dina applikationer.

I kärnan låter docker dig köra nästan vilken applikation som helst, säkert isolerad i en container. Säker isolering gör att du kan köra många behållare på samma värd samtidigt. Behållarens lätta karaktär, som körs utan extra börda av en hypervisor, gör att du kan få ut mer av din hårdvara.

Behållarvirtualiseringsplattformen och verktygen kan vara användbara i följande fall:

  • packa din applikation (och de komponenter du använder) i hamnarcontainrar;
  • distribution och leverans av dessa behållare till era team för utveckling och testning;
  • lägga ut dessa behållare på dina produktionsplatser, både i datacenter och i molnen.

Vad kan jag använda docker till?

Publicera dina applikationer snabbt

Docker är bra för att organisera utvecklingscykeln. Docker tillåter utvecklare att köra lokala behållare med applikationer och tjänster. Vilket sedan låter dig integrera med processen med kontinuerlig integration och driftsättningsarbetsflöde.

Till exempel, dina utvecklare skriver kod lokalt och delar sin utvecklingsstack (en uppsättning Docker-bilder) med kollegor. När de är redo skickar de koden och behållarna till testplatsen och kör alla nödvändiga tester. Från testplatsen kan de skicka kod och bilder till produktion.

Lättare att lägga ut och fälla ut

Docker-containerbaserade plattformen gör det enkelt att porta din nyttolast. Docker-containrar kan köras på din lokala maskin, antingen på riktigt eller på en virtuell maskin i ett datacenter, eller i molnet.

Dockers bärbarhet och lätta karaktär gör det enkelt att dynamiskt hantera din arbetsbelastning. Du kan använda docker för att distribuera eller stänga av din applikation eller tjänster. Dockerhastigheten gör att detta kan göras i nästan realtid.

Högre laster och mer nyttolaster

Docker är lätt och snabb. Det ger ett motståndskraftigt, kostnadseffektivt alternativ till hypervisorbaserade virtuella maskiner. Det är särskilt användbart i högbelastningsmiljöer, till exempel när du skapar ditt eget moln eller plattform-som-tjänst. Men det är också användbart för små och medelstora applikationer när du vill få ut mer av de resurser du har.

Huvudkomponenter för Docker

Docker består av två huvudkomponenter:
  • Docker: en virtualiseringsplattform med öppen källkod;
  • Docker Hub: Vår plattform-som-en-tjänst för distribution och hantering av Docker-containrar.
Notera! Docker distribueras under Apache 2.0-licensen.

Docker-arkitektur

Docker använder en klient-server-arkitektur. Docker-klienten kommunicerar med Docker-demonen, som tar på sig bördan av att skapa, köra och distribuera dina behållare. Både klient och server kan köras på samma system, du kan ansluta klienten till en fjärransluten docker-demon. Klienten och servern kommunicerar via en socket eller ett RESTful API.

Docker-demon

Som visas i diagrammet körs demonen på värddatorn. Användaren interagerar inte direkt med servern utan använder klienten för detta.

Docker-klient

Docker-klienten, docker-programmet, är huvudgränssnittet till Docker. Den tar emot kommandon från användaren och interagerar med docker-demonen.

Inuti hamnarbetare

För att förstå vad docker består av behöver du veta om tre komponenter:
  • bilder
  • register
  • behållare

Bilder

Docker-bilden är en skrivskyddad mall. Till exempel kan bilden innehålla operativsystemet Ubuntu med Apache och en applikation på. Bilder används för att skapa behållare. Docker gör det enkelt att skapa nya bilder, uppdatera befintliga eller så kan du ladda ner bilder skapade av andra. Bilder är komponenter i en docker build.

Register

Docker-registret lagrar bilder. Det finns offentliga och privata register från vilka du kan ladda ner eller ladda upp bilder. Det offentliga Docker-registret är Docker Hub. Det finns en enorm samling bilder lagrade där. Som du vet kan bilder skapas av dig eller så kan du använda bilder skapade av andra. Register är en distributionskomponent.

Behållare

Behållare liknar kataloger. Behållare innehåller allt som applikationen behöver för att köras. Varje behållare skapas från en bild. Behållare kan skapas, startas, stoppas, migreras eller tas bort. Varje behållare är isolerad och ger en säker plattform för applikationen. Behållare är komponenter i arbetet.

Så hur fungerar Docker?

Så långt vet vi att:
  • vi kan skapa bilder där våra applikationer finns;
  • vi kan skapa behållare från bilder för att köra applikationer;
  • Vi kan distribuera bilder via Docker Hub eller annat bildregister.
Låt oss se hur dessa komponenter passar ihop.

Hur fungerar bilden?

Vi vet redan att en bild är en skrivskyddad mall från vilken en behållare skapas. Varje bild består av en uppsättning nivåer. Docker använder ett fackligt filsystem för att kombinera dessa lager till en enda bild. Unions filsystem tillåter filer och kataloger från olika filsystem (olika grenar) att överlappa transparent, vilket skapar ett sammanhängande filsystem.

En av anledningarna till att docker är lätt är för att den använder sådana här lager. När du ändrar bilden, till exempel när du uppdaterar en applikation, skapas ett nytt lager. Så utan att ersätta hela bilden eller bygga om den, som du kan ha att göra med en virtuell maskin, läggs bara lagret till eller uppdateras. Och du behöver inte distribuera hela den nya bilden, bara uppdateringen distribueras, vilket gör det enklare och snabbare att distribuera bilder.

I hjärtat av varje bild finns en basbild. Till exempel, ubuntu, basbilden för Ubuntu, eller fedora, basbilden för Fedora-distributionen. Du kan också använda bilder som bas för att skapa nya bilder. Om du till exempel har en apache-bild kan du använda den som basbild för dina webbapplikationer.

Notera! Docker hämtar vanligtvis bilder från Docker Hub-registret.

Docker-bilder kan skapas från dessa basbilder; vi kallar stegen för att skapa dessa bilder instruktioner. Varje instruktion skapar en ny bild eller nivå. Instruktionerna kommer att vara följande:

  • Kör kommando
  • lägga till en fil eller katalog
  • skapa en miljövariabel
  • instruktioner om vad som ska köras när behållaren för den här bilden startas

Dessa instruktioner lagras i en Dockerfile. Docker läser denna Dockerfil när du bygger bilden, utför dessa instruktioner och returnerar den slutliga bilden.

Hur fungerar docker-registret?

Registret är ett arkiv för docker-bilder. När bilden har skapats kan du publicera den till det offentliga Docker Hub-registret eller till ditt personliga register.

Med docker-klienten kan du söka efter redan publicerade bilder och ladda ner dem till din docker-dator för att skapa behållare.

Docker Hub tillhandahåller offentliga och privata bildarkiv. Att söka och ladda ner bilder från offentliga arkiv är tillgängligt för alla. Innehållet i privata lagringar ingår inte i sökresultaten. Och bara du och dina användare kan ta emot dessa bilder och skapa behållare från dem.

Hur fungerar en container?

En behållare består av ett operativsystem, användarfiler och metadata. Som vi vet skapas varje behållare från en bild. Den här bilden talar om för docker vad som finns i behållaren, vilken process som ska startas, när behållaren startar och annan konfigurationsdata. Docker-bilden är skrivskyddad. När docker startar en behållare skapar den ett läs-/skrivlager ovanpå bilden (med hjälp av fackföreningsfilsystemet som nämnts tidigare) där applikationen kan köras.

Vad händer när containern startar?

Antingen genom docker-programmet eller genom RESTful API, uppmanar docker-klienten docker-demonen att starta behållaren.

$ sudo docker kör -i -t ubuntu /bin/bash

Låt oss ta en titt på det här kommandot. Klienten startas med kommandot docker, med alternativet kör som säger att den ska starta en ny behållare. Minimikrav för att köra en container är följande attribut:

  • vilken bild som ska användas för att skapa behållaren. I vårt fall ubuntu
  • kommandot du vill köra när behållaren startas. I vårt fall /bin/bash

Vad händer under huven när vi kör det här kommandot?

Docker, i ordning, gör följande:

  • laddar ner ubuntu-bilden: docker kontrollerar om det finns en ubuntu-avbild på den lokala maskinen, och om den inte finns där laddar den ner den från Docker Hub. Om det finns en bild, använder den den för att skapa en behållare;
  • skapar en behållare: när bilden tas emot använder docker den för att skapa en behållare;
  • initierar filsystemet och monterar den skrivskyddade nivån: behållaren skapas i filsystemet och bilden läggs till på skrivskyddad nivå;
  • initierar nätverket/bryggan: skapar ett nätverksgränssnitt som tillåter docker att kommunicera med värddatorn;
  • Ställa in IP-adressen: hittar och ställer in adressen;
  • Startar den angivna processen: startar din applikation;
  • Bearbetar och producerar utdata från din applikation: ansluter och loggar din applikations standardinmatning, -utgång och felström så att du kan spåra hur din applikation presterar.
Du har nu en fungerande container. Du kan hantera din behållare, interagera med din applikation. När du bestämmer dig för att stoppa programmet tar du bort behållaren.

Teknik som används

Docker är skrivet i Go och använder vissa funktioner i Linux-kärnan för att implementera ovanstående funktionalitet.

Namnutrymmen

Docker använder namnrymdsteknik för att organisera isolerade arbetsytor, som vi kallar containrar. När vi startar en behållare skapar docker en uppsättning namnrymder för den behållaren.

Detta skapar ett isolerat lager, där varje aspekt av behållaren körs i sitt eget namnområde och inte har tillgång till det externa systemet.

Lista över några namnområden som docker använder:

  • pid: att isolera processen;
  • netto: för hantering av nätverksgränssnitt;
  • ipc: att hantera IPC-resurser. (ICP: InterProccess Communication);
  • mnt: att hantera monteringspunkter;
  • utc: för att isolera kärnan och kontrollversionsgenereringen (UTC: Unix timesharing system).

Kontrollgrupper

Docker använder också teknik för cgroups eller kontrollgrupper. Nyckeln till att köra en applikation isolerat är att förse applikationen med endast de resurser du vill tillhandahålla. Detta säkerställer att containrarna blir goda grannar. Kontrollgrupper låter dig dela tillgängliga hårdvaruresurser och vid behov sätta gränser och begränsningar. Begränsa till exempel den möjliga mängden minne för behållaren.

Unions filsystem

Union File Sysem eller UnionFS är ett filsystem som fungerar genom att skapa lager, vilket gör det väldigt lätt och snabbt. Docker använder UnionFS för att skapa blocken från vilka behållaren är byggd. Docker kan använda flera varianter av UnionFS inklusive: AUFS, btrfs, vfs och DeviceMapper.

Behållarformat

Docker kombinerar dessa komponenter till ett omslag som vi kallar containerformatet. Standardformatet kallas libcontainer. Docker stöder också det traditionella containerformatet i Linux med LXC. I framtiden kan Docker stödja andra containerformat. Till exempel, integration med BSD Jails eller Solaris Zones.

Docker är ett populärt verktyg som, genom användning av behållare, tillhandahåller allt du behöver för att köra applikationer. Genom att använda Docker-behållare kan du vara säker på att din applikation kommer att köras på samma sätt på vilken maskin du kör den på.

I den här handledningen kommer du att lära dig om förhållandet mellan behållare och Docker-avbildningar och hur du installerar, startar, stoppar och tar bort behållare.

Recension

Docker-bild kan ses som en mall som används för att skapa behållare. Bilder börjar vanligtvis med ett rotfilsystem, som sedan skiktas med olika ändringar och deras motsvarande startparametrar. Till skillnad från typiska Linux-distributioner, innehåller en Docker-avbildning vanligtvis bara de delar som behövs för att köra programmet. Bilder har inga statuser och ändras inte. Det skulle vara mer korrekt att säga att de är utgångspunkten, grunden för Docker-containrar.

Bilderna kommer till liv i samma ögonblick som du utfärdar kommandot docker run - det skapar omedelbart en behållare genom att lägga till ett nytt läs-skrivlager ovanpå bilden. Denna kombination av skrivskyddade lager (med ett läs-skriv-lager lagt till ovanpå) är också känt som UnionFS, ett filsystem som kaskaderar fackliga monteringar av filsystem. När en ändring görs i en befintlig fil i en körande behållare, kopieras filen från det skrivskyddade lagret till läs-skrivlagret, där ändringarna tillämpas. Och nu är originalfilen dold av läs-skrivversionen, men den raderas inte. Sådana förändringar i skriv- och läsnivåer finns bara inom en given individuell behållare. När en behållare tas bort går alla ändringar också förlorade (såvida de inte har sparats).

Arbeta med containrar

Varje gång du använder kommandot docker run skapas en ny behållare från bilden du anger. Mer specifika exempel kommer att diskuteras nedan.

Steg 1: Skapa två behållare

Docker run-kommandot nedan skapar en ny behållare som kommer att använda Ubuntu-avbildningen som bas. -t-växeln kommer att tillhandahålla terminalen, och -i kommer att ge möjligheten att interagera med den. För att komma in i behållaren kan du använda standardkommandot bash. Det vill säga, du kan ange:

$ docker run -ti ubuntu

$ docker kör -i -t ubuntu:14.04 /bin/bash

(i det andra fallet kommer du att köra kommandot /bin/bash inuti behållaren och du kommer automatiskt att vara inne i behållaren)

Kommandoraden kommer att bekräfta att du är inne i behållaren som superanvändare. Efter @-tecknet ser du ID:t för behållaren du befinner dig i:

Root@11cc47339ee1:/#

Använd nu kommandot echo, gör ändringar i /tmp-katalogen och kontrollera sedan att ändringarna skrevs med kommandot cat:

Echo "Example1" > /tmp/Example1.txt cat /tmp/Example1.txt

På skärmen bör du se:

Lämna nu behållaren:

När detta kommando har utförts och du avslutar kommandoraden, slutar Docker-behållaren att fungera. Du kan se detta om du använder kommandot docker ps:

Bland de löpande behållarna kommer du inte att se den som används ovan:

KONTAINER-ID BILDKOMMANDO SKAPADE STATUSPORTNAMN

Du kan dock lägga till omkopplaren -a för att se alla behållare - både igång och stoppade - och då kommer behållaren du arbetade i att markeras:

$ docker ps -a CONTAINER ID BILDKOMMANDO SKAPADE STATUS PORTAR NAMN 11cc47339ee1 ubuntu "/bin/bash" 9 minuter sedan Avslutad (127) 10 sekunder sedan small_sinoussi

När en behållare skapas har den ett ID och ett automatiskt genererat namn. I det här fallet är 11cc47339ee1 behållarens identifikationsnummer (ID) och small_sinoussi är det genererade namnet. Kommandot ps -a visar dessa data, såväl som bilden från vilken behållaren skapades (i detta fall ubuntu), när behållaren skapades (9 minuter sedan), och vilket kommando som kördes i den ("/bin/ bash"). Du kan också se statusen för behållaren (den lämnade för 10 sekunder sedan). Om behållaren fortfarande var igång, skulle du se statusen "Upp" och tiden den har varit igång.

Nu kan du ange kommandot igen för att skapa behållaren:

$ docker run -ti ubuntu

Även om kommandot ser likadant ut som förra gången, kommer det att skapa en helt ny behållare - den kommer att ha ett annat ID-nummer, och om du försöker titta på innehållet i filen Exempel1 som du redigerade tidigare, hittar du den inte .

Root@6e4341887b69:/# cat /tmp/Exempel1

Utgången blir:

Katt: /tmp/Exempel1: Ingen sådan fil eller katalog

Det kan tyckas för dig som att uppgifterna har försvunnit, men så är det förstås inte. Gå ur den andra behållaren för att säkerställa att båda behållarna (inklusive den första med önskad fil) finns i systemet.

Root@6e4341887b69:/# avsluta $ docker ps -a

Utgången blir:

CONTAINER ID BILDKOMMANDO SKAPADE STATUSPORTNAMN 6e4341887b69 ubuntu "/bin/bash" För ungefär en minut sedan Avslutad (1) för 6 sekunder sedan kickass_borg 11cc47339ee1 ubuntu "/bin/bash" för 15 minuter sedan small 6si minuter sedan small 6si

Steg 2: Starta om den första behållaren

För att starta om en redan skapad behållare måste du använda startkommandot med två -ai-switchar. I slutet måste du skriva identifikationsnumret för behållaren du vill arbeta med, eller dess namn. Som ett resultat kommer ditt kommando att se ut så här:

Docker start -ai 11cc47339ee1

Nu är du tillbaka i bash-skalet inuti behållaren och du kan verifiera att filen du skapade i början av artikeln fortfarande finns här:

Cat /tmp/Example1.txt

Du kommer att se på skärmen:

Nu kan du lämna behållaren:

På så sätt sparas alla ändringar inuti behållaren, även om du stoppar och sedan startar om behållaren. Data raderas endast när själva behållaren raderas. Exemplet ovan visar också att ändringarna påverkar en enskild behållare (och inte alla behållare samtidigt).

Steg 3: Ta bort båda behållarna

Det sista steget är att ta bort de två behållare du skapade genom att följa denna handledning. För att göra detta måste du använda kommandot docker rm. Det påverkar dock bara stoppade containrar. Efter kommandot måste du ange identifikationsnumret eller namnet på en eller flera behållare. Till exempel, för att ta bort behållare som skapats tidigare, måste du ange kommandot:

Docker rm 6e4341887b69 small_sinoussi

Skärmen kommer att visa:

6e4341887b69 small_sinoussi

Nu har båda behållarna tagits bort.

Slutsats

I den här handledningen lärde du dig om de grundläggande kommandona för att arbeta i Docker och lärde dig hur du skapar, stoppar, startar om och tar bort behållare.

Vi har berört ämnet mer än en gång och övervägt många system för att bygga dem. Idag kommer vi att introducera ett annat bra system, Docker-containrar.

Låt oss börja med att beskriva den grundläggande funktionaliteten som kommer att vara användbar i ytterligare artiklar i serien, och kort minns Docker-arkitekturen. Docker använder en klient-server-arkitektur och består av en klient - docker-verktyget, som får åtkomst till servern med RESTful API, och en demon i operationssalen Linux-system(se fig. 1). Även om Docker körs på icke-Linux operativsystem, täcks de inte av den här artikeln.

Huvudkomponenter i Docker:
    • Behållare– användarmiljöer där applikationer körs, isolerade med operativsystemsteknik. Det enklaste sättet att definiera en Docker-behållare är som ett program som körs från en bild. Förresten, det är just detta som ideologiskt skiljer Docker från till exempel LXC ( Linux-behållare), även om de använder samma Linux-kärnteknologier. Utvecklarna av Docker-projektet följer principen: en behållare är lika med en applikation.
    • Bilder– skrivskyddade applikationsmallar. Nya lager kan läggas till ovanpå befintliga bilder som tillsammans representerar filsystemet, modifiera eller utöka det föregående lagret. Vanligtvis skapas en ny bild antingen genom att spara en redan körande behållare i en ny bild ovanpå den befintliga, eller genom att använda speciella instruktioner för verktyget. För att separera olika behållarnivåer på filsystemsnivå kan användas AUFS, btrfs, vfs och Device Mapper. Om du planerar att använda Docker tillsammans med SELinux, då krävs det Device Mapper.
    • Register som innehåller förråd ( förvaret) bilder, – nätverkslagring av bilder. De kan vara antingen privata eller offentliga. Det mest kända registret är .

För att isolera behållare i GNU/Linux-operativsystem används vanliga Linux-kärnteknologier, såsom:
  • Namnutrymmen ( Linux-namnområden).
  • Kontrollgrupper ( C-grupper).
  • Privilege Management Tools ( Linux-funktioner).
  • Ytterligare, obligatoriska säkerhetssystem, som t.ex AppArmor eller SELinux.

Låt oss titta på de listade teknikerna lite mer detaljerat.

Kontrollgruppsmekanism (Cgroups) ger ett verktyg för finkornig kontroll över tilldelning, prioritering och hantering av systemresurser. Kontrollgrupper är implementerade i Linux-kärnan. I moderna distributioner hanteras kontrollgrupper genom systemd, men det är fortfarande möjligt att styra med hjälp av biblioteket libcgroup och verktyg cgconfig. De huvudsakliga hierarkierna för cgroups (även kallade kontroller) listas nedan:

  • blkio– sätter gränser för I/O-operationer och åtkomst till blockeringsenheter;
  • CPU– med hjälp av processschemaläggaren fördelar processortid mellan uppgifter;
  • cpuacct– skapar automatiska rapporter om användningen av CPU-resurser. Fungerar tillsammans med regulatorn CPU, beskriven ovan;
  • cpuset– tilldelar specifika processorer och minnesnoder till uppgifter;
  • enheter– reglerar uppgifternas åtkomst till vissa enheter;
  • frys– pausar eller återupptar uppgifter;
  • minne– sätter gränser och genererar rapporter om minnesanvändning av kontrollgruppsuppgifter;
  • net_cls– utför taggning nätverkspaket klassidentifierare ( klassid). Detta gör att trafikledaren ( tc team) och brandvägg ( iptables) ta hänsyn till dessa taggar när trafik bearbetas;
  • perf_event– låter dig övervaka kontrollgrupper med hjälp av verktyget perfekt;
  • hugetlb– tillåter användning av virtuella minnessidor stor storlek och tillämpa gränser för dem.

Namnutrymmen i sin tur kontrollerar de inte fördelningen av resurser, utan tillgången till kärndatastrukturer. I själva verket innebär detta att man isolerar processer från varandra och möjligheten att ha parallella "identiska", men inte korsande hierarkier av processer, användare och nätverksgränssnitt. Om så önskas kan olika tjänster till och med ha sina egna loopback-gränssnitt.

Exempel på namnutrymmen som används av Docker:
  • PID, Process ID– isolering av processhierarkin.
  • NET, nätverk– isolering av nätverksgränssnitt.
  • PC, InterProcess Communication– Hantering av interaktion mellan processer.
  • MNT, Mount– Hantering av monteringspunkter.
  • UTS, Unix tidsdelningssystem– isolering av kärnan och versionsidentifierare.

En mekanism som kallas Förmågor låter dig dela upp rootanvändarens privilegier i små grupper av privilegier och tilldela dem individuellt. Denna funktion dök upp i GNU/Linux från och med version kärna 2.2. Inledningsvis lanseras behållare med en begränsad uppsättning privilegier.

Med hjälp av docker-kommandoalternativen kan du aktivera eller inaktivera:
  • monteringsoperationer;
  • tillgång till uttag;
  • Att utföra vissa filsystemoperationer, som att ändra filattribut eller ägande.

Du kan lära dig mer om privilegier med hjälp av man-sidan KAPACITETER(7).

Installerar Docker

Låt oss titta på installation av Docker med CentOS som exempel. När du kör CentOS har du ett val: använd den senaste versionen från u pstream eller versionen som sammanställts av CentOS-projektet med Red Hat-tillägg. En beskrivning av ändringarna finns på sidan.

Detta är huvudsakligen en backport av korrigeringar från nya uppströmsversioner och ändringar föreslagna av Red Hat-utvecklare, men som ännu inte har antagits i huvudkoden. Den mest märkbara skillnaden i skrivande stund var att i nya versioner var docker-tjänsten uppdelad i tre delar: demonen docker, containerd och runc. Red Hat tror ännu inte att denna förändring är stabil och levererar den monolitiska körbara versionen 1.10.

Lagringsinställningar för installation uppströmsversioner, samt instruktioner för installation i andra distributioner och operativsystem, finns i installationsguiden på den officiella webbplatsen. Specifikt, inställningarna för CentOS 7-förvaret:

# cat /etc/yum.repos.d/docker.repo name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7 enabled=1 gpgcheck=1 gpgkey=https://yum .dockerproject.org/gpg

# cat /etc/yum.repos.d/docker.repo

namn = Repository

baseurl=https://yum.dockerproject.org/repo/main/centos/7

aktiverad = 1

gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg

Installera nödvändiga paket på och starta och aktivera tjänsten:

# mums installera -y docker-engine # systemctl starta docker.service # systemctl aktivera docker.service

# yum install -y docker-motor

# systemctl starta docker.service

# systemctl aktivera docker.service

Kontrollera servicestatus:

# systemctl status docker.service

# systemctl status docker.service

Du kan också se systeminformation om Docker och miljön:

# hamnarbetare info

Om du kör samma kommando om du installerade Docker från CentOS-förråden, kommer du att se mindre skillnader på grund av användningen av en äldre version av programvaran. Från utgången hamnarinfo vi kan ta reda på att den används som en drivrutin för att lagra data Device Mapper, och som lagring – en fil i /var/lib/docker/:

# ls -lh /var/lib/docker/devicemapper/devicemapper/data -rw-------. 1 rotrot 100G 27 dec 12:00 /var/lib/docker/devicemapper/devicemapper/data

# ls -lh /var/lib/docker/devicemapper/devicemapper/data

Rw -- -- -- - . 1 rotrot 100G 27 dec 12:00 /var/lib//devicemapper/devicemapper/data

Alternativ för att starta demonen, som är typiskt på CentOS, lagras i /etc/sysconfig/. I det här fallet är filnamnet docker. Motsvarande rad /etc/sysconfig/docker, som beskriver alternativen:

OPTIONS="--selinux-enabled --log-driver=journald"

Om du skulle köra docker-kommandot som en icke-root-användare eller en användare som inte är medlem i docker-gruppen, skulle du se ett fel så här:

$ docker sök mysql

$ sök mysql

Varning: det gick inte att hämta standardregistrets slutpunkt från demonen (Kan inte ansluta till Docker-demonen. Körs docker-demonen på denna värd?). Använder systemets standard: https://index. docker.io/v1/

Kan inte ansluta till Docker-demonen. Körs docker-demonen på denna värd?

Observera att att lägga till en användare i dockergruppen är detsamma som att lägga till den användaren i rotgruppen.

RHEL/CentOS-utvecklarna har en något annorlunda inställning till Docker-demonsäkerhet än uppströmsutvecklarna av Docker själv. Läs mer om Red Hats tillvägagångssätt i en artikel av RHEL-distributionsutvecklaren Dan Walsh.

Om du vill att Dockers "standard" beteende ska installeras från CentOS-förråden (dvs. beskrivet i den officiella dokumentationen), måste du skapa en dockargrupp och lägga till demonstartalternativen:

OPTIONS="--selinux-enabled --log-driver=journald ↵ --group=docker"

ALTERNATIV = "--selinux-enabled --log-driver=journald ↵ --group=docker"

Sedan startar vi om tjänsten och kontrollerar att docker-socket-filen tillhör docker-gruppen och inte root:

# ls -l /var/run/docker.sock

Docker bildsökning och taggar

Låt oss försöka hitta en behållare på Docker Hub.

$ docker sök haproxy

$search haproxy


I denna utgång fick vi en lista med ett antal HA Proxy-bilder. Det översta objektet i listan är HA Proxy från det officiella förvaret. Sådana bilder kännetecknas av att namnet inte innehåller symbolen «/» , separerar namnet på användarens förråd från namnet på själva behållaren. Det officiella exemplet visar två haproxybilder från offentliga användararkiv eeacms och miljoner12.

Du kan själv skapa bilder som de två nedan genom att registrera dig på Docker Hub. De officiella stöds av ett speciellt team sponsrat av Docker, Inc. Funktioner i det officiella förvaret:

  • Dessa är rekommenderade bilder för användning, baserade på bästa praxis och riktlinjer.
  • De ger grundläggande bilder som kan fungera som utgångspunkt för mer finjustering. Till exempel basbilder av Ubuntu, CentOS eller bibliotek och utvecklingsmiljöer.
  • Innehålla senaste versionerna programvara med fixerade sårbarheter.
  • Detta är den officiella produktdistributionskanalen. För att endast söka efter officiella bilder kan du använda alternativet –filter “is-official=true” lag hamnarsök.

Antal stjärnor i kommandoutgången hamnarsök motsvarar bildens popularitet. Detta liknar en knapp Tycka om V i sociala nätverk eller bokmärken för andra användare. Automatiserad innebär att bilden byggs automatiskt från ett speciellt skript med hjälp av Docker Hub. Vanligtvis bör du ge företräde åt automatiskt insamlade bilder på grund av att dess innehåll kan verifieras genom att bekanta dig med motsvarande .

Ladda ner den officiella HA Proxy-bilden:

$ docker pull haproxy Använder standardtagg: senaste

Det fullständiga namnet på bilden kan se ut så här:

[användarnamn]bildnamn[:tagg]

Du kan se listan över nedladdade bilder med kommandot docker-bilder:

Körande containrar

För att köra en behållare är det inte nödvändigt att först ladda ner bilden. Om den är tillgänglig kommer den att laddas ner automatiskt. Låt oss försöka köra en behållare med Ubuntu. Vi kommer inte att ange något arkiv och kommer att ladda ner den senaste officiella bilden som stöds av Canonical.

$ docker kör -it ubuntu root@d7402d1f7c54:/#

$ köra - det ubuntu

root @d7402d1f7c54 : / #

Förutom laget springa, angav vi två alternativ: -jag– behållaren ska starta i interaktivt läge och -t– en pseudoterminal måste tilldelas. Som du kan se från utdata har vi root-privilegier i behållaren, och behållar-ID visas som värdnamnet. Det senare kanske inte är sant för alla behållare och beror på behållarens utvecklare. Låt oss kontrollera att detta verkligen är en Ubuntu-miljö:

root@d7402d1f7c54:/# cat /etc/*release | grep DISTRIB_DESCRIPTION DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"

root @d7402d1f7c54 : / # cat /etc/*release | grep DISTRIB_DESCRIPTION

DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

kommandot uname -a Den kan inte användas för sådana ändamål, eftersom behållaren fungerar med värdkärnan.

Ett alternativ skulle vara att ange ett unikt behållarnamn som kan refereras till för bekvämlighet, förutom Behållar-ID. Det ges som -namn<имя>. Om alternativet utelämnas genereras namnet automatiskt.

Automatiskt genererade behållarnamn har ingen semantisk belastning, men som ett intressant faktum kan det noteras att namnen genereras slumpmässigt från ett adjektiv och namnet på en berömd vetenskapsman, uppfinnare eller hackare. I generatorkoden för varje namn kan du hitta en kort beskrivning av vad den givna figuren är känd för.

Du kan se listan över körande behållare med kommandot. För att göra detta, öppna en andra terminal:

Men om vi utfärdar kommandot kommer vi inte att hitta behållaren som skapats från mysql-avbildningen. Låt oss använda alternativet -a, som visar alla behållare, inte bara de som körs:

Uppenbarligen specificerades inte nödvändiga parametrar när behållaren startas. För en beskrivning av de miljövariabler som krävs för att köra en behållare, kan du hitta den officiella MySQL-avbildningen på Docker Hub. Låt oss försöka igen med alternativet -e, som ställer in miljövariablerna i behållaren:

$ docker run --name mysql-test ↵ -e MYSQL_ROOT_PASSWORD=docker -d mysql

Den sista parametern är kommandot som vi vill köra inuti behållaren. I det här fallet är det kommandotolken Våldsamt slag. alternativ -Det liknande i syfte de som användes tidigare i kommandot hamnarkörning.

Faktum är att efter att ha kört det här kommandot i behållaren mysql-test en annan process läggs till - våldsamt slag. Detta kan tydligt ses med hjälp av kommandot pstree. Förkortad utdata till ett kommando docker exec:

 Topp