Docker-afbeelding maken. Docker begrijpen. De belangrijkste componenten van Docker

Docker is het meest voorkomende containerisatiesysteem waarmee u de software die nodig is voor ontwikkeling in containers kunt uitvoeren zonder deze op het lokale systeem te installeren. In het kader van dit materiaal zullen we het beheer van dockercontainers analyseren.

Docker bestaat uit verschillende componenten:
  1. Afbeelding- een set software geconfigureerd door de ontwikkelaars, die is gedownload van de officiële website
  2. container- image-implementatie - een entiteit op de server die ervan is gemaakt, de container mag geen exacte kopie zijn en kan worden aangepast met Dockerfile
  3. Volume- het gebied op de schijf dat door de container wordt gebruikt en waarin de gegevens worden opgeslagen. Na het verwijderen van de container blijft de software niet achter, de gegevens kunnen in de toekomst worden gebruikt

Over de hele structuur wordt op een speciale manier een netwerk gebouwd, waarmee je poorten op de gewenste manier doorstuurt en de container van buitenaf toegankelijk maakt (standaard draait deze op een lokaal IP-adres) via een virtuele bridge. In dit geval kan de container zowel voor de wereld als voor één adres beschikbaar zijn.

Docker-containerbeheer: basismogelijkheden

Installeer Docker op de Ubuntu- of Debian-server als deze nog niet volgens de instructies is geïnstalleerd. Het is beter om opdrachten uit te voeren als een onbevoegde gebruiker via sudo

Het uitvoeren van de eenvoudigste container laat zien dat alles werkt

Basisopdrachten voor het beheren van containers

U kunt alle actieve containers op deze manier weergeven

Met de schakelaar -a worden alle containers weergegeven, ook inactieve

Dicker wijst willekeurig namen toe aan containers, indien nodig kunt u de naam rechtstreeks opgeven

docker run —name hello-world

Start een container met de naam my-linux-container op basis van de ubuntu-afbeelding en ga naar de containerconsole door de bash-shell op te geven

docker run -it —naam mijn-linux-container ubuntu bash

Om de container te verlaten en terug te keren naar de host, moet het systeem draaien

Alle afbeeldingen op basis waarvan containers worden gemaakt, worden automatisch gedownload van hub.docker.com wanneer de container voor het eerst wordt gemaakt. De afbeeldingen die al lokaal bestaan, kunnen worden bekeken door docker-afbeeldingen uit te voeren

Het maken van een container van een reeds gedownloade afbeelding zal veel sneller zijn (bijna onmiddellijk)

Wanneer u de container verlaat met exit, stopt deze, zodat dit niet gebeurt, u kunt afsluiten met de sneltoets CTRL + A + P

U kunt alle containers verwijderen die niet actief zijn

docker rm $ (docker ps -a -f status = verlaten -q)

Of verwijder ze een voor een

In plaats van een identifier in de laatste opdracht, kunt u een naam opgeven

In docker worden containers beheerd met een klein aantal intuïtieve opdrachten:

start-ID van docker-container

docker container stop-ID

docker container herstart ID

docker container inspecteren ID

Dit laatste is vooral handig, het toont alle informatie over de container, configuratiebestanden en gebruikte schijfpartities. De volledige lijst met opdrachten is eenvoudig te vinden in de help of op de officiële Docker-website.

Uw Docker-image bouwen en het Dockerfile gebruiken

Afbeeldingen worden meestal gemaakt van bestaande afbeeldingen met behulp van extra opties die zijn gespecificeerd in het Dockerbestand

VAN ubuntu
CMD-echo "hallo wereld"

Nu wordt er een nieuwe afbeelding gemaakt op basis van de standaard c ubuntu

Bouw de afbeelding op door deze een naam te geven (de punt aan het einde van de opdracht betekent dat de huidige map wordt gebruikt, en dus de Dockerfile erin)

docker build -t mijn-ubuntu.

docker-afbeeldingen wordt nu weergegeven en de nieuw gemaakte my-ubuntu-afbeelding

Het kan worden uitgevoerd en de console wordt weergegeven: Hallo Wereld en dit is het enige verschil met de standaardafbeelding

Meestal hebben we complexere regels nodig, we moeten bijvoorbeeld python3 in de afbeelding opnemen - laten we naar een nieuwe map gaan en een Dockerfile maken

VAN ubuntu
CMD apt-get update && apt-get install python3

Alle instructies zijn op één regel geschreven

docker build -t mijn-ubuntu-met-python3.

We starten de container door naar binnen te gaan

docker run -it my-ubuntu-with-python3 bash

Binnenin, als root, moet je uitvoeren dpkg -l | grep python3, zal het commando laten zien dat het pakket aanwezig is in het systeem, wat succes betekent

Het feit dat Docker echt een onmisbare tool is voor een ontwikkelaar en beheerder van elk groot project. Maar zelfs als dit niet het geval is, moet Docker het nog weten: in de zeer nabije toekomst zal het overal zijn, van een desktop Linux-distributie tot een pool van servers op AWS. En het beste is dat het omgaan met Docker vrij eenvoudig is, als je natuurlijk begrijpt hoe het correct werkt.

Apt-get in de wereld van virtuele omgevingen

