Over containers, Windows en Docker in .NET land
Wanneer bedrijven als Netflix, Uber, of ING zeer enthousiast over een technologie zijn, is het minste wat je kan doen even over de schutting kijken. En dat is precies wat Saber Karmous heeft gedaan met het open-source project Docker.Ik wilde weten: Is het slechts een hype of the next best thing since sliced bread?
Bij Aviva Solutions passen we niet alleen de bekende, bruikbare technologie of ontwikkelmethoden toe. Ook werken we graag met (bèta)technologie die vers van de pers komt. Uiteraard staan niet alle klanten te trappelen om aan de slag te gaan met nieuwste versies of tooling. Zij willen samen mooie, betrouwbare en - bovenal - bruikbare oplossingen realiseren. Geen toeters en bellen - gewoon bewezen, stabiele technologie; dan maar iets minder efficiënt, effectief of handig. Want hoe mooi ze nieuwe technologie ook vinden, het is ook een beetje eng. En in deze gevallen kan Docker ons uitkomst bieden...
Voor wie is deze blog?
Deze blog is met name gericht op .NET ontwikkelaars. In dit eerste deel van deze blogpost geef ik een introductie, in het tweede deel zal ik beschrijven hoe je Docker in de praktijk kunt inzetten. Daarmee hoop ik jou, de immens nieuwsgierige, getalenteerde superontwikkelaar, enthousiast te maken over de toekomst van .NET gecombineerd met Docker.
Docker dus. Wat is het?
Om het makkelijk te maken is Docker ook de naam van het commerciële bedrijf achter het project, en in deze blogpost bedoel ik met Docker het project. Het is een relatief nieuwe technologie, aangezien het pas in april 2013 voor het publiek werd opengesteld via Github.
Docker maakt het “packagen” en “shippen” van applicaties eenvoudiger middels images in containers. En dat is voor ontwikkelaars en beheerders een uitkomst. Zo kun je met deze tool bijvoorbeeld op een laptop zeer snel een, aan productie vergelijkbare, configuratie draaien. Dat lijkt misschien niks nieuws omdat dat min of meer ook met virtuele machines zou kunnen, maar ik geef je straks de kleine verschillen die bij elkaar stiekem een groot effect hebben.
Daarnaast kan Docker ook helpen met het onderzoeken van nieuwe technologie. Je kunt immers eenvoudig een volledige software stack draaien op je eigen laptop, en er naar hartenlust mee spelen. En zoals ik later ook zal uitleggen is dat ook voor Microsoft ontwikkelaars heel belangrijk. Microsoft staat inmiddels qua technologie voor een enorm breed scala aan talen, frameworks, platforms en operating systems. Met Docker wordt het ‘even over de schutting kijken’ een stuk eenvoudiger: je start een kant-en-klare container op en gaat er meteen mee aan de slag.
Docker en Windows, wie maakt me los?
De vraag of Docker bruikbaar is op het Windows-platform is voor Microsoft .NET ontwikkelaars, beheerders en architecten meteen ook de relevantste vraag. Immers, hoe kunnen we ooit gelukkig worden van iets wat initieel alleen op Linux draaide? Gelukkig voor .NET ontwikkelaars zag Microsoft óók de toegevoegde waarde van Docker en is ermee aan de slag gegaan.
Waarom Docker voor het Microsoft platform logisch is
Jarenlang zag Microsoft open-source als een bedreiging voor haar business model. Later realiseerde Microsoft zich (ook) dat met open-source geld te verdienen is en de wereld groter is dan Windows en Office. Om te begrijpen waarom ook Microsoft Docker omarmt en niet een eigen variant introduceert, is het in mijn ogen relevant om in vogelvlucht te bekijken waarom het voor Microsoft platform (.NET/Azure) logisch is om gebruik te maken van Docker.
Waar komen we vandaan?
Het is tegenwoordig steeds minder voor dat een gedistribueerde applicatie bestaat uit alléén componenten die gebouwd zijn op een enkel platform zoals Java of .NET. Er is steeds meer kruisbestuiving tussen verschillende platformen. “Traditionele” platforms/talen zoals C/C++, Ruby, Java en .NET/C#, maar ook de modernere Go, Node, Elixir, en F# maken gretig gebruik van elkaars nieuwe ideeën, concepten of aanpakken. Nemen we dan het Microsoft ecosysteem onder de loep, dan zie je dat sinds de introductie van ASP.NET MVC (ongeveer 10 jaar geleden) Microsoft steeds meer bij de buren shopt. Open-source is al lang niet meer een vies woord in Redmond, en zelfs Linux is uiteindelijk omarmd.
ASP.NET MVC is een goed voorbeeld van hoe Microsoft heeft gekeken naar Ruby om Rails, en is zich tegelijk ook meer gaan conformeren aan het gebruik van webstandaarden. Het ontwikkelteam achter ASP.NET MVC besefte dat concepten als Viewstate en Server Side controls niet helemaal compatibel zijn met webstandaarden als het stateless HTTP protocol. En het is in mijn ogen niet geheel toevallig dat het ASP.NET team binnen Microsoft een grote voorstander van open-source is. De heren Scott Guthrie, Scott Hanselman en Phil Haack staken dit ook nooit onder stoelen of banken.
Kortom het Microsoft - ten tijde van de introductie van .NET - is een heel ander Microsoft dan dat van nu. Waar het business model toen grofweg ging om het verkopen van zoveel mogelijk Windows en Office licenties, is de Azure cloud (Office 365, SaaS, PaaS, IaaS etc.) een zeer belangrijke inkomstenbron geworden. Om dit zo aantrekkelijk mogelijk te maken, richt Microsoft zich niet alleen op de Microsoft ontwikkelaar, maar zorgen ze dat de developer experience voor o.a. Java, Node.JS, Python ook heel sterk is.
Maak me gek: Visual Studio & Linux samen
Als het om besturingssystemen gaat ben ik altijd zeer gecharmeerd geweest van Linux, en met name de controle die hebt. Tegelijkertijd word ik nog steeds warm van Visual Studio, in mijn ogen simpelweg de beste IDE. Dus je kunt je voorstellen dat wanneer die twee werelden bij elkaar komen ik nogal enthousiast word. Een paar mind blowing zaken die afgelopen periode in .NET land hebben plaatsgevonden:
- Open source .NET (Eat that Java)
- .NET Core is multiplatform (of zoals de cool kids zeggen: XPlat)
- Ubuntu voor Windows (Zeg me a.u.b. dat ik niet droom)
- SQL Server for Linux (Whuuuttt!)
- Visual Studio Code draait op Windows, Mac en Linux (Zupertoll!)
- Visual Studio for Mac (hou op hoor!!)
- Windows 2016 met container support (Eindelijk…)
- Docker for Windows (What else?)
En voor met name de laatste 2 punten ben jij, de lezer, hier natuurlijk. Het is dus geen toeval meer dat dit nu gebeurt: er waren her en der wat zaadjes geplant, en in het afgelopen jaar stond opeens de hele boel in bloei.
Microsoft heeft dus heel goed gekeken waar developers gelukkig van worden, wat de cool kids tegenwoordig gebruiken en wat mooi aansluit op hun Azure Cloud strategie. Dus gelukkig voor ons hebben ze, door gebruik te maken van open-source, in mijn ogen een veel sterker platform neergezet.
Maar wát kunnen we er nu mee?
Docker is zo’n technologie die je nooit mistte totdat je begrijpt waar je het voor kunt gebruiken. Het maakt bijvoorbeeld Continuous Delivery / Deployment een stuk eenvoudiger. Mijn collega Dennis Doomen schreef daarover een mooie serie artikelen: Continuous delivery: het pijnloze productieproces deel 1 & deel 2. Maar ook het inrichten van je development machine, het snel optuigen van een testomgeving op je laptop, of het op spinnen van applicaties die bestaan uit honderden of misschien wel duizenden containers.
Introductie: termen en begrippen
Voordat we verder gaan is het handig om een aantal termen en begrippen uit de Docker-wereld van een toelichting te voorzien. Voor mij gold in ieder geval dat ik wel een vermoeden had wat zij konden betekenen, maar het was wel een soort klok-klepel-situatie.
Docker Image en Layers
Een Docker image is opgebouwd uit zogenaamde layers waarin de wijzigingen aan een filesysteem opgenomen zijn t.o.v. van een voorgaande ‘state’ van een image. Beetje zoals commits in een git repository. Een Docker image kun je zien als een read-only template voor een Docker container. Deze gelaagde opzet komt met het voordeel dat - wanneer je meerdere containers draait op basis van dezelfde base image - op disk maar één keer de basis image staat, en per container alleen de verschillen extra ruimte innemen.
Dockerfile
De beschrijving van een Docker image staat in een Dockerfile. Je kunt een Dockerfile zien als een recept om een container te builden, gebaseerd op een image. Iedere stap die beschreven staat in een Dockerfile heeft als gevolg dat er een nieuwe layer gecreëerd wordt. Een voorbeeld van een Dockerfile waarmee een Redis server image gebouwd kan worden ziet er als volgt uit:
Voorbeeld van een Docker file waarmee een Resis server image gebouwd kan worden.
Dit zegt eigenlijk: neem 'ubuntu:14.04' als base image, installeer daarop redis-server, maak dit image benaderbaar via poort 6379, en wanneer de container gestart is voer dan “/usr/bin/redis-server” uit. Ter vergelijking: een Dockerfile voor een dotnet core applicatie draaiend op Windows Nanoserver. De Windows Server Core variant is pak 'm beet 8 GB vs. de circa 600 GB voor Nanoserver. Hier heeft Microsoft nog wat werk te doen. Een Linux Alpine image is 5 MB (!!!) groot.
Voorbeeld van een Dockerfile voor een dotnet core appilicatie draaiend op Windows Nanoserver.
Docker Container
Een Docker container is een draaiend proces wat aanvankelijk gestart is door een image. Docker containers draaien, in principe, op een lichtgewicht vorm van virtualisatie. Hierdoor start een container op in een paar seconden i.p.v. een minuut. Een eenvoudig image kan zelfs opstarten in 100 milliseconden!
Een Docker container bevat dus alles om een applicatie te kunnen draaien. De code, framework, systeemtools & libraries. Alles wat dus geïnstalleerd kan of moet worden op en server. Dit zorgt ervoor dat de software overal hetzelfde draait.
Initieel was Docker gebaseerd op Linux technologie LXC en (zonder daar al te diep op in te gaan) kun je ervan uitgaan dat er functioneel op Linux niks veranderd is. Tot de release van Windows 2016 kon je Docker op Windows draaien door gebruik te maken van containers die in Hyper-V draaien. Dat laatste is natuurlijk een beetje valsspelen. Maar gelukkig is er met de komst van Windows 2016 en Windows 10 Anniversary Edition ondersteuning voor echte Windows containers.
Een uitleg over het verschil in implementatie van Containers tussen Windows en Linux kun je hier lezen: Comparative Study of Docker Engine on Windows Server Vs Linux Platform.
Docker Hub
De Docker Hub is een clouddienst die Docker aanbiedt. Deze dienst is een centrale plek waar onder meer kant-en-klare Docker images te vinden zijn, maar waar je ook images kunt ‘builden’. De images die daar staan variëren: van kale ‘base images’ met alleen een lean & mean Linux installatie en enkele layers, - tot werkende applicaties opgebouwd uit een veelvoud aan layers. Inmiddels vind je op de Docker Hub ook images die op Windows zijn gebaseerd.
Docker Services
Sinds de 1.12 release van Docker wordt Docker Swarm nu standaard meegeleverd met de standaard installatie van Docker. Door Docker Services is het mogelijk om een zogenaamde Swarm aan Docker nodes samen te laten werken. Docker Services moet gezien worden als het component wat schaalbaarheid faciliteert.
Door de komst van Windows 2016 en Windows 10 Anniversary Edition hebben .NET ontwikkelaars eigenlijk geen blokkade meer om met Docker te spelen op de - voor ons zo vertrouwde - Windows omgeving. Ik ben ervan overtuigd dat een .NET ontwikkelaar minstens een beetje moeten experimenteren met Docker, zodat je de concepten beter gaat begrijpen. Dus: hoe maak je een image en hoe draai je die, en wat voor impact gaat dit hebben op de code-build-deploy-test cyclus? Hoe bouw ik images op? En hoe maak ik een “compositie” van meerdere containers: web applicatie container + database container + cache container. Zeker in combinatie met dotnet core werkt dit heel natuurlijk.
Docker overzicht
Nu we bekend zijn met de begrippen is het tijd voor een uitleg (a.d.h.v. visualisaties) over docker. De Docker is in tweeën verdeeld. Docker Engine doet het ‘echte’ werk van managen van Containers, en de Docker CLI (Client) - die gebruik maakt van een REST API - geeft opdracht aan de Docker daemon (server). In onderstaand figuur is te zien hoe die zaken zich relateren.
Overzicht van de Docker.
Docker Container vs. Virtual Machines
Dan komt nu het antwoord op de vraag waar het allemaal om draait is: wat het verschil nu is tussen een Virtuele Machine en een Container. In onderstaande vergelijking gaat het om het beschikbaar stellen van applicaties middels Containers of Virtuele Machines.
Virtual Machine
Containers
Containers bevatten ook alles wat de applicatie nodig heeft. Maar in tegenstelling tot een virtuele machine wordt de kernel gedeeld. De containers draaien in geïsoleerde processen, zoals Word in een eigen proces draait. Dit gebeurt dus in User Space. Dit maakt een Container een stuk lichter dan een virtuele machine, alleen is de isolatie niet zo sterk als die van een virtuele machine. Je levert dus isolatie in en krijgt er allerlei andere coole dingen voor terug.
Volgend deel
In het volgende deel vertel ik over hoe we in de toekomst gebruik kunnen gaan maken van Docker. Docker is op het Windows platform relatief nieuw, en het is niet meer dan logisch dat beheerders eerst vertrouwd willen raken met het werken met Docker. En dan heb je natuurlijk het antwoord van mij tegoed: is het slechts een hype of the next best thing since sliced bread?
Wil je met mij sparren over Docker of de mogelijkheden verkennen? Stuur een mailtje, tweet of bel via het algemene nummer 071 710 7474.