Cover
Zacznij teraz za darmo 7__Lecture_Virtualization-Containers.pdf
Summary
# Introductie tot containerisatie
Dit topic introduceert het concept van containerisatie, waarbij containers worden gedefinieerd als geïsoleerde processen en vergeleken met virtuele machines, met een focus op OS-level virtualisatie en de geschiedenis ervan.
## 1. Introductie tot containerisatie
Containerisatie is een vorm van besturingssysteem-level virtualisatie, wat betekent dat de kernel van een besturingssysteem het mogelijk maakt om meerdere geïsoleerde user-space instanties te creëren. Deze geïsoleerde omgevingen worden containers genoemd en zijn in wezen geïsoleerde processen die binnen het host-besturingssysteem draaien. Dit staat in contrast met traditionele virtuele machines, die een volledige gastbesturingssysteem emulator vereisen [10](#page=10) [3](#page=3).
### 1.1 Wat zijn containers?
Containers worden gedefinieerd als geïsoleerde processen. Dit kan worden geverifieerd doordat ze zichtbaar zijn in de proceslijst van het besturingssysteem, maar met toegevoegde isolatie. Wanneer een proces wordt gecontaineriseerd, "ziet" het slechts een beperkt deel van het besturingssysteem en zijn bronnen, in plaats van het volledige systeem [3](#page=3) [5](#page=5).
> **Tip:** Controleer in het lab hoe containers zich manifesteren in de proceslijst en hoe ze verschillende omgevingen waarnemen [3](#page=3).
### 1.2 OS-level virtualisatie
OS-level virtualisatie is de algemene term voor het creëren van geïsoleerde omgevingen binnen de kernel van een besturingssysteem. Afhankelijk van de specifieke software kan deze technologie verschillende namen hebben [7](#page=7):
* **Containers:** Gebruikt door Docker, Podman, LXC [7](#page=7).
* **Zones:** Gebruikt door Solaris [7](#page=7).
* **Jails:** Gebruikt door chroot of BSD [7](#page=7).
Containerisatie is geen nieuw concept en heeft wortels die teruggaan tot begin jaren 2000. Echter, Docker, gelanceerd in 2013, heeft containerisatie toegankelijker gemaakt met verbeterde tools en een duidelijk doel: het "verschepen" van software met containers. Kubernetes, geïntroduceerd in 2014, heeft geholpen bij het schalen van container-gebaseerde oplossingen, wat heeft geleid tot wijdverbreid gebruik in productieomgevingen [7](#page=7).
> **Tip:** Begrijp dat containers niet nieuw zijn, maar dat tools zoals Docker en orkestratiesystemen zoals Kubernetes hun populariteit en praktisch nut enorm hebben vergroot [7](#page=7).
### 1.3 Containers versus virtuele machines (VMs)
Het fundamentele verschil tussen containers en virtuele machines ligt in hun architectuur en de mate van virtualisatie.
* **Virtuele Machines (VMs):** Virtualiseren de hardware en vereisen een volledig gastbesturingssysteem per VM bovenop een hypervisor. Dit resulteert in hogere overhead, meer resourceverbruik en langere opstarttijden [10](#page=10).
* **Containers:** Virtualiseren het besturingssysteem zelf. Ze delen de kernel van het host-besturingssysteem en isoleren alleen de applicatieprocessen en hun benodigde bibliotheken en dependencies. Dit maakt containers lichter, sneller en efficiënter in resourcegebruik [10](#page=10) [3](#page=3).
> **Voorbeeld:** Stel u voor dat u één server heeft om maximaal te benutten. Vroeger zou u misschien verschillende VMs draaien voor verschillende diensten (webserver, fileserver, etc.). Met containerisatie kunt u op diezelfde server meerdere containers draaien, elk met een specifieke applicatie en zijn dependencies, die allemaal de kernel van het host-besturingssysteem delen [9](#page=9).
### 1.4 De filosofie van Docker
Docker's filosofie draait om het vereenvoudigen en standaardiseren van het proces van softwareontwikkeling en -implementatie. Het wordt vaak omschreven als [12](#page=12):
* "Een chique manier om een commando uit te voeren" [14](#page=14).
* "Applicatiecontainers" [14](#page=14).
* "Het verschepen van software (en al zijn dependencies)" [14](#page=14).
Dit benadrukt het doel om applicaties en hun omgeving samen te verpakken, zodat ze consistent draaien, ongeacht waar ze worden geïmplementeerd [12](#page=12) [14](#page=14).
---
# Docker ecosysteem en concepten
Dit gedeelte biedt een diepgaande blik op de kerncomponenten en architectuur van het Docker ecosysteem, van registraties en images tot de onderliggende technologieën die containers aandrijven [15](#page=15).
### 2.1 Kernconcepten van Docker
Docker wordt gezien als een manier om commando's uit te voeren en wordt toegepast op "application containers", wat helpt bij het "shippen" van software samen met al haar afhankelijkheden. De fundamentele elementen binnen Docker zijn registraties, images en containers, die nauw met elkaar samenhangen [14](#page=14) [15](#page=15).
#### 2.1.1 Registraties, Images en Containers
* **Registratie (Registry):** Een opslagplaats voor Docker images. Voorbeelden hiervan zijn Docker Hub (publiek) of private registraties [15](#page=15).
* **Image:** Een uitvoerbaar pakket dat alles bevat wat nodig is om een applicatie te draaien: code, runtime, systeertools, systeembibliotheken en instellingen. Images zijn immutable (onveranderlijk) [15](#page=15).
* **Container:** Een draaiende instantie van een image. Het is de runtime omgeving waarin de applicatie daadwerkelijk draait. Containers zijn geïsoleerd van de host machine en van andere containers [15](#page=15).
#### 2.1.2 Dockerfile
Een `Dockerfile` is een tekstbestand dat instructies bevat om een Docker image te bouwen. Deze instructies specificeren de basisimage, commando's om software te installeren, bestanden te kopiëren, poorten te openen, en het commando dat moet worden uitgevoerd bij het starten van de container [16](#page=16).
> **Tip:** Het volgen van best practices voor Dockerfiles, zoals die van Microsoft en Docker zelf, is cruciaal voor het optimaliseren van buildtijden en imagegroottes [16](#page=16).
#### 2.1.3 Multi-stage builds
Multi-stage builds in Dockerfiles zijn een techniek om de uiteindelijke container image kleiner en efficiënter te maken. Hierbij worden meerdere stages gedefinieerd binnen één `Dockerfile`. Een typisch scenario is het gebruik van één stage voor het bouwen van de applicatie (bijvoorbeeld met ontwikkeltools) en een tweede stage die enkel de gecompileerde binaire code bevat voor de productie-image. Dit resulteert in een image die geen onnodige build-tools of tussenliggende artefacten bevat [17](#page=17).
> **Tip:** Multi-stage builds helpen bij het scheiden van build-omgevingen van runtime-omgevingen, wat leidt tot veiligere en kleinere images [17](#page=17).
#### 2.1.4 Docker Compose
Docker Compose is een tool voor het definiëren en beheren van applicaties die uit meerdere containers bestaan. De configuratie van de multi-container applicatie wordt vastgelegd in een `docker-compose.yml` bestand, waarna de applicatie eenvoudig kan worden gestart met het commando `docker compose up` [18](#page=18).
> **Voorbeeld:** Een `docker-compose.yml` bestand kan worden gebruikt om een WordPress website te definiëren samen met een bijbehorende database container [18](#page=18).
### 2.2 Docker Engine architectuur
De Docker Engine bestaat uit een server (daemon) en een client die met elkaar communiceren via de Docker Engine API, een REST API. De `docker version` commando toont informatie over de client en de daemon, wat verschilt van `docker --version` dat enkel de clientversie toont [19](#page=19).
#### 2.2.1 Interactie via de Docker Engine API
De Docker Engine API maakt interactie met de Docker daemon mogelijk. Dit kan bijvoorbeeld via een Unix socket, zoals gedemonstreerd met `curl --unix-sock /var/run/docker.sock http://1.43/images/json` om een lijst van images op te vragen, of `curl --unix-sock /var/run/docker.sock http://1.43/containers/json` om een lijst van containers op te vragen [19](#page=19).
#### 2.2.2 Onderliggende componenten: Containerd en runc
Onder de motorkap maakt Docker gebruik van gespecialiseerde componenten om containers te beheren en uit te voeren. De belangrijkste hiervan zijn `containerd` en `runc` [20](#page=20).
* **Containerd:** Een daemon die verantwoordelijk is voor het beheer van de levenscyclus van containers op een host. Het beheert onder andere de image transfers, opslag en het uitvoeren van containers [20](#page=20) [21](#page=21).
* **runc:** Een lichtgewicht, low-level container runtime die is gebaseerd op de Open Container Initiative (OCI) standaard. `runc` is verantwoordelijk voor het daadwerkelijk starten en uitvoeren van de containerprocessen [20](#page=20) [21](#page=21) [23](#page=23).
Technisch gezien, wanneer een container met Docker wordt gestart, communiceert de Docker daemon met `containerd`, die op zijn beurt `runc` aanroept om de container uit te voeren. De systeemservice `docker.service` is te vinden onder `/lib/systemd/system/docker.service` [21](#page=21).
> **Tip:** Begrijpen hoe `containerd` en `runc` samenwerken, helpt bij het dieper doorgronden van de containertechnologie en de interactie met het besturingssysteem [20](#page=20) [21](#page=21) [23](#page=23).
---
# Container standaarden en alternatieven
Dit topic verkent de Open Container Initiative (OCI) standaard die zorgt voor interoperabiliteit tussen containertechnologieën, en bespreekt alternatieve containeromgevingen zoals Podman en LXC/LXD/Incus [24](#page=24).
### 3.1 Open Container Initiative (OCI)
De Open Container Initiative (OCI) is een project dat tot doel heeft een set standaarden te creëren voor het formatteren en uitvoeren van containers, met als belangrijkste doel interoperabiliteit tussen verschillende containertechnologieën te waarborgen [25](#page=25).
* **Kernidee:** De OCI definieert een standaard voor zowel het containerformaat (image-spec) als de runtime-specificatie (runtime-spec). Dit betekent dat een container die volgens de OCI-standaard is gebouwd, door elke container runtime die OCI ondersteunt, kan worden uitgevoerd [25](#page=25).
* **Voordelen:** Door de OCI-standaard wordt vendor lock-in verminderd en kunnen ontwikkelaars en operators de tools en platformen kiezen die het beste bij hun behoeften passen, zonder zich zorgen te maken over compatibiliteit [25](#page=25).
* **Relatie met Docker:** Een Dockerfile is OCI-compliant, wat impliceert dat elke runtime die OCI ondersteunt, containers kan uitvoeren die met behulp van de Dockerfile-syntax zijn gecreëerd [25](#page=25).
### 3.2 Podman
Podman is een daemonless container engine die fungeert als een krachtig alternatief voor Docker, met een sterke focus op veiligheid en flexibiliteit [27](#page=27) [28](#page=28).
* **Daemonless architectuur:** In tegenstelling tot Docker, dat een centrale daemon (`dockerd`) gebruikt, opereert Podman zonder een dergelijke daemon. Dit draagt bij aan een eenvoudigere architectuur en potentieel minder beveiligingsrisico's [28](#page=28).
* **Rootless containers:** Een van de belangrijkste voordelen van Podman is de ingebouwde ondersteuning voor rootless containers. Dit stelt gebruikers in staat containers te draaien zonder root-privileges, wat de beveiliging aanzienlijk verhoogt. Hoewel Docker ook pogingen doet om rootless containers te ondersteunen, is dit een kernkenmerk van Podman [28](#page=28).
* **Gebruiksscenario's:** Podman is uitermate geschikt voor scenario's waar verbeterde beveiliging en flexibiliteit vereist zijn, zoals in development workflows en omgevingen waar root-toegang beperkt is [36](#page=36).
* **OCI-compatibiliteit:** Podman is OCI-compliant en kan containers bouwen en uitvoeren die voldoen aan de OCI-standaarden, vergelijkbaar met Docker-images [36](#page=36).
### 3.3 LXC / LXD / Incus
LXC (LinuX Containers) is een ouder en meer op het besturingssysteem gerichte containertechnologie, die zich onderscheidt van de applicatiecontainers van OCI/Docker. LXD bouwt hierop voort als een uitgebreider beheerplatform, en Incus is een recente fork van LXD [29](#page=29) [31](#page=31) [34](#page=34).
#### 3.3.1 LXC (LinuX Containers)
LXC is een technologie die zich richt op "system containers" in plaats van "application containers" zoals bij Docker en OCI [31](#page=31) [32](#page=32).
* **System containers:** Deze containers bieden een meer volledige Linux-omgeving, vergelijkbaar met een lichtgewicht virtuele machine, maar dan zonder de overhead van een aparte kernel of hardware-emulatie. Ze kunnen een complete Linux-distributie hosten [32](#page=32) [36](#page=36).
* **Kernel features:** LXC maakt gebruik van de containment-features die worden ondersteund door de Linux-kernel, zoals namespaces en cgroups, voor isolatie [31](#page=31) [36](#page=36).
* **Gebruiksscenario's:** LXC is geschikt voor het draaien van volledige Linux-distributies, development- en testomgevingen die een complete OS-omgeving vereisen [36](#page=36).
#### 3.3.2 LXD
LXD is een uitbreiding op LXC die een gebruikersinterface biedt voor het beheren van containers en deze over het netwerk via een REST API kan beheren [31](#page=31).
* **Beheer en API:** LXD voegt een daemonlaag en API toe om het beheer van LXC-containers te vereenvoudigen en schaalbaarder te maken [31](#page=31).
* **LXCFS:** LXD maakt gebruik van LXCFS (Linux Containers File System), een userspace-filesystem (FUSE) dat container-bewuste functionaliteit biedt, vergelijkbaar met hoe `sshfs` werkt [31](#page=31).
* **Commerciële ondersteuning:** Canonical, bekend van Ubuntu, biedt commerciële ondersteuning voor LXD [31](#page=31).
#### 3.3.3 Incus
Incus is een fork van LXD, gelanceerd door het oorspronkelijke Linux Containers upstream-project en bijdragers van andere distributies, na een licentiewijziging van LXD [34](#page=34).
* **Licentiewijziging van LXD:** In december 2023 werd LXD's licentie gewijzigd van Apache 2.0 naar AGPLv3, een copyleft licentie. Dit, samen met de vereiste van het ondertekenen van een Contributor License Agreement (CLA), leidde tot de oprichting van Incus [34](#page=34).
* **Community-onderhoud:** Incus is een community-onderhouden fork die de ontwikkeling en beschikbaarheid van LXD-functionaliteit voor diverse distributies wil waarborgen, met name in reactie op de licentiewijzigingen [34](#page=34).
#### 3.3.4 LXC/LXD/Incus en OCI
Hoewel LXC/LXD oorspronkelijk niet direct geassocieerd waren met de OCI-standaard, is er groeiende ondersteuning om OCI- en Docker-images te gebruiken binnen deze omgevingen vanwege hun populariteit. Dit maakt de migratie en integratie tussen verschillende containertechnologieën mogelijk [33](#page=33).
### 3.4 Vergelijking van containertechnologieën
| Aspect | LXC/LXD/Incus | Docker | Podman |
| :--------------- | :---------------------------------------------- | :------------------------------------------------- | :------------------------------------------------ |
| **Doel** | Systeemcontainers (volledige OS-omgevingen) | Applicatiecontainers (enkele apps/processen) | Applicatiecontainers (enkele apps/processen) |
| **Architectuur** | Gebruikt LXC-bibliotheken; LXD biedt daemon-management | Daemon-gebaseerd (dockerd) | Daemonless |
| **Gebruiksscenario's** | Volledige Linux distro's, development, testing | Microservices, CI/CD, lichtgewicht deployments | Rootless containers, verbeterde beveiliging |
| **Image Formaat** | Custom (rootfs of tarball-gebaseerd) | OCI-compatibel (Docker images) | OCI-compatibel (Docker images) |
| **Netwerk** | Geavanceerder, ondersteunt bridge/VLAN management | Vereenvoudigd standaard | Zoals Docker, met rootless opties |
| **Resourcegebruik** | Hoger (door volledige OS-functionaliteit) | Lager (ontworpen voor enkele apps/processen) | Zoals Docker |
| **Beveiliging** | Sterke isolatie via namespaces en cgroups | Isolatie via namespaces, seccomp, AppArmor | Focus op rootless containers en isolatie |
| **Certificatie** | | | | [36](#page=36).
> **Tip:** Het is cruciaal om het onderscheid tussen "system containers" en "application containers" te begrijpen, aangezien dit de primaire drijfveer is achter de verschillende ontwerpprincipes en gebruiksscenario's van LXC/LXD/Incus versus Docker/OCI/Podman [31](#page=31) [36](#page=36).
>
> **Voorbeeld:** Als u een complete ontwikkelomgeving nodig heeft die exact lijkt op uw productie-Linux-server, dan zou een LXC/LXD/Incus "system container" geschikter kunnen zijn. Als u echter een specifieke webapplicatie wilt isoleren en snel wilt deployen, dan is een OCI-compatibele "application container" (gemaakt met Docker of Podman) waarschijnlijk de betere keuze [36](#page=36).
---
# Praktische toepassing en experimenten
Dit gedeelte beschrijft de praktische uitvoering van containerisatie door middel van een lab-opzet, waarbij de basistaken met Docker, Podman en LXD/LXC worden behandeld, evenals de stappen voor het opzetten van virtuele machines en het installeren van deze technologieën [37](#page=37).
### 4.1 Container lab setup
Het lab-opzet vereist het uitvoeren van specifieke taken met de genoemde containertechnologieën [39](#page=39).
#### 4.1.1 Basis container taken
Met Docker, Podman en LXD/LXC dient men de volgende basistaken te kunnen uitvoeren [38](#page=38):
* Een container creëren [38](#page=38).
* Een container starten en stoppen [38](#page=38).
* Een commando "in" de container uitvoeren [38](#page=38).
* Een shell verkrijgen en "in" de container kunnen navigeren [38](#page=38).
#### 4.1.2 Docker specifieke taken
Voor Docker dienen de volgende specifieke taken beheerst te worden [38](#page=38):
* Een image bouwen op basis van een Dockerfile [38](#page=38).
* Een instantie van een image draaien [38](#page=38).
* Port-forwarding configureren [38](#page=38).
* Informatie opvragen door de container te inspecteren [38](#page=38).
* Volumes mounten [38](#page=38).
* Een container op de achtergrond starten [38](#page=38).
* Docker Compose gebruiken [38](#page=38).
#### 4.1.3 Virtuele machine en installatie stappen
De voorbereiding voor het lab omvat het opzetten van een virtuele machine en de installatie van de containertechnologieën. Dit proces omvat de volgende stappen [39](#page=39):
* Een nieuwe (Debian) virtuele machine creëren [39](#page=39).
* Na de installatie een snapshot van de virtuele machine maken [39](#page=39).
* Docker installeren, enkele vragen beantwoorden en een voorbeeldproject opzetten [39](#page=39).
* Terugkeren naar een eerder gemaakt snapshot (revert) [39](#page=39).
* Podman installeren [39](#page=39).
* Opnieuw gebruikmaken van snapshots om terug te keren [39](#page=39).
* LXD/LXC installeren [39](#page=39).
> **Tip:** Het maken en gebruiken van snapshots is cruciaal om snel terug te kunnen keren naar een werkende staat na experimenten of mislukte installaties. Dit voorkomt tijdverlies bij het herhaaldelijk opnieuw opzetten van de omgeving [39](#page=39).
---
## Veelgemaakte fouten om te vermijden
- Bestudeer alle onderwerpen grondig voor examens
- Let op formules en belangrijke definities
- Oefen met de voorbeelden in elke sectie
- Memoriseer niet zonder de onderliggende concepten te begrijpen
Glossary
| Term | Definition |
|------|------------|
| Containerisatie | Het proces van het creëren en beheren van geïsoleerde omgevingen op besturingssysteemniveau, waardoor applicaties en hun afhankelijkheden efficiënt kunnen worden verpakt en uitgevoerd. |
| Virtuele machine (VM) | Een gesimuleerde computeromgeving die draait bovenop een fysiek systeem, met een eigen besturingssysteem en hardware-emulatie, wat resulteert in zwaardere overhead dan containers. |
| Operating-system-level virtualization | Een virtualisatietechniek waarbij de kernel van een besturingssysteem meerdere geïsoleerde gebruikersruimte-instanties (containers) toestaat, die dezelfde kernel delen maar hun eigen processen, bestanden en netwerken hebben. |
| Besturingssysteem (OS) | De fundamentele software die de hardware van een computer beheert en basisdiensten levert aan applicaties, zoals geheugenbeheer, procesplanning en bestandsysteemtoegang. |
| Kernel | Het centrale deel van een besturingssysteem dat de hardware van de computer beheert en als tussenlaag fungeert tussen de hardware en de applicatiesoftware. |
| Geïsoleerde processen | Processen die worden uitgevoerd binnen een beperkte omgeving, waardoor ze geen invloed kunnen uitoefenen op andere processen of het gehele systeem en hun eigen bestandssysteem, netwerk en processen hebben. |
| Docker | Een populair platform voor het ontwikkelen, distribueren en draaien van applicaties met behulp van containers, dat een gestandaardiseerde methode biedt om software 'in te schepen' met al zijn afhankelijkheden. |
| Podman | Een daemonless container-engine die fungeert als een alternatief voor Docker, met een focus op rootless containers en verbeterde beveiligingsfuncties, en die ook OCI-compatibele images ondersteunt. |
| LXC (Linux Containers) | Een OS-level virtualisatie-technologie voor Linux die systeemcontainers biedt, vergelijkbaar met lichtgewicht virtuele machines, en die een breed scala aan inkapselingsfuncties van de Linux-kernel benut. |
| LXD (Linux Container Daemon) | Een extensie op LXC die een gebruikersinterface en beheerfunctionaliteit biedt voor containers, inclusief netwerkbeheer en een REST API voor externe interactie. |
| Incus | Een fork van LXD, gelanceerd na een licentiewijziging van LXD, die gemeenschapsgestuurd onderhoud en ontwikkeling nastreeft en compatibiliteit met OCI-images nastreeft. |
| OCI (Open Container Initiative) | Een standaardisatie-initiatief dat industriestandaarden definieert voor containerformaten en runtimes, met als doel interoperabiliteit tussen verschillende containertechnologieën te waarborgen. |
| Registratie (Registry) | Een opslagplaats voor container-images, zoals Docker Hub of een privé-registratie, waar images kunnen worden opgeslagen, gedeeld en gedownload. |
| Image | Een lichtgewicht, uitvoerbaar, stand-alone softwarepakket dat alles bevat wat nodig is om een stuk software te draaien: code, runtime, systeengereedschappen, systeembibliotheken en instellingen. |
| Container | Een draaiende instantie van een image, die een geïsoleerde omgeving biedt waarin de applicatie kan worden uitgevoerd. |
| Dockerfile | Een tekstbestand dat instructies bevat voor het bouwen van een Docker-image, vergelijkbaar met een recept voor het creëren van de applicatieomgeving. |
| Multi-stage dockerfile | Een methode om Dockerfiles te optimaliseren door verschillende bouwfases te gebruiken, waarbij alleen de benodigde artefacten (zoals de gecompileerde applicatie) in de uiteindelijke image worden opgenomen, wat resulteert in kleinere en veiligere images. |
| Docker Compose | Een tool voor het definiëren en beheren van multi-container Docker-applicaties, waarbij de configuratie wordt vastgelegd in een YAML-bestand (`docker-compose.yml`). |
| Containerd | Een industriestandaard container runtime die wordt gebruikt om het levenscyclusbeheer van containers te automatiseren, vaak onderliggend aan hogere-level tools zoals Docker. |
| runc | Een lichtgewicht, cross-platform tool om containers te creëren en te draaien volgens de OCI-specificaties, vaak gebruikt als de lage-niveau runtime door containertechnologieën zoals Docker en Containerd. |
| REST API | Een architectuurstijl voor het ontwerpen van netwerkapplicaties die gebruikmaakt van HTTP-verzoeken om te communiceren tussen een client en een server, vaak gebruikt om container-orchestratietools te beheren. |
| Rootless containers | Containers die worden uitgevoerd zonder dat de gebruiker root-rechten nodig heeft, wat de beveiliging verbetert door het potentiële aanvalsoppervlak te verkleinen. |
| Systeemcontainer | Een container die is ontworpen om een volledig besturingssysteem te emuleren, inclusief meerdere services en processen, vergelijkbaar met een lichtgewicht virtuele machine. |
| Applicatiecontainer | Een container die is ontworpen om een enkele applicatie of een specifieke set processen te huisvesten, geoptimaliseerd voor snelle implementatie en efficiëntie. |