Docker is gebaseerd op namespaces en cgroup-technologieën (de eerste biedt isolatie, de tweede biedt procesgroepering en resourcebeperking), daarom verschilt het qua virtualisatie niet veel van de LXC / OpenVZ die we gewend zijn, en er is geen veel om over te praten hier. Dezelfde native snelheid, dezelfde isolatiemethoden op basis van Linux-kernelmechanismen. Hierboven begint echter een heel ander verhaal. Het hoogtepunt van Docker is dat je hiermee een volwaardige virtuele omgeving kunt implementeren en er een applicatie in kunt starten, net zo eenvoudig als bijvoorbeeld het herstarten van een webserver.

We abstraheren van de details van specifieke distributies en stellen ons voor dat we een pure CentOS hebben en dat we een specifieke opdracht daarin willen uitvoeren in een volledig virtuele omgeving zonder toegang tot het hoofdsysteem. Moet u afbeeldingen van distributies downloaden, deze op het systeem implementeren en een virtuele omgeving opzetten? Helemaal niet, u hoeft alleen maar twee opdrachten uit te voeren:

$ sudo yum install docker-io $ sudo docker run -t ubuntu: laatste / usr / bin / top

En het is alles. We hebben zojuist het bovenste hulpprogramma in een container uitgevoerd met een omgeving die is gebaseerd op de nieuwste Ubuntu-versie die momenteel beschikbaar is, waarbij informatie wordt uitgevoerd naar de huidige terminal. En dit alles met één simpele opdracht (installatie telt niet). Niet slecht, toch? Over het algemeen kunnen we zelfs in deze container "gaan" en alles doen wat normaal gesproken wordt gedaan met een vers geïnstalleerd systeem:

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

Zoals u kunt zien, is alles ook in orde met het netwerk, dus we kunnen het systeem bijwerken, alle software installeren en configureren. Het lijkt een beetje op magie, maar het is eigenlijk heel eenvoudig. Docker is een soort apt-get in de wereld van containers, alleen in plaats van pakketten zijn er bestandssysteemafbeeldingen en in plaats van de officiële Debian / Ubuntu-repositories is er een cloudopslag genaamd Docker Hub.

Toen we "docker run ..." deden, deed het systeem het volgende:

  1. Het docker-hulpprogramma nam contact op met de dockerd-daemon op onze lokale computer, zei hallo van ons en vroeg om de nieuwste versie van Ubuntu (zoals aangegeven door de laatste tag in de opdracht) in een geïsoleerde container te draaien.
  2. De dockerd-daemon controleerde zijn notebook, ging naar de map / var / lib / docker en ontdekte dat de image van het bestandssysteem van de nieuwste Ubuntu niet op onze computer staat, dus besloot hij contact op te nemen met de Docker Hub om erachter te komen of er staat daar zo'n beeld.
  3. Nadat hij met Docker Hub had gesproken, zorgde hij ervoor dat de afbeelding nog steeds bestaat en vroeg hij deze naar ons te sturen.
  4. Nadat hij de gewenste afbeelding had ontvangen, koppelde dockerd zijn bestandssysteem aan, maakte er een chroot in en voerde de opdracht uit die in het laatste argument was gespecificeerd, waarbij de "scope" werd beperkt met behulp van naamruimten (in feite sneed het de toegang tot het hoofdbestandssysteem, host systeemprocessen, IPC en andere , opgesloten in de sandbox), maar gooide de apparaatbestanden van de huidige terminal erin (de -t-vlag) zodat onze top zijn pseudo-grafische interface kan tekenen.

Het hoogtepunt van dit model is dat Docker Hub voor iedereen toegankelijk is en dat iedereen zijn eigen afbeelding kan voorbereiden (daarover later meer) en deze kan publiceren voor installatie op een andere machine en/of door een andere persoon. Op het moment van schrijven zijn er meer dan 45 duizend afbeeldingen gepubliceerd op de Docker Hub voor alle gelegenheden, van afbeeldingen van "naakte" distributies tot afbeeldingen met vooraf geconfigureerde server- en desktopapplicaties die draaien in een minimalistische Linux-omgeving.

Wat als we Firefox in een virtuele omgeving willen gebruiken? Het kan niet eenvoudiger, open Docker Hub in een browser, klik op Bladeren en zoeken en typ firefox in. Er verschijnt een lijst met resultaten op het scherm. We kijken, kennethkl / firefox lijkt best geschikt. We klikken erop en zien informatie over hoe het hele ding te starten. De auteur vertelt ons om een ​​commando als dit uit te voeren:

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

Laten we proberen. Ja inderdaad, na een korte download van de afbeelding krijgen we standaard Firefox op het scherm. Trouwens, aan de hand van hetzelfde voorbeeld kunt u vertrouwd raken met vier meer handige opties van de opdracht docker run:

  • -d - "daemoniseert" de container, dat wil zeggen, het koppelt Docker eenvoudig los van de virtuele STDOUT-omgeving en laat het op de achtergrond draaien;
  • --name - de naam van de container, die deze zal ontvangen in plaats van de identifier;
  • -e - hiermee kunt u een omgevingsvariabele "doorsturen" naar de virtuele machine;
  • -v - stuurt het gespecificeerde bestand of directory door (format / file / on / host / system: / file / in / virtual machine of gewoon / file / on / host / system, als de paden overeenkomen).

