Als je een developer of engineer bent, is de kans groot dat je op zijn minst gehoord hebt van Docker: een handig hulpmiddel voor het verpakken, verzenden en runnen van applicaties in ‘containers’.
Ongeacht of je een onmiddellijke toepassing voor Docker in gedachten hebt, is het belangrijk om een aantal fundamentele concepten te begrijpen rondom ‘containers’ en hoe dit zich verhoudt tot een Virtuele Machine (VM).
VM’s en Containers zijn gelijkwaardig in hun doel: het isoleren van een applicatie en haar afhankelijkheden in een zelfstandige unit die overal kan draaien. Daarnaast maken containers en VM’s de noodzaak van fysieke hardware overbodig, waardoor computerresources efficiënter benut kunnen worden.
Docker oogt in eerste instantie weliswaar op een virtuele machine, maar de functionaliteiten zijn niet hetzelfde. Anders dan Docker bevat een virtuele machine een compleet besturingssysteem. Het functioneert onafhankelijk en gedraagt zich als een computer. Docker deelt enkel de resources van de hostmachine om zijn omgeving te laten draaien.
Het belangrijkste verschil tussen containers en VM’s ligt in de architecturale opzet. Onderstaand worden de concepten nader toegelicht.
Een ‘virtuele machine‘ werd oorspronkelijk door Popek en Goldberg gedefinieerd als een efficiënte, geïsoleerde kopie van een echte computer. VM’s vormen een soort virtualisatie van servers. Met betrekking tot VM’s bestaan enkele belangrijke aspecten:
Een hypervisor is een stukje software, firmware of hardware waar VM’s op draaien. De hypervisors zelf draaien op fysieke computers, de zogenaamde ‘host machine’. De hostmachine voorziet de VM’s van resources, waaronder RAM en CPU. Deze resources zijn verdeeld over VM’s en worden naar gelang van de behoeften verdeeld.
De VM die op de host machine draait (wederom met hypervisor) wordt veelal aangeduid als ‘Guest machine‘. De host machine bevat zowel de applicatie als alles wat nodig is om die applicatie te draaien (e.g. system binaries and libraries). Het draagt ook een volledige eigen gevirtualiseerde hardwarestack, inclusief gevirtualiseerde netwerkadapters, opslag en CPU – wat betekent dat het een eigen volwaardig guest operaringsystem bezit.
Van binnenuit gedraagt de host machine zich als een eigen unit, met eigen dedicated resources. Van de buitenkant weten we dat het een VM betreft – die resources uitwisselt die door de hostmachine worden geleverd.
Je vraagt je misschien af waarom deze extra ‘hypervisor’ -laag tussen de VM en de host machine überhaupt nodig is.
Aangezien de VM een eigen virtueel besturingssysteem heeft, speelt de hypervisor een essentiële rol om de VM’s te voorzien van een platform om Guest OS te beheren en uit te voeren. Het maakt het mogelijk dat de host machines hun resources delen tussen de virtuele machines die als ‘guest’ hierop draaien.
In tegenstelling tot een VM die hardwarevirtualisatie biedt, biedt een container virtualisatie op systeemniveau door de ‘user space’ te onttrekken. Je zult zien wat de term ‘container’ betekent als we naar verschillende definities van het begrip kijken.
Er zijn een hele reeks definities van wat een container is.
Containers lijken in principe op een VM. Ze hebben bijvoorbeeld private ruimte voor gegevensverwerking, kunnen commando’s als root uitvoeren, hebben een private netwerkinterface en IP-adres, staan aangepaste routes en iptable rules toe, kunnen bestandssystemen managen, enz.
Het enige grote verschil tussen containers en VM’s is dat containers de kernel van het hostsysteem delen met andere containers.
De architectuur op het niveau van het besturingssysteem wordt verspreid over de containers. Containers nemen alleen de user space in en niet de kernel of de virtuele hardware, zoals bij een VM het geval is. Elke container krijgt zijn eigen geïsoleerde user space om meerdere containers op één enkele host machine te laten draaien. De enige aspecten die vanaf de grond worden gecreëerd zijn de binaire bestanden en de libraries. Hierom zijn de containers zo licht in gebruik.
Nu het grote geheel duidelijk is geworden, bekijken we de fundamentele elementen van Docker.
Een Docker-container, zoals eerder vermeld, verpakt de software van een applicatie in een onzichtbare doos met alles wat de applicatie nodig heeft om te functioneren. Dat omvat het besturingssysteem, broncode, runtime, systeemtools, libraries, enz. Docker containers zijn opgebouwd uit Docker images.
Docker creëert een netwerkinterface zodat de container kan communiceren met de local host, voegt een beschikbaar IP-adres toe aan de container en voert het proces uit dat is opgegeven voor het uitvoeren van de applicatie bij het definiëren van de image.
Als een container eenmaal succesvol is ontworpen, kan deze in elke omgeving worden uitgevoerd zonder wijzigingen aan te brengen.
Docker gebruikers profiteren daarnaast van het steeds rijker wordende ecosysteem van Docker Hub, dat je kunt beschouwen als een app-store voor Docker images. Docker Hub heeft vele duizenden images die door de community zijn ontwikkeld en die direct beschikbaar zijn voor gebruik.
Het is ongelooflijk eenvoudig om te zoeken naar images die voldoen aan jouw behoeften, gereed voor gebruik en met weinig tot geen aanpassingen te implementeren.