In het container-ecosysteem ontstaat vaak verwarring wanneer developers Docker (een volledig platform) vergelijken met containerd, dat in feite een gefocuste runtimecomponent is. Die vergelijking is alsof je een complete auto vergelijkt met de motor: beide zijn essentieel, maar ze dienen verschillende doelen op verschillende abstractieniveaus.
In deze gids verduidelijk ik de relatie tussen deze twee technologieën, en verken ik hun architectuur, Kubernetes-integratie en de specifieke scenario’s waarin elk hulpmiddel uitblinkt. Of je nu lokaal containers bouwt of productie-Kubernetesclusters beheert, begrijpen wanneer je Docker versus containerd inzet kan je infrastructuurbeslissingen aanzienlijk beïnvloeden.
Aan het eind van dit artikel snap je helder hoe Docker en containerd elkaar aanvullen en hoe je het juiste hulpmiddel kiest voor jouw behoeften, of dat nu snelle lokale ontwikkeling is of grootschalige productiedeployments.
Als je nieuw bent met containerization, raad ik je sterk aan om onze cursus Containerization and Virtualization Concepts te volgen.
Wat is Docker?
Docker heeft het softwarelandschap veranderd door containerization toegankelijk en praktisch te maken voor alledaagse developers. Als een compleet platform biedt Docker alles wat je nodig hebt om containerized applicaties te bouwen, te distribueren en te draaien.
Voor beginners biedt deze Praktische gids voor containers een uitstekend startpunt voor Docker en containers.
Docker fungeert als een alles-in-één containerplatform met een geïntegreerde toolstack die het grootste deel van de containerlevenscyclus afdekt. In de kern verpakt Docker applicaties met al hun afhankelijkheden in draagbare, zelfstandige images die consistent draaien in elke omgeving, van de laptop van een developer tot productieservers.

Deze allesomvattende aanpak heeft van Docker de industriestandaard gemaakt voor lokale development en de developer experience. Enkele belangrijke voordelen zijn:
- Uitgebreid ecosysteem: Docker Hub herbergt miljoenen kant-en-klare images, van databases tot webservers, waardoor complexe installatieprocedures overbodig worden
- Universele portabiliteit: Een container gebouwd op macOS draait identiek op Linux of Windows, mits Docker is geïnstalleerd
- Focus op developers: Abstraheert infrastructuurverschillen zodat developers zich kunnen richten op hun applicaties in plaats van op deploycomplexiteit
- Snelle onboarding: Nieuwe teamleden kunnen in minuten in plaats van uren een ontwikkelomgeving opzetten
Belangrijke componenten en workflow
De architectuur van Docker bestaat uit verschillende onderling verbonden componenten die naadloos samenwerken.
De Docker CLI is de interface voor gebruikers waar developers commando’s geven. Wanneer je een commando als docker run uitvoert, communiceert de CLI met de Docker-daemon (dockerd), de kernservice die containers, images, netwerken en volumes beheert.
Voor Windows- en macOS-gebruikers biedt Docker Desktop een extra laag gemak met een grafische interface, waardoor containermanagement toegankelijk is voor wie minder thuis is in de command line. Deze geïntegreerde omgeving bevat alles voor lokale development, van Kubernetes-ondersteuning tot volumebeheer.
De gebruikelijke workflow volgt een duidelijk patroon:
- Developers bouwen images met Dockerfiles
- Ze pushen die naar registries zoals Docker Hub
- Tot slot worden de images als containers gedraaid op elke host met Docker
Wat veel developers niet beseffen: Docker voert containers niet direct uit. In plaats daarvan delegeert dockerd de daadwerkelijke containerexecutie aan containerd, dat op de achtergrond draait als een apart proces.

Dit modulaire ontwerp, waarbij Docker containerd gebruikt voor low-level operaties, stelt elke component in staat te doen waar hij goed in is: Docker levert de gebruiksvriendelijke interface en het ecosysteem, terwijl containerd de details van de containerexecutie afhandelt.
Of je nu net begint met Docker of een stap verder wilt, bekijk onze 10 Docker-projectideeën voor alle niveaus.
Wat is Containerd?
Nu we Docker’s volledige platformbenadering hebben bekeken, gaan we containerd onder de loep nemen: de gespecialiseerde runtime die containerexecutie aandrijft binnen Docker én in het bredere ecosysteem.
Een industriestandaard container-runtime
Containerd is een lichtgewicht, industriestandaard core container-runtime die is afgestudeerd binnen de Cloud Native Computing Foundation (CNCF), wat duidt op volwassenheid, betrouwbaarheid en brede adoptie. Oorspronkelijk onderdeel van Docker, werd containerd in 2017 losgekoppeld en gedoneerd aan CNCF om bredere ecosysteemadoptie mogelijk te maken.