In dit geval zijn de variabele en het bestand nodig zodat Firefox toegang heeft tot de weergave van de lokale machine. Dit is nogal onveilig, aangezien elk proces in de container niet alleen software op uw bureaublad kan uitvoeren, maar bijvoorbeeld ook toetsaanslagen of cursorbewegingen kan onderscheppen. Maar het zal bijvoorbeeld wel lukken.

Er is een eenvoudigere manier om Docker-afbeeldingen te vinden met behulp van de docker-zoekopdracht:

$ sudo docker zoeken nginx

INFO

Elke Docker-gebruiker kan zijn eigen privéhub gebruiken. Het wordt het "register" genoemd en is beschikbaar als een kant-en-klaar image. Het enige wat u hoeft te doen is het gewoon uit te voeren: docker run -p 5555: 5555 registry.

De Docker-daemon is niet alleen beschikbaar met behulp van de client, maar ook met behulp van de RESTful API, zowel lokaal als vanaf een externe machine. De standaard Docker-poorten zijn tcp / 2375 en tcp / 2376.

De Docker-image hoeft niet onmiddellijk na het downloaden te worden uitgevoerd, u kunt deze eerst downloaden naar uw lokale computer met behulp van het docker pull-commando en pas daarna uitvoeren: docker pull ubuntu.

Gelaagde taart

Docker stelt u in staat om het werken met virtuele omgevingen zo gemakkelijk mogelijk te maken, zowel het proces van het implementeren van omgevingen als het opzetten van hun interactie met het hostsysteem (wat slechts het laatste voorbeeld is). Maar dit is niet het enige hoogtepunt.

Als je al met de Ubuntu-afbeelding uit de eerste twee voorbeelden hebt gespeeld, heb je waarschijnlijk gemerkt dat elke nieuwe lancering van de container helemaal opnieuw gebeurt en dat alle wijzigingen die in de vorige sessie zijn aangebracht, verloren gaan. Dit is helemaal geen bug, het is een van de belangrijkste kenmerken van de Docker-architectuur die het een nog interessantere en aantrekkelijkere oplossing maakt.

Het feit is dat in de overgrote meerderheid van de gevallen de "Docker-image" helemaal geen monolithische image van het bestandssysteem is, maar een soort laagcake, bestaande uit verschillende bestandssysteem-images, op basis waarvan de container wordt gevormd. Tegelijkertijd zijn individuele FS-images helemaal niet verantwoordelijk voor bepaalde delen van de directorystructuur (zoals bijvoorbeeld in het geval van het partitioneren van een schijf onder Linux in partities / home, / var, / boot), maar zijn ze gelaagd op elkaar met behulp van het AUFS-kernelmechanisme Linux (er is ook ondersteuning voor dezelfde functionaliteit door het gebruik van btrfs, device mapper en overlay).

Om te begrijpen hoe dit werkt, gaan we terug naar onze gecontaineriseerde Ubuntu. We starten de container en installeren nginx, zoals weergegeven in het tweede voorbeeld aan het begin van het artikel, maar beëindigen deze niet. In plaats daarvan lanceren we een andere terminal en zien we de lijst met actieve containers:

$ sudo docker ps

Deze opdracht toont alle actieve containers samen met hun ID, gebruikte afbeelding, gestarte opdracht, uptime en meer. We zijn geïnteresseerd in de waarde in de kolom CONTEINER ID. Kopieer het en voer de volgende opdracht uit:

$ sudo docker commit container-ID ubuntu-nginx

Nadat het is voltooid, kunt u de container verlaten, waardoor het werk wordt beëindigd. En dan starten we gewoon de ubuntu-nginx-container en zien dat nginx nergens is verdwenen en op zijn plaats staat:

$ sudo docker run -i -t ubuntu-nginx / bin / bash # welke nginx / usr / sbin / nginx

Wat hebben we gedaan? We hebben nog een laag gemaakt, dat wil zeggen een extra FS-image, en een nieuwe Docker-image gegenereerd op basis van de reeds bestaande Ubuntu Docker-image, inclusief onze FS-image, die nginx bevat. Klinkt een beetje verwarrend, toch? Het is eigenlijk vrij eenvoudig.

We hebben al ontdekt dat elke Docker-afbeelding uit verschillende bestandssysteemafbeeldingen bestaat. Wanneer we de container starten, worden deze afbeeldingen gemount en geassembleerd in één directorystructuur met behulp van AUFS. De eerste afbeelding kan bijvoorbeeld alleen een basisinstallatie van Ubuntu bevatten, de tweede voegt er een set standaarddaemons aan toe, de derde - beheerhulpprogramma's, enzovoort. Docker koppelt alle lagen in alleen-lezen modus, maar zodat we de inhoud van de afbeelding kunnen wijzigen, wordt er nog een, aanvankelijk lege laag bovenop aangesloten in lees/schrijfmodus.


Nadat de container is voltooid (wat gebeurt nadat het laatste proces erin is uitgevoerd), wordt standaard de laatste laag gewist en gaan al onze wijzigingen verloren. Met behulp van de opdracht docker commit kunnen we de wijzigingen echter "vastleggen" door een nieuwe Docker-afbeelding te maken op basis van de bestaande FS-afbeeldingen plus de FS-afbeelding met onze wijzigingen. Hiermee worden de door ons aangebrachte wijzigingen opgeslagen. Optioneel kunnen we de ubuntu-nginx-container starten, er wijzigingen in aanbrengen en op dezelfde manier opslaan in een nieuwe Docker-afbeelding met behulp van commit, en een nieuwe laag toevoegen. U kunt de opdracht docker-afbeeldingen gebruiken om een ​​lijst te zien van alle resulterende afbeeldingen (en van Docker Hub), en de opdracht docker-geschiedenis om de geschiedenis van laagvorming te bekijken:

$ sudo docker geschiedenis ubuntu-nginx

Deze benadering van imaging biedt meer flexibiliteit in containerbeheer, bespaart veel tijd en stelt u in staat om reeds geconfigureerde Docker-images gemakkelijk tussen machines over te dragen (de image kan worden geüpload naar Docker Hub en vervolgens op een andere machine worden geïmplementeerd). Een minder voor de hand liggend pluspunt is de besparing van schijfruimte. Als we op een machine een hele dierentuin aan containers inzetten, die elk in eerste instantie gebaseerd zullen zijn op één basisimage (dezelfde Ubuntu bijvoorbeeld) - ze zullen allemaal verwijzen naar deze basisimage en niet de inhoud ervan dupliceren.


Docker buiten Linux

De enige manier om Docker op OS X of Windows uit te voeren, is door het op een virtuele machine te installeren. Je hoeft het niet handmatig te doen, je kunt een kant-en-klare oplossing gebruiken, bijvoorbeeld boot2docker. Dit is een set scripts waarmee u snel een virtuele Linux- en Docker-machine in VirtualBox kunt implementeren en deze kunt opstarten met automatische SSH-toegang. Instructies voor het gebruik ervan en het installatieprogramma zelf zijn te vinden op de officiële Docker-website.

Netwerk configuratie

Om containers met elkaar en met de buitenwereld te laten communiceren, heft Docker automatisch de virtuele netwerkbrug op en configureert masquerading (NAT) regels voor de externe netwerkinterface. Dit betekent dat het niet mogelijk zal zijn om de containers van buitenaf te bereiken. We kunnen port forwarding echter zo configureren dat een verzoek naar specifieke poorten op de externe netwerkinterface van de machine automatisch wordt doorgestuurd naar de opgegeven containerpoorten. Bij Mirantis draait het belangrijkste Fuel-knooppunt (dit is de GUI voor het implementeren en configureren van OpenStack) bijvoorbeeld in Docker en gebruikt het port forwarding om toegang te krijgen tot de ful / nginx-container (poort 8000):

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

We zouden poort 8000 kunnen doorsturen naar een andere poort van de container door simpelweg het tweede nummer in de -p optie te veranderen, maar dit heeft geen zin in deze configuratie.

Bestanden doorsturen en Dockerfile

Aan het begin van het artikel maakten we al kennis met de vlag -v, waarmee je elk bestand of elke map van het hostsysteem naar de container kunt doorsturen. Dit is een erg handige functie, het kan zowel worden gebruikt voor het opslaan van tijdelijke gegevens als voor het delen van bestanden tussen verschillende containers. In Mirantis wordt deze functie gebruikt om configuratiebestanden voor de Fuel / astute-service (/ etc / astute) in de container door te sturen:

$ sudo docker run -d -v / etc / slimme brandstof / astute_6.0: laatste /usr/local/bin/start.sh

Hetzelfde kan gedaan worden met de opdracht VOLUME in de Dockerfile. De Dockerfile zelf is het lokale equivalent van de Makefile, maar als de laatste bedoeld is voor het bouwen van applicaties vanaf de bron, dan kun je met de Dockerfile afbeeldingen bouwen voor Docker. Het doel is om het maken van nieuwe afbeeldingen te vereenvoudigen zonder de noodzaak om een ​​container te starten, er bewerkingen in uit te voeren en een commit uit te voeren. Je kunt gewoon een Dockerfile schrijven en Docker doet alles voor je. Overweeg bijvoorbeeld de Dockerfile voor het bouwen van Fuel / scherpzinnig:

VAN brandstof / centen ONDERHOUDER Matthew Mosesohn [e-mail beveiligd] RUN 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 RUN marionet toepassen --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/astute-only.pp; [[$? == 0 || $? == 2]] RUN chmod + x /usr/local/bin/start.sh; \ echo -e "\ nname = Nailgun Local Repo \ nbaseurl = bestand: / var / www / nailgun / centos / x86_64 \ ngpgcheck = 0 "> /etc/yum.repos.d/nailgun.repo; yum schoon alles VOLUME / etc / scherpzinnige CMD /usr/local/bin/start.sh

Het is niet moeilijk te begrijpen waarvoor het dient. Het maakt een afbeelding op basis van brandstof / centos, voert verschillende opdrachten uit om de afbeelding voor te bereiden, voegt bestanden uit de huidige map toe aan de afbeelding, past het Puppet-manifest toe, wijzigt machtigingen voor sommige bestanden, stuurt de / etc / asture / map door van de host system naar de container en start de container met het commando /usr/local/bin/start.sh.

Om een ​​container te bouwen, plaatst u het Dockerfile en alle bestanden die eraan worden toegevoegd in een map en voert u de volgende opdracht uit:

$ sudo docker build brandstof / astute_6.0: laatste

In dit geval hebben we gekozen voor de naam fuel / astute_6.0: nieuwste, al kan het van alles zijn.

Nuances van werken met Docker