In tegenstelling tot Docker’s uitgebreide feature-set is de scope van containerd bewust beperkt: het beheert kernoperaties in de containerlevenscyclus zoals starten, stoppen, pauzeren en verwijderen, en verzorgt imagetransfer en -opslag. Deze focus maakt containerd uitzonderlijk stabiel en efficiënt, kwaliteiten die essentieel zijn in productieomgevingen.
Zie containerd als "leidingen": infrastructuur die bedoeld is om in grotere systemen te worden ingebed in plaats van direct door mensen gebruikt te worden. Grote platforms zoals Kubernetes, AWS Fargate en Google Kubernetes Engine vertrouwen allemaal op containerd om containers uit te voeren, ook al interacteren gebruikers met deze platforms via hun eigen interfaces.
Architectuur en ontwerp
Om te begrijpen waarom containerd zo breed wordt ingezet in productiesystemen, moeten we de architectuurprincipes bekijken.
De architectuur van containerd is een schoolvoorbeeld van modulair ontwerp. Gebouwd rond de standaarden van de Open Container Initiative (OCI) garandeert containerd compatibiliteit in het hele container-ecosysteem. Dat betekent dat elke OCI-conforme image met containerd werkt, ongeacht met welke tool die is gemaakt.
De architectuur bestaat uit enkele belangrijke lagen:
- gRPC API-laag: Biedt een client-servermodel waarbij meerdere clients (Docker, Kubernetes, custom tools) met één containerd-instantie communiceren
- Containerd-daemon: Beheert de status van draaiende containers, beheert imagestorage via snapshotters en coördineert netwerkfunctionaliteit via plugins
- runc-runtime: Een lichte, OCI-conforme runtime die direct met Linux-kernelfuncties praat, namespaces creëert, cgroups instelt en containerprocessen start
- Modulaire plugins: Aangepaste snapshotters voor gespecialiseerde opslag, alternatieve runtimes (gVisor, Kata Containers) en netwerkplugins zijn integreerbaar zonder containerd te wijzigen
Wanneer containerd een container moet starten, spawnt het runc, dat het daadwerkelijke werk doet: geïsoleerde namespaces creëren, cgroups voor resource-limieten instellen en het containerproces starten.
Deze scheiding van verantwoordelijkheden maakt containerd zeer extensibel. Organisaties kunnen vrijwel elk aspect aanpassen zonder de kerncode van containerd aan te raken.
Containerd vs Docker: belangrijkste verschillen
Met een stevig begrip van wat elk hulpmiddel doet, bekijken we nu hoe ze in de praktijk verschillen, van architectuur tot integratiepatronen.
Het fundamentele verschil zit in scope en doel.
Docker gebruikt een gecentraliseerde daemonarchitectuur waarin dockerd veel verschillende aspecten coördineert, zoals:
- Image-builds
- Containerexecutie
- Netwerken
- Volumebeheer
Dit alles-in-één ontwerp vereenvoudigt de developer experience, maar introduceert overhead via meerdere abstractielagen.
Containerd daarentegen focust nauw op containerexecutie. Het bevat geen mogelijkheden voor image-builds, geen orchestratiefuncties en geen grafische interface. Voor netwerken heeft Docker Libnetwork ingebouwd in zijn daemon, terwijl containerd vertrouwt op externe Container Network Interface (CNI)-plugins die je naar behoefte kunt wisselen.
Dit architectuurverschil heeft prestatiegevolgen. In omgevingen met veel wisselingen, waar containers vaak starten en stoppen, zoals autoscalende Kubernetesclusters, kan het gestroomlijnde design van containerd zorgen voor snellere starttijden en lager resourceverbruik. Minder overhead betekent minder geheugen- en CPU-gebruik, wat op schaal significant wordt.
Kubernetes-integratie
Over Kubernetes gesproken: de relatie tussen container-runtimes en orchestratieplatformen is flink geëvolueerd, vooral rondom hoe Kubernetes met containerd verbindt.
De relatie tussen Kubernetes en container-runtimes maakte een grote verandering door met Kubernetes 1.24, uitgebracht in 2022. Deze versie verwijderde "Dockershim", een compatibiliteitslaag die Kubernetes in staat stelde Docker als container-runtime te gebruiken.
Dockershim was altijd bedoeld als tijdelijke brug. Toen Kubernetes de Container Runtime Interface (CRI) introduceerde om communicatie met runtimes te standaardiseren, kon Docker die niet direct implementeren omdat Docker ouder is dan het CRI-ontwerp. Dockershim vertaalde tussen Kubernetes en Docker en voegde zo een uiteindelijk overbodige vertaallaag toe.
Moderne Kubernetes-versies communiceren nu rechtstreeks met containerd via CRI, waardoor de Docker-vertaallaag volledig verdwijnt. Deze vereenvoudiging levert concrete voordelen op:
- Lagere latentie: Directe communicatie elimineert vertaal-overhead bij containeroperaties
- Betere stabiliteit: Minder bewegende delen betekent minder potentiële storingspunten
- Hogere performance: Een gestroomlijnde runtimestack is vooral gunstig voor grootschalige deployments
- Eenvoudiger debuggen: Directe CRI-integratie maakt troubleshooting overzichtelijker
Voor Kubernetes-gebruikers is deze verandering grotendeels transparant. Docker-images blijven volledig compatibel omdat ze aan OCI-standaarden voldoen. In de praktijk draaien productie-Kubernetesclusters nu efficiënter door containerd direct te gebruiken, terwijl developers lokaal Docker kunnen blijven gebruiken voor bouwen en testen.
Als je twijfelt over de voor- en nadelen van het gebruik van Kubernetes in de eerste plaats, bekijk dan deze vergelijking over Docker Compose vs Kubernetes.
Image-builds en -beheer
Hoewel runtime-integratie cruciaal is voor orchestratie, hangt de developerworkflow sterk af van hoe elk hulpmiddel met imagecreatie en -opslag omgaat. Image-builds vormen een aanzienlijk verschil in mogelijkheden tussen Docker en containerd.
Docker biedt een geïntegreerd buildsysteem via Dockerfiles en BuildKit, waarmee developers complexe multi-stage builds kunnen maken met caching, parallelisatie en geavanceerde features zoals build secrets en SSH-agent forwarding.
Containerd heeft bewust geen native image-buildworkflow. Om images te bouwen met containerd moeten developers externe tools gebruiken. Opties zijn onder meer BuildKit als aparte daemon draaien en buildctl gebruiken voor commandline-builds, of nerdctl inzetten, een Docker-compatibele CLI die BuildKit integreert.
Ook de opslagmechanismen verschillen qua filosofie. Het volumebeheer van Docker biedt een abstractie die natuurlijk aanvoelt voor developers, met benoemde volumes die data behouden, los van de levenscyclus van containers. Containerd gebruikt een meer low-level snapshotter-systeem, waarbij verschillende snapshotdrivers kunnen worden ingeplugd om gelaagde bestandsystemen verschillend te behandelen op basis van onderliggende opslagvereisten.
Dit verschil weerspiegelt de beoogde doelgroepen van de tools:
- Docker optimaliseert voor developerproductiviteit met ingebouwde gemakken
- Containerd biedt flexibele bouwstenen die platformbouwers naar eigen behoefte kunnen samenstellen
CLI, developer experience en nerdctl
Naast architectuur en features wordt de dagelijkse developer experience het meest direct gevormd door de commandline-interface van elk hulpmiddel. De commandline-ervaring laat de verschillende ontwerpfllosofieën het duidelijkst zien.
De CLI van Docker staat bekend om zijn gebruiksvriendelijkheid. Commando’s zoals docker run, docker build en docker logs zijn intuïtief, goed gedocumenteerd en ontworpen voor mensen. De CLI bevat handige defaults, duidelijke foutmeldingen en uitgebreide opties die de meeste use-cases afdekken.
Containerd wordt geleverd met ctr, een minimale CLI die puur bedoeld is voor debugging en het testen van low-level containerd-functionaliteit. De tool ctr is bewust niet op developers gericht. Hij mist gebruikelijke features zoals port-mapping-shorthand, automatische herstart policies en integratie met credential helpers. Hij is ontworpen voor containerd-developers, niet voor applicatiedevelopers.
De kloof overbruggen met nerdctl
Deze gebruikskloof leidde tot de creatie van nerdctl, een Docker-compatibele CLI voor containerd. nerdctl gebruiken voelt identiek aan Docker: dezelfde commando-syntaxis, dezelfde flags, dezelfde workflow, maar met containerd als onderliggende runtime. Dit maakt nerdctl een uitstekende brug voor teams die in ontwikkelomgevingen van Docker naar containerd overstappen.
In de praktijk interacteren developers zelden direct met containerd. Wanneer dat wel nodig is, biedt nerdctl de vertrouwde interface die ze verwachten, terwijl platformoperators en beheerders de API’s van containerd programmatisch gebruiken via orchestratiesystemen zoals Kubernetes.
Om de verschillen in de praktijk te illustreren, zie je hier hoe veelvoorkomende containerhandelingen zich verhouden over de drie CLI-tools:
|
Taak
|
Docker
|
nerdctl
|
ctr
|
|
Container draaien
|
docker run -d -p 8080:80 nginx
|
nerdctl run -d -p 8080:80 nginx
|
ctr run --net-host -d docker.io/library/nginx:latest nginx_id
|
|
Containers tonen
|
docker ps
|
nerdctl ps
|
ctr tasks list
|
|
Image bouwen
|
docker build -t myapp .
|
nerdctl build -t myapp .
|
Niet ondersteund
|
|
Logs bekijken
|
docker logs <container>
|
nerdctl logs <container>
|
Niet ondersteund
|
|
Container inspecteren
|
docker inspect <container>
|
nerdctl inspect <container>
|
ctr containers info <container>
|
|
Image pullen
|
docker pull nginx
|
nerdctl pull nginx
|
ctr images pull docker.io/library/nginx:latest
|
|
Compose-ondersteuning
|
docker compose up
|
nerdctl compose up
|
Niet ondersteund
|
Opmerking: ctr ondersteunt geen port-mapping (-p) en vereist hostnetwerken (--net-host) om services bloot te stellen. Het pullt ook niet automatisch images.
Overzicht van belangrijkste verschillen
Voordat we aanbevelingen doen voor specifieke use-cases, vatten we de verschillen tot nu toe samen. De onderstaande tabel geeft de belangrijkste functionele verschillen tussen Docker en containerd weer en belicht hun uiteenlopende mogelijkheden en doelgroepen:
|
Feature
|
Docker
|
Containerd
|
|
Image-builds
|
Geïntegreerd (Dockerfiles, BuildKit)
|
Vereist externe tools (buildctl, nerdctl)
|
|
Orchestratie
|
Docker Swarm / Kubernetes
|
Geen (gebruikt door Kubernetes)
|
|
Opslagbeheer
|
Volumebeheer
|
Snapshotter-systeem
|
|
Grafische interface
|
Docker Desktop
|
Geen
|
|
Containerlevenscyclus
|
Volledig beheer (via containerd)
|
Kernfocus (CRI-compatibel)
|
|
Primaire gebruikers
|
Applicatiedevelopers
|
Clusteroperators, platformbouwers
|
Waarom kiezen voor Docker?
Nu we de technische verschillen hebben behandeld, bekijken we praktische scenario’s waarin elk hulpmiddel uitblinkt. Ondanks de opmars van containerd in productieomgevingen blijft Docker de betere keuze voor specifieke situaties waarin de developer experience en uitgebreide tooling het zwaarst wegen.
Voor lokale development en prototyping
Docker blinkt uit wanneer je een "alles-in-één" oplossing nodig hebt voor het schrijven en testen van code. De geïntegreerde toolchain betekent dat developers in minuten, zonder meerdere componenten te hoeven samenstellen of complexe netwerken te configureren, van nul naar draaiende containers kunnen gaan.
Het Docker-ecosysteem levert enorme productiviteitswinst op:
- Docker Hub: Miljoenen direct bruikbare images voor databases, message queues en webservers
- Docker Compose: Definieer multi-containerapplicaties in één YAML-bestand en start complete ontwikkelomgevingen met één commando
- Docker Desktop GUI: Visueel containermanagement, volumes verkennen, resource-limieten aanpassen en geïntegreerde Kubernetes-ondersteuning
- Lagere instapdrempel: Grafische tools en intuïtieve commando’s maken containers toegankelijk voor developers die nieuw zijn met de technologie