Docker is gebouwd rond het idee dat er slechts één service in elke container zou moeten draaien. Je verpakt Apache, MySQL, nginx, Varnish en alles wat je project nodig heeft in verschillende containers en gebruikt vervolgens Docker om alles samen te bouwen. Deze aanpak biedt een grote flexibiliteit omdat u hiermee eenvoudig de configuratie kunt wijzigen, updates kunt testen en afzonderlijke services naar andere machines kunt migreren.

Om dezelfde reden is het niet gebruikelijk om Docker te gebruiken om volwaardige Linux-omgevingen te draaien met een init-daemon, cron- en syslog-daemons en andere standaarddistributiecomponenten. In plaats daarvan starten we gewoon de service die we nodig hebben, en deze draait helemaal alleen in een virtuele omgeving:

$ sudo docker run -d -p 80 ubuntu-nginx / usr / sbin / nginx

Maar hier is een klein probleempje. Docker sluit de container onmiddellijk af nadat het proces dat erin wordt uitgevoerd (in dit geval nginx) is beëindigd, en aangezien nginx standaard is gedemoniseerd, vorkt het een nieuw proces en beëindigt het degene die we met de hand hebben gestart, dan Docker verlaat onmiddellijk en een container door een gevorkte Docker vast te spijkeren.

In het geval van nginx kun je dit probleem omzeilen door daemon toe te voegen; de eerste regel in zijn config. Andere daemons hebben hun eigen instellingen nodig, en van sommige kan worden voorkomen dat ze rechtstreeks vanaf de opdrachtregel worden gedemoniseerd. Sshd levert hiervoor bijvoorbeeld de vlag -D:

$ sudo docker run -d -p 22 ubuntu-ssh / usr / sbin / sshd -D

U kunt op elk moment verbinding maken met de container met behulp van de opdracht docker exec om de logboeken te bekijken of de instellingen te wijzigen (hierna is de container-ID ofwel de ID die kan worden gezien in de docker ps-uitvoer, of de naam die is opgegeven bij opstarten in de --name optie ):

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

Maar er is ook een klein probleempje hier. Zoals we weten, gaat alle informatie die is verzameld tijdens de werking van de virtuele omgeving verloren als we het werk van de virtuele omgeving beëindigen, en daarmee verdwijnen de logboeken en wijzigingen in de instellingen. We kunnen ook niet eindeloos lagen maken (al was het maar omdat het er niet meer dan 127 kunnen zijn), maar we kunnen een iets ander pad nemen en het logaggregatiesysteem gebruiken dat in Docker is ingebouwd. Docker kan natuurlijk geen logs van individuele applicaties verzamelen, maar het kan wel STDOUT-uitvoer verzamelen, dat wil zeggen elke console-uitvoer. Het enige dat ons nog rest, is om de nginx-configuratie te wijzigen zodat de logs in / dev / stdout worden gegoten, en ze vervolgens te bekijken met de opdracht docker logs:

$ sudo docker logt container-ID

Een andere en meer correcte optie is om de logs (en, indien nodig, instellingen) eenvoudig naar het hostsysteem te verplaatsen met behulp van de al beschreven -v-optie:

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

Indien nodig kan de container correct worden gestopt door de service die erin draait te beëindigen met behulp van het docker stop-commando:

$ sudo docker stop container-ID

En als het om de een of andere reden niet goed werkt, kun je het doden met kill:

$ sudo docker kill container-ID

Wanneer je dit doet, gebeurt er één belangrijk ding dat veel nieuwelingen vergeten: Docker bewaart meta-informatie over de container. In feite betekent dit dat als je bijvoorbeeld nginx start en de naam opgeeft met behulp van de argumenten van de opdracht docker run, mappen die moeten worden doorgegeven aan de container, poorten, omgevingsvariabelen en dergelijke, al deze informatie wordt opgeslagen wanneer de container eindigt en om het de volgende keer uit te voeren, hoeft u het niet op te geven, maar voert u gewoon de volgende opdracht uit (u kunt een naam gebruiken in plaats van ID):

$ sudo docker start container-ID

Als u de status niet hoeft op te slaan (bijvoorbeeld voor het testen of controleren van bepaalde functionaliteit), kunt u de vlag --rm gebruiken, die Docker dwingt om de container volledig te vernietigen nadat deze is voltooid (de afbeelding opslaan):

$ sudo docker run --rm -i -t busybox / bin / bash

U kunt alle eerder opgeslagen containers vernietigen met het volgende commando:

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

Docker kan containers onafhankelijk opnieuw opstarten als ze crashen en zelfs starten tijdens het opstarten van het systeem. Het enige dat u hoeft te doen, is de optie --restart gebruiken:

$ sudo docker run --restart = altijd \ -d -v / root / logs: / var / logs -p 80 \ ubuntu-nginx / usr / sbin / nginx

De afbeelding kan op elk moment worden geëxporteerd naar een enkel bestand en vervolgens worden geïmporteerd op een andere machine. Hiervoor zijn de commando's docker save en docker restore voorzien. Het is heel gemakkelijk om ze te gebruiken, het exporteren gaat als volgt:

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

En de import is als volgt:

$ sudo docker load -i ubuntu-nginx.img

conclusies

Docker is een uitstekende tool. Voor een niet-ingewijd persoon lijkt het misschien speelgoed dat niet langer geschikt is voor iets anders dan het uitvoeren van software in een sandbox, maar het kan helpen bij het oplossen van een enorm scala aan taken, waarover we in het volgende artikel zullen praten.

Docker-voordelen ten opzichte van LXC, OpenVZ en andere virtualisatie-oplossingen op OS-niveau

  1. Docker gebruikt een draagbaar generiek beeldformaat. Dit betekent dat deze afbeeldingen probleemloos naar een andere machine kunnen worden overgebracht en gedeeld voor gebruik door andere gebruikers.
  2. De afbeelding kan als basis dienen voor andere afbeeldingen. In Docker wordt het als normaal beschouwd om meerdere lagen te gebruiken om de uiteindelijke afbeelding te vormen. U kunt beginnen met een basis Ubuntu-image en vervolgens Apache 2.4 toevoegen om een ​​Ubuntu + Apache-microservice te maken.
  3. Wanneer u zich commit, kan de afbeelding worden geversied, net als in GIT.
  4. Docker heeft een grote community en een uitgebreid ecosysteem met een aanzienlijk aantal tools voor het schalen, groeperen, bewaken, implementeren en beheren van containers.

We hebben het onderwerp meer dan eens aangeroerd en hebben veel systemen overwogen voor hun constructie. Vandaag introduceren we weer een geweldig systeem met Docker containers.

Laten we beginnen met het beschrijven van de basisfunctionaliteit die van pas zal komen in andere artikelen in de serie, en herinneren ons kort de Docker-architectuur. Docker gebruikt een client-server-architectuur en bestaat uit een client-docker-hulpprogramma dat toegang heeft tot de server met behulp van: REST-API, en een daemon in het Linux-besturingssysteem (zie Fig. 1). Hoewel Docker op niet-Linux-besturingssystemen werkt, worden ze in dit artikel niet behandeld.

De belangrijkste onderdelen van Docker:
    • containers- gebruikersomgevingen geïsoleerd met behulp van besturingssysteemtechnologieën, waarin applicaties worden uitgevoerd. De eenvoudigste manier is om een ​​Docker-container te definiëren als een toepassing die wordt gestart vanuit een afbeelding. Dit is overigens precies waar Docker ideologisch van verschilt, bijvoorbeeld van LXC ( Linux-containers), hoewel ze dezelfde Linux-kerneltechnologieën gebruiken. De ontwikkelaars van het Docker-project houden vast aan het principe dat één container één applicatie is.
    • Afbeeldingen- alleen-lezen applicatiesjablonen. Er kunnen nieuwe niveaus worden toegevoegd bovenop bestaande afbeeldingen, die samen het bestandssysteem vertegenwoordigen en het vorige niveau wijzigen of aanvullen. Gewoonlijk wordt een nieuwe afbeelding gemaakt door ofwel een reeds actieve container op te slaan in een nieuwe afbeelding over een bestaande, of door speciale instructies voor het hulpprogramma te gebruiken. Om de verschillende niveaus van een container op bestandssysteemniveau te scheiden, AUFS, btrfs, vfs en Device Mapper... Als u Docker wilt gebruiken in combinatie met: SELinux, dan is het verplicht Apparaattoewijzer.
    • registers met opslagplaatsen ( opslagplaats) afbeeldingen, - netwerkbeeldopslag. Ze kunnen zowel privé als openbaar zijn. Het bekendste register is.

GNU/Linux-besturingssystemen gebruiken standaard Linux-kerneltechnologieën om containers te isoleren, zoals:
  • Naamruimten ( Linux-naamruimten).
  • Controle groepen ( Cgroepen).
  • Hulpprogramma's voor privilegebeheer ( Linux-mogelijkheden).
  • Aanvullende, verplichte beveiligingssystemen, zoals: AppArmor of SELinux.

Laten we de vermelde technologieën in wat meer detail bekijken.

Controlegroepmechanisme (C-groepen) biedt een hulpmiddel voor het verfijnen van de toewijzing, prioritering en het beheer van systeembronnen. Stuurgroepen zijn geïmplementeerd in de Linux-kernel. In moderne distributies wordt stuurgroepbeheer geïmplementeerd via: systemd, het blijft echter mogelijk om te besturen met behulp van de bibliotheek libcgroep en nutsvoorzieningen cgconfig... De belangrijkste cgroup-hiërarchieën (ook wel controllers genoemd) worden hieronder vermeld:

  • blkio- stelt limieten in voor input-output operaties en voor toegang tot block devices;
  • CPU- verdeelt de processortijd over de taken met behulp van de procesplanner;
  • cpuacct- Genereert automatische rapporten over het gebruik van CPU-bronnen. Werkt in combinatie met de controller CPU hierboven omschreven;
  • cpuset- wijst bepaalde processors en geheugenknooppunten toe aan taken;
  • apparaten- regelt de toegang van taken tot specifieke apparaten;
  • diepvries- taken opschort of hervat;
  • geheugen- stelt limieten in en genereert rapporten over geheugengebruik door taken van de controlegroep;
  • net_cls- voert het taggen van netwerkpakketten uit met een class-identifier ( klassikaal). Hierdoor kan de verkeersleider ( tc commando) en firewall ( iptables) rekening houden met deze tags bij het verwerken van verkeer;
  • perf_event- hiermee kunt u controlegroepen bewaken met behulp van het hulpprogramma perf;
  • enormtlb- hiermee kunt u grote virtuele geheugenpagina's gebruiken en er limieten op toepassen.