Voor teams die Docker Desktop gebruiken, biedt de GUI extra gemakken die onboarding en dagelijkse workflows aanzienlijk versnellen.
Voor complexe build-pipelines
Naast development maken de build-mogelijkheden van Docker het de logische keuze voor geavanceerde continuous integration- en deploymentworkflows.
Docker’s geïntegreerde BuildKit biedt geavanceerde features die essentieel zijn voor moderne CI/CD-pipelines. Multi-stage builds minimaliseren imagegrootte en houden Dockerfiles leesbaar. De cachingmechanismen van BuildKit hergebruiken lagen slim over builds heen, wat buildtijden in CI-omgevingen drastisch reduceert.
De meeste automatiseringsplatformen, zoals GitHub Actions, GitLab CI, Jenkins en anderen, hebben volwassen, beproefde Docker-integraties. Deze integraties regelen authenticatie, caching en publicatie van images zonder frictie.
Andere tools kunnen vergelijkbare resultaten behalen, maar de alomtegenwoordigheid van Docker betekent dat oplossingen en hulp bij troubleshooten makkelijk te vinden zijn — nog een grote plus.
Waarom kiezen voor Containerd?
Containerd blinkt uit in productiescenario’s waar minimalisme, performance en stabiliteit zwaarder wegen dan het gemak van geïntegreerde tooling.
Voor productie-Kubernetesclusters
Containerd als runtime voor Kubernetes-nodes gebruiken levert meetbare voordelen op:
- Minder overhead: Het elimineren van Docker’s daemon betekent lager resourceverbruik per node en substantiële besparingen op schaal
- Betere stabiliteit: Minder bewegende delen betekent minder potentiële storingspunten in je infrastructuur
- Kleiner aanvalsoppervlak: Minder code om te auditen en minder potentiële kwetsbaarheden
- Eenvoudiger debuggen: Directe CRI-integratie verwijdert de dockershim-vertaallaag, wat troubleshooting overzichtelijker maakt
- Betere performance: Een gestroomlijnde runtimestack verbetert containerstarttijden en responsiviteit

De CNCF-graduatiestatus van containerd geeft zijn volwassenheid en betrouwbaarheid aan. Grote cloudproviders, waaronder AWS, Google Cloud en Azure, hebben containerd als standaard voor hun managed Kubernetes-diensten, wat vertrouwen in zijn productierijpheid voor kritieke infrastructuur laat zien.
Voor gespecialiseerde, minimale omgevingen
Hoewel Kubernetes de meest voorkomende productiesituatie is, opent de lichtgewicht aard van containerd de deur naar deployments waar Docker onpraktisch zou zijn.
Edge computing en IoT-apparaten werken vaak met strikte resourcebeperkingen. Het lichtgewicht ontwerp van containerd maakt het inzetbaar in deze omgevingen, waar de volledige stack van Docker te zwaar zou zijn. Elk megabyte geheugen en elke CPU-cyclus telt op embedded hardware.
Geavanceerde security-scenario’s profiteren van de modulaire runtime-architectuur van containerd. Organisaties kunnen sandboxed runtimes integreren voor workloads die extra beveiligingsgrenzen vereisen. Voorbeelden zijn:
- gVisor: biedt sterke kernelisolatie
- Kata Containers: draait containers in lichte vm’s
Deze integraties plug je in containerd zonder uitgebreide aanpassingen.
Migratie van Docker naar Containerd
Begrijpen wanneer je elk hulpmiddel gebruikt is belangrijk, maar weten hoe je ertussen overstapt is net zo cruciaal. Overstappen van Docker naar containerd in bestaande omgevingen vereist zorgvuldige planning, maar het proces is goed gedocumenteerd en rechttoe rechtaan.
Kubernetes-nodes migreren
De operationele stappen om Kubernetes-nodes van Docker naar containerd te migreren volgen een standaardpatroon:
-
Node cordonen: Voorkom dat er nieuwe pods worden gepland (kubectl cordon <node-name>)
-
Bestaande pods drainen: Verplaats workloads naar andere nodes (kubectl drain <node-name>)
-
Kubelet-configuratie updaten: Wijs naar de CRI-socket van containerd op /run/containerd/containerd.sock
-
CNI-plugins verifiëren: Zorg dat containerd de benodigde netwerkplugins geïnstalleerd heeft
-
Kubelet herstarten: Laat registreren met de nieuwe runtime en opnieuw deelnemen aan het cluster
De migratie eerst op niet-productienodes testen helpt om omgevingsspecifieke issues te identificeren voordat je clusterbreed uitrolt. Om veelvoorkomende valkuilen te vermijden, volg je best de volgende best practices:
- Wijzigingen in logpaden: Docker en containerd gebruiken verschillende standaardlocaties voor logs, dus pas je logginginfrastructuur aan
- Ontbrekende CNI-plugins installeren: Containerd vereist CNI-pluginbinaries voor netwerken; die zijn niet altijd standaard geïnstalleerd
- Let op verschillen bij image-pullen: Authenticatie- en registryconfiguraties moeten mogelijk worden aangepast
- Pas op voor mismatches in storage drivers: Zorg dat je persistente volumes compatibel zijn met de snapshotter van containerd
Navigeren door de CLI-verschillen
Zodra je infrastructuur is gemigreerd, moeten developers hun dagelijkse workflows aanpassen aan de nieuwe runtime.
Voor developers die gewend zijn aan Docker-commando’s biedt nerdctl een bijna identieke ervaring. Commando’s zoals nerdctl run, nerdctl build en nerdctl compose up werken precies zoals hun Docker-equivalenten, wat de overgang naadloos maakt.
Voor debugging is het essentieel te begrijpen hoe je Docker-debugworkflows naar containerd mapt. Waar je docker inspect zou gebruiken om een container te bekijken, geeft ctr containers info vergelijkbare informatie, zij het in een ander formaat. Evenzo toont ctr tasks list draaiende containers.
De meeste developers merken dat nerdctl de noodzaak wegneemt om de syntaxis van ctr te leren voor alledaagse taken. De low-level ctr blijft nuttig voor het oplossen van runtime-specifieke problemen of wanneer je direct met de API’s van containerd werkt.
Conclusie
De relatie tussen Docker en containerd is een perfect voorbeeld van geslaagd modulair ontwerp in software-infrastructuur. Docker blijft het optimale hulpmiddel voor mensen die code schrijven, omdat het de geïntegreerde ervaring, het uitgebreide ecosysteem en de developer-vriendelijke interfaces biedt die het bouwen van containerized applicaties productief (en leuk) maken.
Containerd blinkt ondertussen uit als runtime voor machines die code uitvoeren, met de stabiliteit, performance en het minimalisme die nodig zijn voor productie-orchestratieplatforms. Dat Docker Engine onder de motorkap containerd gebruikt, laat zien hoe beide tools elkaar aanvullen in plaats van concurreren.
Ik raad de meeste organisaties een pragmatische aanpak aan: blijf Docker gebruiken op de laptops van developers, waar de tooling ontwikkelworkflows versnelt, maar overweeg productie-Kubernetesclusters rechtstreeks naar containerd te migreren voor de operationele voordelen van minder overhead en een vereenvoudigde runtimestack.
Of je nu kiest voor het volledige platform van Docker of de gefocuste runtime van containerd, beide blijven essentiële onderdelen van het moderne container-ecosysteem, elk geoptimaliseerd voor verschillende fasen van de applicatielevenscyclus.
Blijf leren en schrijf je in voor onze skill track Containerization and Virtualization with Docker and Kubernetes.
In het container-ecosysteem ontstaat vaak verwarring wanneer developers Docker (een volledig platform) vergelijken met containerd, dat in feite een gefocuste runtimecomponent is. Die vergelijking is alsof je een complete auto vergelijkt met de motor: beide zijn essentieel, maar ze dienen verschillende doelen op verschillende abstractieniveaus.
In deze gids verduidelijk ik de relatie tussen deze twee technologieën, en verken ik hun architectuur, Kubernetes-integratie en de specifieke scenario’s waarin elk hulpmiddel uitblinkt. Of je nu lokaal containers bouwt of productie-Kubernetesclusters beheert, begrijpen wanneer je Docker versus containerd inzet kan je infrastructuurbeslissingen aanzienlijk beïnvloeden.
Aan het eind van dit artikel snap je helder hoe Docker en containerd elkaar aanvullen en hoe je het juiste hulpmiddel kiest voor jouw behoeften, of dat nu snelle lokale ontwikkeling is of grootschalige productiedeployments.
Als je nieuw bent met containerization, raad ik je sterk aan om onze cursus Containerization and Virtualization Concepts te volgen.
Wat is Docker?
Docker heeft het softwarelandschap veranderd door containerization toegankelijk en praktisch te maken voor alledaagse developers. Als een compleet platform biedt Docker alles wat je nodig hebt om containerized applicaties te bouwen, te distribueren en te draaien.
Voor beginners biedt deze Praktische gids voor containers een uitstekend startpunt voor Docker en containers.
Een compleet containerplatform
Docker fungeert als een alles-in-één containerplatform met een geïntegreerde toolstack die het grootste deel van de containerlevenscyclus afdekt. In de kern verpakt Docker applicaties met al hun afhankelijkheden in draagbare, zelfstandige images die consistent draaien in elke omgeving, van de laptop van een developer tot productieservers.
Deze allesomvattende aanpak heeft van Docker de industriestandaard gemaakt voor lokale development en de developer experience. Enkele belangrijke voordelen zijn:
Belangrijke componenten en workflow
De architectuur van Docker bestaat uit verschillende onderling verbonden componenten die naadloos samenwerken.
De Docker CLI is de interface voor gebruikers waar developers commando’s geven. Wanneer je een commando als
docker runuitvoert, communiceert de CLI met de Docker-daemon (dockerd), de kernservice die containers, images, netwerken en volumes beheert.Voor Windows- en macOS-gebruikers biedt Docker Desktop een extra laag gemak met een grafische interface, waardoor containermanagement toegankelijk is voor wie minder thuis is in de command line. Deze geïntegreerde omgeving bevat alles voor lokale development, van Kubernetes-ondersteuning tot volumebeheer.
De gebruikelijke workflow volgt een duidelijk patroon:
Wat veel developers niet beseffen: Docker voert containers niet direct uit. In plaats daarvan delegeert
dockerdde daadwerkelijke containerexecutie aan containerd, dat op de achtergrond draait als een apart proces.Dit modulaire ontwerp, waarbij Docker containerd gebruikt voor low-level operaties, stelt elke component in staat te doen waar hij goed in is: Docker levert de gebruiksvriendelijke interface en het ecosysteem, terwijl containerd de details van de containerexecutie afhandelt.
Of je nu net begint met Docker of een stap verder wilt, bekijk onze 10 Docker-projectideeën voor alle niveaus.
Wat is Containerd?
Nu we Docker’s volledige platformbenadering hebben bekeken, gaan we containerd onder de loep nemen: de gespecialiseerde runtime die containerexecutie aandrijft binnen Docker én in het bredere ecosysteem.
Een industriestandaard container-runtime
Containerd is een lichtgewicht, industriestandaard core container-runtime die is afgestudeerd binnen de Cloud Native Computing Foundation (CNCF), wat duidt op volwassenheid, betrouwbaarheid en brede adoptie. Oorspronkelijk onderdeel van Docker, werd containerd in 2017 losgekoppeld en gedoneerd aan CNCF om bredere ecosysteemadoptie mogelijk te maken.
In tegenstelling tot Docker’s uitgebreide feature-set is de scope van containerd bewust beperkt: het beheert kernoperaties in de containerlevenscyclus zoals starten, stoppen, pauzeren en verwijderen, en verzorgt imagetransfer en -opslag. Deze focus maakt containerd uitzonderlijk stabiel en efficiënt, kwaliteiten die essentieel zijn in productieomgevingen.
Zie containerd als "leidingen": infrastructuur die bedoeld is om in grotere systemen te worden ingebed in plaats van direct door mensen gebruikt te worden. Grote platforms zoals Kubernetes, AWS Fargate en Google Kubernetes Engine vertrouwen allemaal op containerd om containers uit te voeren, ook al interacteren gebruikers met deze platforms via hun eigen interfaces.
Architectuur en ontwerp
Om te begrijpen waarom containerd zo breed wordt ingezet in productiesystemen, moeten we de architectuurprincipes bekijken.
De architectuur van containerd is een schoolvoorbeeld van modulair ontwerp. Gebouwd rond de standaarden van de Open Container Initiative (OCI) garandeert containerd compatibiliteit in het hele container-ecosysteem. Dat betekent dat elke OCI-conforme image met containerd werkt, ongeacht met welke tool die is gemaakt.
De architectuur bestaat uit enkele belangrijke lagen:
Wanneer containerd een container moet starten, spawnt het runc, dat het daadwerkelijke werk doet: geïsoleerde namespaces creëren, cgroups voor resource-limieten instellen en het containerproces starten.
Deze scheiding van verantwoordelijkheden maakt containerd zeer extensibel. Organisaties kunnen vrijwel elk aspect aanpassen zonder de kerncode van containerd aan te raken.
Containerd vs Docker: belangrijkste verschillen
Met een stevig begrip van wat elk hulpmiddel doet, bekijken we nu hoe ze in de praktijk verschillen, van architectuur tot integratiepatronen.
Container-runtime vs platform
Het fundamentele verschil zit in scope en doel.
Docker gebruikt een gecentraliseerde daemonarchitectuur waarin
dockerdveel verschillende aspecten coördineert, zoals:Dit alles-in-één ontwerp vereenvoudigt de developer experience, maar introduceert overhead via meerdere abstractielagen.
Containerd daarentegen focust nauw op containerexecutie. Het bevat geen mogelijkheden voor image-builds, geen orchestratiefuncties en geen grafische interface. Voor netwerken heeft Docker
Libnetworkingebouwd in zijn daemon, terwijl containerd vertrouwt op externe Container Network Interface (CNI)-plugins die je naar behoefte kunt wisselen.Dit architectuurverschil heeft prestatiegevolgen. In omgevingen met veel wisselingen, waar containers vaak starten en stoppen, zoals autoscalende Kubernetesclusters, kan het gestroomlijnde design van containerd zorgen voor snellere starttijden en lager resourceverbruik. Minder overhead betekent minder geheugen- en CPU-gebruik, wat op schaal significant wordt.
Kubernetes-integratie
Over Kubernetes gesproken: de relatie tussen container-runtimes en orchestratieplatformen is flink geëvolueerd, vooral rondom hoe Kubernetes met containerd verbindt.
De relatie tussen Kubernetes en container-runtimes maakte een grote verandering door met Kubernetes 1.24, uitgebracht in 2022. Deze versie verwijderde "Dockershim", een compatibiliteitslaag die Kubernetes in staat stelde Docker als container-runtime te gebruiken.
Dockershim was altijd bedoeld als tijdelijke brug. Toen Kubernetes de Container Runtime Interface (CRI) introduceerde om communicatie met runtimes te standaardiseren, kon Docker die niet direct implementeren omdat Docker ouder is dan het CRI-ontwerp. Dockershim vertaalde tussen Kubernetes en Docker en voegde zo een uiteindelijk overbodige vertaallaag toe.
Moderne Kubernetes-versies communiceren nu rechtstreeks met containerd via CRI, waardoor de Docker-vertaallaag volledig verdwijnt. Deze vereenvoudiging levert concrete voordelen op:
Voor Kubernetes-gebruikers is deze verandering grotendeels transparant. Docker-images blijven volledig compatibel omdat ze aan OCI-standaarden voldoen. In de praktijk draaien productie-Kubernetesclusters nu efficiënter door containerd direct te gebruiken, terwijl developers lokaal Docker kunnen blijven gebruiken voor bouwen en testen.
Als je twijfelt over de voor- en nadelen van het gebruik van Kubernetes in de eerste plaats, bekijk dan deze vergelijking over Docker Compose vs Kubernetes.
Image-builds en -beheer
Hoewel runtime-integratie cruciaal is voor orchestratie, hangt de developerworkflow sterk af van hoe elk hulpmiddel met imagecreatie en -opslag omgaat. Image-builds vormen een aanzienlijk verschil in mogelijkheden tussen Docker en containerd.
Docker biedt een geïntegreerd buildsysteem via Dockerfiles en BuildKit, waarmee developers complexe multi-stage builds kunnen maken met caching, parallelisatie en geavanceerde features zoals build secrets en SSH-agent forwarding.
Containerd heeft bewust geen native image-buildworkflow. Om images te bouwen met containerd moeten developers externe tools gebruiken. Opties zijn onder meer BuildKit als aparte daemon draaien en
buildctlgebruiken voor commandline-builds, ofnerdctlinzetten, een Docker-compatibele CLI die BuildKit integreert.Ook de opslagmechanismen verschillen qua filosofie. Het volumebeheer van Docker biedt een abstractie die natuurlijk aanvoelt voor developers, met benoemde volumes die data behouden, los van de levenscyclus van containers. Containerd gebruikt een meer low-level snapshotter-systeem, waarbij verschillende snapshotdrivers kunnen worden ingeplugd om gelaagde bestandsystemen verschillend te behandelen op basis van onderliggende opslagvereisten.
Dit verschil weerspiegelt de beoogde doelgroepen van de tools:
CLI, developer experience en nerdctl
Naast architectuur en features wordt de dagelijkse developer experience het meest direct gevormd door de commandline-interface van elk hulpmiddel. De commandline-ervaring laat de verschillende ontwerpfllosofieën het duidelijkst zien.
De CLI van Docker staat bekend om zijn gebruiksvriendelijkheid. Commando’s zoals
docker run,docker buildendocker logszijn intuïtief, goed gedocumenteerd en ontworpen voor mensen. De CLI bevat handige defaults, duidelijke foutmeldingen en uitgebreide opties die de meeste use-cases afdekken.Containerd wordt geleverd met
ctr, een minimale CLI die puur bedoeld is voor debugging en het testen van low-level containerd-functionaliteit. De toolctris bewust niet op developers gericht. Hij mist gebruikelijke features zoals port-mapping-shorthand, automatische herstart policies en integratie met credential helpers. Hij is ontworpen voor containerd-developers, niet voor applicatiedevelopers.De kloof overbruggen met nerdctl
Deze gebruikskloof leidde tot de creatie van
nerdctl, een Docker-compatibele CLI voor containerd.nerdctlgebruiken voelt identiek aan Docker: dezelfde commando-syntaxis, dezelfde flags, dezelfde workflow, maar met containerd als onderliggende runtime. Dit maaktnerdctleen uitstekende brug voor teams die in ontwikkelomgevingen van Docker naar containerd overstappen.In de praktijk interacteren developers zelden direct met containerd. Wanneer dat wel nodig is, biedt
nerdctlde vertrouwde interface die ze verwachten, terwijl platformoperators en beheerders de API’s van containerd programmatisch gebruiken via orchestratiesystemen zoals Kubernetes.Om de verschillen in de praktijk te illustreren, zie je hier hoe veelvoorkomende containerhandelingen zich verhouden over de drie CLI-tools:
Taak
Docker
nerdctl
ctr
Container draaien
docker run -d -p 8080:80 nginxnerdctl run -d -p 8080:80 nginxctr run --net-host -d docker.io/library/nginx:latest nginx_idContainers tonen
docker psnerdctl psctr tasks listImage bouwen
docker build -t myapp .nerdctl build -t myapp .Niet ondersteund
Logs bekijken
docker logs <container>nerdctl logs <container>Niet ondersteund
Container inspecteren
docker inspect <container>nerdctl inspect <container>ctr containers info <container>Image pullen
docker pull nginxnerdctl pull nginxctr images pull docker.io/library/nginx:latestCompose-ondersteuning
docker compose upnerdctl compose upNiet ondersteund
Opmerking: ctr ondersteunt geen port-mapping (
-p) en vereist hostnetwerken (--net-host) om services bloot te stellen. Het pullt ook niet automatisch images.Overzicht van belangrijkste verschillen
Voordat we aanbevelingen doen voor specifieke use-cases, vatten we de verschillen tot nu toe samen. De onderstaande tabel geeft de belangrijkste functionele verschillen tussen Docker en containerd weer en belicht hun uiteenlopende mogelijkheden en doelgroepen:
Feature
Docker
Containerd
Image-builds
Geïntegreerd (Dockerfiles, BuildKit)
Vereist externe tools (buildctl, nerdctl)
Orchestratie
Docker Swarm / Kubernetes
Geen (gebruikt door Kubernetes)
Opslagbeheer
Volumebeheer
Snapshotter-systeem
Grafische interface
Docker Desktop
Geen
Containerlevenscyclus
Volledig beheer (via containerd)
Kernfocus (CRI-compatibel)
Primaire gebruikers
Applicatiedevelopers
Clusteroperators, platformbouwers
Waarom kiezen voor Docker?
Nu we de technische verschillen hebben behandeld, bekijken we praktische scenario’s waarin elk hulpmiddel uitblinkt. Ondanks de opmars van containerd in productieomgevingen blijft Docker de betere keuze voor specifieke situaties waarin de developer experience en uitgebreide tooling het zwaarst wegen.
Voor lokale development en prototyping
Docker blinkt uit wanneer je een "alles-in-één" oplossing nodig hebt voor het schrijven en testen van code. De geïntegreerde toolchain betekent dat developers in minuten, zonder meerdere componenten te hoeven samenstellen of complexe netwerken te configureren, van nul naar draaiende containers kunnen gaan.
Het Docker-ecosysteem levert enorme productiviteitswinst op:
Voor teams die Docker Desktop gebruiken, biedt de GUI extra gemakken die onboarding en dagelijkse workflows aanzienlijk versnellen.
Voor complexe build-pipelines
Naast development maken de build-mogelijkheden van Docker het de logische keuze voor geavanceerde continuous integration- en deploymentworkflows.
Docker’s geïntegreerde BuildKit biedt geavanceerde features die essentieel zijn voor moderne CI/CD-pipelines. Multi-stage builds minimaliseren imagegrootte en houden Dockerfiles leesbaar. De cachingmechanismen van BuildKit hergebruiken lagen slim over builds heen, wat buildtijden in CI-omgevingen drastisch reduceert.
De meeste automatiseringsplatformen, zoals GitHub Actions, GitLab CI, Jenkins en anderen, hebben volwassen, beproefde Docker-integraties. Deze integraties regelen authenticatie, caching en publicatie van images zonder frictie.
Andere tools kunnen vergelijkbare resultaten behalen, maar de alomtegenwoordigheid van Docker betekent dat oplossingen en hulp bij troubleshooten makkelijk te vinden zijn — nog een grote plus.
Waarom kiezen voor Containerd?
Containerd blinkt uit in productiescenario’s waar minimalisme, performance en stabiliteit zwaarder wegen dan het gemak van geïntegreerde tooling.
Voor productie-Kubernetesclusters
Containerd als runtime voor Kubernetes-nodes gebruiken levert meetbare voordelen op:
De CNCF-graduatiestatus van containerd geeft zijn volwassenheid en betrouwbaarheid aan. Grote cloudproviders, waaronder AWS, Google Cloud en Azure, hebben containerd als standaard voor hun managed Kubernetes-diensten, wat vertrouwen in zijn productierijpheid voor kritieke infrastructuur laat zien.
Voor gespecialiseerde, minimale omgevingen
Hoewel Kubernetes de meest voorkomende productiesituatie is, opent de lichtgewicht aard van containerd de deur naar deployments waar Docker onpraktisch zou zijn.
Edge computing en IoT-apparaten werken vaak met strikte resourcebeperkingen. Het lichtgewicht ontwerp van containerd maakt het inzetbaar in deze omgevingen, waar de volledige stack van Docker te zwaar zou zijn. Elk megabyte geheugen en elke CPU-cyclus telt op embedded hardware.
Geavanceerde security-scenario’s profiteren van de modulaire runtime-architectuur van containerd. Organisaties kunnen sandboxed runtimes integreren voor workloads die extra beveiligingsgrenzen vereisen. Voorbeelden zijn:
Deze integraties plug je in containerd zonder uitgebreide aanpassingen.
Migratie van Docker naar Containerd
Begrijpen wanneer je elk hulpmiddel gebruikt is belangrijk, maar weten hoe je ertussen overstapt is net zo cruciaal. Overstappen van Docker naar containerd in bestaande omgevingen vereist zorgvuldige planning, maar het proces is goed gedocumenteerd en rechttoe rechtaan.
Kubernetes-nodes migreren
De operationele stappen om Kubernetes-nodes van Docker naar containerd te migreren volgen een standaardpatroon:
Node cordonen: Voorkom dat er nieuwe pods worden gepland (
kubectl cordon <node-name>)Bestaande pods drainen: Verplaats workloads naar andere nodes (
kubectl drain <node-name>)Kubelet-configuratie updaten: Wijs naar de CRI-socket van containerd op
/run/containerd/containerd.sockCNI-plugins verifiëren: Zorg dat containerd de benodigde netwerkplugins geïnstalleerd heeft
Kubelet herstarten: Laat registreren met de nieuwe runtime en opnieuw deelnemen aan het cluster
De migratie eerst op niet-productienodes testen helpt om omgevingsspecifieke issues te identificeren voordat je clusterbreed uitrolt. Om veelvoorkomende valkuilen te vermijden, volg je best de volgende best practices:
Navigeren door de CLI-verschillen
Zodra je infrastructuur is gemigreerd, moeten developers hun dagelijkse workflows aanpassen aan de nieuwe runtime.
Voor developers die gewend zijn aan Docker-commando’s biedt nerdctl een bijna identieke ervaring. Commando’s zoals
nerdctl run,nerdctl buildennerdctl compose upwerken precies zoals hun Docker-equivalenten, wat de overgang naadloos maakt.Voor debugging is het essentieel te begrijpen hoe je Docker-debugworkflows naar containerd mapt. Waar je
docker inspectzou gebruiken om een container te bekijken, geeftctr containers infovergelijkbare informatie, zij het in een ander formaat. Evenzo toontctr tasks listdraaiende containers.De meeste developers merken dat
nerdctlde noodzaak wegneemt om de syntaxis vanctrte leren voor alledaagse taken. De low-levelctrblijft nuttig voor het oplossen van runtime-specifieke problemen of wanneer je direct met de API’s van containerd werkt.Conclusie
De relatie tussen Docker en containerd is een perfect voorbeeld van geslaagd modulair ontwerp in software-infrastructuur. Docker blijft het optimale hulpmiddel voor mensen die code schrijven, omdat het de geïntegreerde ervaring, het uitgebreide ecosysteem en de developer-vriendelijke interfaces biedt die het bouwen van containerized applicaties productief (en leuk) maken.
Containerd blinkt ondertussen uit als runtime voor machines die code uitvoeren, met de stabiliteit, performance en het minimalisme die nodig zijn voor productie-orchestratieplatforms. Dat Docker Engine onder de motorkap containerd gebruikt, laat zien hoe beide tools elkaar aanvullen in plaats van concurreren.
Ik raad de meeste organisaties een pragmatische aanpak aan: blijf Docker gebruiken op de laptops van developers, waar de tooling ontwikkelworkflows versnelt, maar overweeg productie-Kubernetesclusters rechtstreeks naar containerd te migreren voor de operationele voordelen van minder overhead en een vereenvoudigde runtimestack.
Of je nu kiest voor het volledige platform van Docker of de gefocuste runtime van containerd, beide blijven essentiële onderdelen van het moderne container-ecosysteem, elk geoptimaliseerd voor verschillende fasen van de applicatielevenscyclus.
Blijf leren en schrijf je in voor onze skill track Containerization and Virtualization with Docker and Kubernetes.