naamruimten, op hun beurt controleren ze niet de toewijzing van middelen, maar de toegang tot kerneldatastructuren. In feite betekent dit de isolatie van processen van elkaar en de mogelijkheid om parallel "identieke", maar niet overlappende hiërarchieën van processen, gebruikers en netwerkinterfaces te hebben. Indien gewenst kunnen verschillende diensten zelfs hun eigen hebben loopback-interfaces.

Voorbeelden van naamruimten die door Docker worden gebruikt:
  • PID, proces-ID- isolatie van de hiërarchie van processen.
  • NET, Netwerken- isolatie van netwerkinterfaces.
  • PC, InterProcess-communicatie- beheer van interactie tussen processen.
  • MNT, Mount- beheer van punten.
  • UTS, Unix Timesharing-systeem- isolatie van de kernel en versie-ID's.

Een mechanisme genaamd Mogelijkheden stelt u in staat om de privileges van de rootgebruiker te splitsen in kleine groepen privileges en deze afzonderlijk toe te wijzen. Deze functionaliteit is sinds versie in GNU / Linux verschenen kernen 2.2. In eerste instantie worden containers gestart met een beperkte set privileges.

U kunt de docker-opdrachtopties in- en uitschakelen:
  • mount operaties;
  • toegang tot stopcontacten;
  • Sommige bewerkingen op het bestandssysteem uitvoeren, zoals het wijzigen van de kenmerken van bestanden of de eigenaar.

U kunt meer leren over de privileges met behulp van de man-pagina. MOGELIJKHEDEN (7).

Docker installeren

Laten we eens kijken naar het installeren van Docker met CentOS als voorbeeld. Als je met CentOS werkt, heb je de keuze: gebruik de nieuwste versie van u pstream of een versie gebouwd door het CentOS-project met Red Hat-add-ons. Een beschrijving van de wijzigingen vindt u op de pagina.

In feite is dit een omgekeerde overdracht van fixes van nieuwe upstream-versies en wijzigingen voorgesteld door de Red Hat-ontwikkelaars, maar nog niet geaccepteerd in de hoofdcode. Het meest opvallende verschil op het moment van schrijven was dat in nieuwere versies de docker-service in drie delen is opgesplitst: een daemon docker, containerd en runc... Red Hat beschouwt deze wijziging nog niet als stabiel en levert een monolithische versie 1.10 uitvoerbaar.

Repository-instellingen voor installatie upstream-versies, evenals instructies voor installatie op andere distributies en besturingssystemen, worden gegeven in de installatiegids op de officiële website. In het bijzonder de instellingen voor de CentOS 7-repository:

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

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

naam = Opslagplaats

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

ingeschakeld = 1

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

Installeer de vereiste pakketten op en start en schakel de service in:

# yum install -y docker-engine # systemctl start docker.service # systemctl activeer docker.service

# yum install -y docker-engine

# systemctl start docker.service

# systemctl docker.service inschakelen

De servicestatus controleren:

# systemctl status docker.service

# systemctl status docker.service

U kunt ook systeeminformatie over Docker en de omgeving bekijken:

# havenarbeider info

Als u een vergelijkbare opdracht uitvoert en Docker installeert vanuit de CentOS-repositories, ziet u kleine verschillen vanwege het gebruik van een oudere versie van de software. Van de uitgang havenarbeider info we kunnen achterhalen wat wordt gebruikt als stuurprogramma voor het opslaan van gegevens Toewijzing apparaat, en als opslag - een bestand in / var / lib / docker /:

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

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

Rw - - - -. 1 root root 100G 27 december 12:00 / var / lib / / devicemapper / devicemapper / data

De opstartopties van de daemon, zoals meestal het geval is op CentOS, worden opgeslagen in / etc / sysconfig /... In dit geval de naam van het docker-bestand. Overeenkomstige regel: / etc / sysconfig / docker opties beschrijven:

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

Als u de opdracht docker uitvoert als een niet-rootgebruiker of als lid van de docker-groep, ziet u een foutmelding als deze:

$ docker zoeken mysql

$ zoek mysql

Waarschuwing: kan het standaard register-eindpunt van daemon niet ophalen (kan geen verbinding maken met de Docker-daemon. Draait de docker-daemon op deze host?). Systeemstandaard gebruiken: https: // index. docker.io/v1/

Kan geen verbinding maken met de Docker-daemon. Draait de docker-daemon op deze host?

Merk op dat het daadwerkelijk toevoegen van een gebruiker aan de dockergroep gelijk staat aan het toevoegen van die gebruiker aan de rootgroep.

De RHEL/CentOS-ontwikkelaars hebben een iets andere benadering van Docker-daemonbeveiliging dan de upstream Docker-ontwikkelaars zelf. Zie een artikel van RHEL-ontwikkelaar Dan Walsh voor meer informatie over de aanpak van Red Hat.

Als u het "standaard" gedrag van Docker wilt installeren vanuit de CentOS-repositories (dat wil zeggen, beschreven in de officiële documentatie), dan moet u een docker-groep maken en toevoegen aan de daemon-startopties:

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

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

Vervolgens herstarten we de service en controleren of het docker-socketbestand tot de docker-groep behoort, en niet root:

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

Afbeeldingen en Docker-tags zoeken

Laten we proberen een container te vinden op Docker Hub.

$ docker zoeken haproxy

$ zoek haproxy


In deze uitvoer hebben we een lijst met een aantal HA Proxy-afbeeldingen verkregen. Het bovenste item in de lijst is de HA-proxy uit de officiële repository. Dergelijke afbeeldingen verschillen doordat er geen symbool in de naam staat «/» de naam van de repository van de gebruiker scheiden van de naam van de container zelf. Het voorbeeld achter de official toont twee haproxy-afbeeldingen van open gebruikersrepositories eeacms en miljoen12.

Afbeeldingen zoals de twee hieronder kunt u zelf maken door u te registreren op Docker Hub. De officiële worden ondersteund door een toegewijd team gesponsord door Docker, Inc. Kenmerken van de officiële repository:

  • Dit zijn aanbevolen afbeeldingen voor gebruik, gebaseerd op best practices en best practices.
  • Het zijn basisafbeeldingen die een startpunt kunnen zijn voor meer maatwerk. Bijvoorbeeld basisimages van Ubuntu, CentOS of bibliotheken en ontwikkelomgevingen.
  • Bevat de nieuwste softwareversies met vaste kwetsbaarheden.
  • Dit is het officiële distributiekanaal voor de producten. Als u alleen naar officiële afbeeldingen wilt zoeken, kunt u de optie gebruiken: –Filter “is-officieel = waar” commando's havenarbeider zoeken.

Sterren in opdrachtuitvoer havenarbeider zoeken komt overeen met de populariteit van het beeld. Dit is de analoog van de knop Leuk vinden op sociale netwerken of bookmarks voor andere gebruikers. Geautomatiseerd betekent dat de afbeelding automatisch wordt opgebouwd vanuit een aangepast script met Docker Hub. Gewoonlijk moet u de voorkeur geven aan automatisch verzamelde afbeeldingen omdat de inhoud ervan kan worden gecontroleerd door bekendheid met het bijbehorende bestand.

Download de officiële HA Proxy-afbeelding:

$ docker pull haproxy Standaardtag gebruiken: nieuwste

De volledige naam van de afbeelding kan er als volgt uitzien:

[gebruikersnaam] afbeeldingsnaam [: tag]

U kunt de lijst met gedownloade afbeeldingen bekijken met het commando docker-afbeeldingen:

Lancering van containers

Het is niet nodig om de afbeelding te downloaden om de container uit te voeren. Indien beschikbaar, wordt deze automatisch geladen. Laten we proberen een container te starten met Ubuntu. We zullen de repository niet vermelden en zullen de nieuwste officiële afbeelding downloaden die wordt ondersteund door Canonical.

$ docker run -it ubuntu [e-mail beveiligd]:/#

$ uitvoeren - het ubuntu

wortel @ d7402d1f7c54: / #

Naast het team loop, hebben we twee opties gespecificeerd: -I- de container moet interactief draaien en -t- een pseudo-terminal moet worden gemarkeerd. Zoals je aan de output kunt zien, hebben we root-gebruikersrechten in de container en wordt de container-ID weergegeven als de hostnaam. Dit laatste geldt mogelijk niet voor alle containers en is afhankelijk van de containerontwikkelaar. Laten we eens kijken of dit inderdaad de Ubuntu-omgeving is:

[e-mail beveiligd]: / # cat / etc / * release | grep DISTRIB_DESCRIPTION DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

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

DISTRIB_DESCRIPTION = "Ubuntu 16.04.1 LTS"

Uname-opdracht -een voor dergelijke doeleinden zal het niet werken, omdat de container met de host-kernel werkt.

Een van de opties kan een unieke containernaam zijn waarnaar voor het gemak kan worden verwezen, naast: Container-ID. Het wordt gegeven als -Naam<имя>. Als de optie wordt weggelaten, wordt de naam automatisch gegenereerd.

De automatisch gegenereerde containernamen hebben geen semantische lading, maar als interessant feit kan worden opgemerkt dat de namen willekeurig worden gegenereerd uit het bijvoeglijk naamwoord en de naam van een beroemde wetenschapper, uitvinder of hacker. In de generatorcode vindt u voor elke naam een ​​korte beschrijving van waar het gegeven cijfer om bekend staat.

U kunt de lijst met actieve containers bekijken met de opdracht. Open hiervoor een tweede terminal:

Als we de opdracht echter geven, zullen we de container die is gemaakt op basis van de mysql-afbeelding niet vinden. Laten we de optie gebruiken -een die alle containers toont, niet alleen actieve containers:

Het is duidelijk dat de vereiste parameters niet zijn opgegeven bij het starten van de container. Zie de officiële MySQL-image op Docker Hub voor een beschrijving van de omgevingsvariabelen die nodig zijn om een ​​container uit te voeren. Laten we het opnieuw proberen met behulp van de optie -e die de omgevingsvariabelen in de container instelt:

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

De laatste parameter is de opdracht die we in de container willen uitvoeren. In dit geval is dit de opdrachtinterpreter. bash... Opties -het zijn qua doel vergelijkbaar met die eerder in de opdracht zijn gebruikt havenarbeider rennen.

In feite na het uitvoeren van deze opdracht in container mysql-test nog een proces is toegevoegd - bash... Dit is duidelijk te zien met behulp van het pstree-commando. Afgekorte output naar commando docker-exec: