Verschil tussen FreeBSD jails en Docker containers
FreeBSD jails isoleren een volledige userland, terwijl Docker werkt met gelaagde images. Ontdek de verschillen in netwerkbeheer, opslag en procesbeheer voor uw workload.
FreeBSD jails versus Docker containers, in één alinea
FreeBSD jails en Docker containers lossen hetzelfde probleem op, maar in een andere vorm. Beide draaien geïsoleerde userlands op één gedeelde kernel, waardoor geen van beide een virtuele machine is. Het verschil zit in de inhoud. Een Docker container voert één proces uit vanuit een gelaagde image die u uit een registry heeft opgehaald. Een jail draait een volledige FreeBSD userland: met een eigen /etc, eigen rc-opstartscripts, een eigen pkg database en zoveel processen als u wilt. Vrijwel elk ander verschil op deze pagina vloeit voort uit dit fundamentele onderscheid.
SSD Nodes biedt geen FreeBSD images aan. U kunt op dit platform geen FreeBSD server huren en onderstaande tekst is geen installatiehandleiding voor een machine die u hier kunt aanschaffen. Dit is een vergelijking van twee isolatiemodellen, geschreven zodat u kunt bepalen welk model uw workload vereist en zodat u de configuratie van een FreeBSD-team kunt begrijpen zonder te hoeven gissen.
Wat een jail precies is
Jails werden in maart 2000 geïntroduceerd in FreeBSD 4.0, wat ze ouder maakt dan cgroups en ongeveer een decennium ouder dan Docker. Het mechanisme is gebaseerd op één kernel-aanroep. jail(8) neemt een mappenstructuur en start processen daarbinnen met een gekoppeld jail-ID; de kernel weigert vervolgens een vastgestelde set operaties voor elk proces dat dit ID draagt. Een proces in een jail kan geen processen buiten de jail zien, kan geen bestandssystemen koppelen of ontkoppelen, kan geen kernelmodules laden en kan niet binden aan netwerkadressen die niet aan de jail zijn toegewezen. Er is geen apart type namespace om te leren en geen opt-in per functie: de beperkingen komen als één geheel, aangepast via parameters in de configuratie van de jail.
Op de host toont jls de actieve jails en brengt jexec web sh u naar een shell binnen de jail genaamd web.
U bouwt een jail door een FreeBSD userland in een map te plaatsen. Het basissysteem doet dit voor u:
sudo bsdinstall jail /usr/local/jails/containers/webDit haalt de basisdistributieset voor uw release op en voert de gebruikelijke post-installatiestappen uit, zodat u een root-wachtwoord instelt en een tijdzone kiest, precies zoals u dat op een nieuwe server zou doen. Het resultaat is een FreeBSD-installatie in een map. Vervolgens beschrijft u deze in /etc/jail.conf:
web {
host.hostname = "web.example.internal";
path = "/usr/local/jails/containers/web";
ip4.addr = "10.0.0.10";
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
mount.devfs;
}Start de jail en controleer deze vervolgens:
sudo service jail start web
jlsjls zou nu web moeten weergeven met een JID, de hostnaam en het IP-adres. Als de jail niet verschijnt, voer dan sudo jail -c web direct uit. Dit past dezelfde configuratie toe in de voorgrond en toont de parameter die niet kon worden geaccepteerd, in plaats van de foutmelding in de service-output achter te laten.
De regel die het waard is om twee keer te lezen is exec.start = "/bin/sh /etc/rc". Het starten van een jail voert het normale opstartscript van FreeBSD daarbinnen uit, waardoor de jail elke service opstart die in zijn eigen /etc/rc.conf is ingeschakeld. Een Docker-container heeft geen equivalente stap, omdat deze het entrypoint-proces van de image uitvoert en stopt wanneer dat proces stopt.
Hoe u software binnenhaalt: images en registries versus een userland die u zelf vult
Dit is het verschil dat u vanaf de eerste dag merkt.
Met Docker benoemt u software en ontvangt u deze. docker pull nginx haalt een gelaagde, op inhoud geadresseerde image op die door iemand anders is gebouwd en getest, en docker compose up -d start deze met de bijbehorende volumes en netwerkconfiguratie. De registry is het product. Het grootste deel van de waarde in een Docker-workflow is dat duizenden projecten een werkende image publiceren, wat het draaien van Docker op een VPS tot een korte taak maakt in plaats van een langdurig project.
FreeBSD levert geen standaard publieke registry met jail-images. U creëert een lege userland en installeert daar software in, op dezelfde manier als bij het inrichten van een bare-metal server. Dat vereist meer typewerk. Het is echter ook transparanter, omdat wat er in de jail draait, precies datgene is wat pkg daar heeft geplaatst, afkomstig uit dezelfde pakketset die de host gebruikt.
Tooling maakt dit proces kort. BastilleBSD is de gangbare jail-manager en is beschikbaar als pakket:
sudo pkg install bastille
sudo sysrc bastille_enable=YES
sudo bastille setup
sudo bastille bootstrap 15.1-RELEASEbastille setup configureert netwerken, opslag en de firewall voor u. bastille bootstrap downloadt een release één keer, en elke jail die u daarna aanmaakt, hergebruikt deze. FreeBSD 15.1 is de huidige productie-release, uitgebracht in juni 2026; vervang dit door de release die u gebruikt.
Het aanmaken van een jail is vervolgens één commando, en het vullen ervan nog één:
sudo bastille create web 15.1-RELEASE 10.17.89.10/24
sudo bastille pkg web install nginx
sudo bastille service web nginx start
sudo bastille console webbastille console web geeft u een login-shell binnen de jail, en bastille list toont wat er op de host aanwezig is. Om een build te herhalen, bevatten Bastille-templates de stappen in een bestand die vervolgens op een jail worden toegepast; dit is het dichtstbijzijnde equivalent van een Dockerfile in deze wereld. Een template wordt op elke jail opnieuw uitgevoerd. Niets wordt vooraf gebouwd aangeleverd.
De eerlijke samenvatting is dus kort. Docker geeft u de builds van anderen. Jails geven u uw eigen installaties. Als de software op uw shortlist uitsluitend als container-image wordt geleverd, dan is de keuze al gemaakt voordat andere factoren een rol spelen.
Status en upgrades: de rol van ZFS
Docker scheidt de status bewust van de applicatie. Het bestandssysteem van de container is tijdelijk, uw data bevindt zich in een named volume of een bind mount, en een upgrade is docker compose pull gevolgd door docker compose up -d. De container wordt vervangen en alles wat u niet in een volume hebt geplaatst, is verdwenen. Dat is een functie wanneer u de regel volgt, en een incident met dataverlies wanneer u het vergeet. Daarom is de keuze tussen bind mounts en named volumes zo bepalend in een Compose-stack.
Een jail scheidt de status niet, en ZFS is de reden dat dit werkt. De gehele jail is één dataset:
sudo zfs snapshot zroot/jails/containers/web@pre-upgrade
sudo pkg -j web upgrade
sudo zfs rollback zroot/jails/containers/web@pre-upgradeControleer de werkelijke datasetnaam met zfs list voordat u dit uitvoert; het bovenstaande pad is de indeling die het handboek gebruikt. De snapshot duurt ongeveer een seconde en kost vrijwel geen ruimte totdat de inhoud van de jail verandert. Als de upgrade de service onklaar maakt, herstelt de rollback de gehele userland naar de eerdere status, inclusief de pakketdatabase en de configuratiebestanden die u handmatig om 02:00 uur hebt bewerkt. Docker heeft geen ingebouwd equivalent, omdat het model ervan uitgaat dat u dit nooit nodig had.
zfs clone is de andere helft. Een kloon van een snapshot is een nieuwe beschrijfbare jail die ongewijzigde blokken deelt met de parent. Een staging-kopie van een jail van 3 GB kost daarom vrijwel niets op schijf totdat u deze begint te wijzigen. Zo bouwt een FreeBSD-beheerder een "identiek aan productie" jail om een upgrade te oefenen.
De upgrade van het basissysteem staat los van pakketten. Voor een jail die een eigen kopie van de userland bevat:
sudo freebsd-update -b /usr/local/jails/containers/web fetch installThin jails voorkomen dat dit werk wordt herhaald. Ze koppelen één gedeelde, alleen-lezen base via nullfs en geven elke jail een eigen kleine beschrijfbare laag. U patcht de base dus één keer en elke jail ziet het resultaat. Bastille maakt standaard thin jails aan.
Netwerkbeheer: gepubliceerde poorten versus een adresseringsbesluit
Docker bepaalt het netwerk voor u en vraagt u om de uitzonderingen te publiceren. Containers landen op een bridge, ze bereiken elkaar via de servicenaam op een door de gebruiker gedefinieerd netwerk, en -p 8080:80 stelt een van hen bloot aan de host. Docker schrijft zijn eigen packet filter-regels om dit mogelijk te maken; dit is ook de reden waarom een gepubliceerde containerpoort direct langs ufw gaat.
Een jail dwingt u om vooraf een model te kiezen, en er zijn er twee.
Shared IP. ip4.addr = "10.0.0.10" voegt dat adres toe aan een bestaande host-interface en beperkt de jail daartoe. De jail heeft geen eigen netwerkstack, dus kan deze geen eigen firewall draaien. De jail kan ook niet echt binden aan elk adres: een jailed socket die vraagt om 0.0.0.0 wordt door de kernel herschreven naar het eigen adres van de jail. Twee jails kunnen niet beide op poort 80 van hetzelfde adres luisteren, dus geeft u ze elk een adres, of u plaatst een reverse proxy ervoor.
VNET. Voeg vnet; toe aan de jail en deze krijgt een volledige netwerkstack: eigen interfaces, een eigen routeringstabel en eigen firewallregels. U verbindt de jail met de host via een epair, een virtuele kabel met aan beide kanten een uiteinde, en plaatst de kant van de host op een bridge. Dit komt het dichtst in de buurt van wat Docker biedt, en het is de modus achter de -V- en -B-jailtypes van Bastille.
Het doorsturen van een hostpoort naar een jail is een pf-redirectregel. Bastille verpakt dit:
sudo bastille rdr web tcp 80 80Er is geen EXPOSE en geen automatische publicatie. Niets bereikt een jail tenzij het adres of een redirectregel dit toestaat. Dat zorgt voor een langzamere start en een veel stillere firewall.
Resource limits: cgroups vs rctl
Docker limits a container with cgroups, and the limits live where the container is defined: --memory=1g --cpus=1.5 on the command line, or the matching keys in a Compose file. If you already keep your stack in a Docker Compose file on a VPS, the limit sits beside the service it applies to and travels with it in git.
FreeBSD uses rctl, and it is a subsystem you have to switch on. Resource accounting is off by default because it costs a little on every allocation. Add the tunable to /boot/loader.conf and reboot:
kern.racct.enable=1Then set a rule and watch it:
sudo rctl -a jail:web:vmemoryuse:deny=1g
rctl -hu jail:webrctl -hu jail:web prints the jail's current usage in human-readable units, so you can see how close it sits to the limit before anything breaks. The deny action makes the over-limit allocation fail inside the jail, so you see the application's own allocation error rather than a kill message on the host.
Rules added with rctl -a vanish at the next reboot. FreeBSD's rctl service reloads them from /etc/rctl.conf, so write the rule into that file and enable the service:
sudo sysrc rctl_enable=YESThis is the axis where Docker is plainly more convenient. A limit in a Compose file is reviewed with the service it constrains. An rctl rule is a line in a separate file naming a jail defined somewhere else.
Wanneer het antwoord een virtuele machine is: bhyve
Een jail deelt de kernel van de host, waardoor sommige zaken permanent onbereikbaar zijn. Het kan geen andere kernelversie draaien, het kan geen kernelmodule laden en het kan geen Linux-binaries uitvoeren op de manier zoals een Linux-container dat doet. FreeBSD beschikt over een Linux-compatibiliteitslaag, de linuxulator, maar deze implementeert slechts een subset van de Linux-systeemaanroepen en is geen algemene oplossing voor willekeurige Linux-images.
bhyve is de hypervisor van FreeBSD en is het juiste hulpmiddel wanneer u een echte machinegrens nodig heeft: een ander besturingssysteem, een andere kernel of een tenant waarmee u liever geen kernel deelt. U betaalt hiervoor in de vorm van geheugen dat gereserveerd wordt in plaats van gedeeld, en een tweede kernel die u moet patchen. Dit is dezelfde afweging die u op Linux maakt tussen containers en volledige virtuele machines, en het is de beslissing die bepaalt of u een VPS die nested virtualization ondersteunt nodig heeft.
Het ecosysteem, de eerlijke reden waarom de meeste teams Docker gebruiken
Alles hierboven gaat over het model. Wat voor de meeste teams de doorslag geeft, is de omvang van de wereld rondom elk platform.
Docker brengt Docker Hub en GHCR, docker compose, Kubernetes wanneer één server niet langer volstaat, CI-runners met ingebouwde containerondersteuning en een quickstart met één commando in de README van vrijwel elk project. Jails bieden de FreeBSD ports tree, die groot en zorgvuldig onderhouden is, plus een veel kleinere set kant-en-klare applicatiebundels. Wanneer een project enkel een container image publiceert, is de FreeBSD-route om de documentatie te lezen en de onderdelen zelf samen te stellen.
Jails verdienen hun plek aan de andere kant van die afweging. U kiest voor Jails wanneer u al ZFS gebruikt en waarde hecht aan snapshots en rollbacks van een volledige service, wanneer uw services FreeBSD-native zijn, wanneer u een volledig userland per tenant wilt in plaats van een enkel proces, of wanneer u wilt dat de kernel, de packet filter, het bestandssysteem en de documentatie als één systeem worden onderhouden. Dat laatste punt is wat men bedoelt wanneer men FreeBSD coherent noemt, en dit krijgt meer aandacht in de bredere vergelijking tussen Linux en FreeBSD als serverplatform en in wat FreeBSD 15 heeft veranderd voor servergebruik.
Een afsluitend oordeel. Als uw team Docker al kent, is de overstap kostbaar en moet de opbrengst specifiek zijn. Stap niet over vanwege de isolatiekwaliteit; de twee modellen liggen dicht genoeg bij elkaar dat uw configuratie meer gewicht in de schaal legt. Stap over omdat u ZFS-gebaseerde rollbacks van volledige services wilt, of omdat u al op FreeBSD werkt.
FAQ
Kan ik Docker-images draaien op FreeBSD?
Geen Linux-images, en niet als een ondersteund pad. FreeBSD heeft wel ondersteuning voor OCI-containers: sudo pkg install -y podman-suite installeert Podman, dat containers draait via ocijail, een runtime die daadwerkelijke jails aanmaakt. Het vereist fdescfs gemount op /dev/fd voor de containermonitor, en pf voor container NAT (network address translation). FreeBSD-native OCI-images werken het best. Linux-images vereisen daarnaast de Linux-compatibiliteitslaag, en per augustus 2026 wordt de FreeBSD Podman-port nog steeds als experimenteel beschreven. Als uw deployment een stack van Linux-images is, draai deze dan op Linux.
Zijn FreeBSD jails veiliger dan Docker-containers?
Beide delen één host-kernel, dus een kernel-bug vormt voor beide een risico, en geen van beide is de grens die u zou kiezen voor werkelijk onbetrouwbare code. Het verschil zit in het uitgangspunt. Een jail begint met een brede set geweigerde operaties die u per parameter opnieuw inschakelt. Een Docker-container begint als root binnen een set namespaces waarbij enkele privileges zijn verwijderd, en verdere beveiliging is optioneel. In de praktijk bepaalt de configuratie meer dan het model: een jail die draait met allow.mount en allow.raw_sockets ingeschakeld is niet veiliger dan een zorgvuldig geconfigureerde container.
Hoe maak ik een back-up van een jail?
Maak een snapshot van de dataset en verstuur deze. sudo zfs snapshot zroot/jails/containers/web@backup, en vervolgens zfs send dat snapshot naar een andere pool of naar een bestand dat u van de machine kopieert. Omdat een jail zijn volledige userland in één dataset bewaart, legt het snapshot de geïnstalleerde pakketten en de data op één consistent punt vast, samen met elk configuratiebestand dat u handmatig heeft bewerkt. Dat is het tegenovergestelde van de Docker-gewoonte, waarbij u de named volumes en het Compose-bestand back-upt en de rest opnieuw opbouwt vanuit de image.
Heb ik BastilleBSD nodig, of is het basissysteem voldoende?
Het basissysteem is voldoende, en het is de betere plek om te beginnen. jail.conf, jls, jexec en service jail start dekken het gehele model, en zodra u deze kent, kunt u elke FreeBSD-host lezen zonder eerst de tooling van die specifieke host te hoeven leren. Bastille is een gemaklaag daarbovenop: het bootstrapt releases, maakt thin jails aan, past templates toe en schrijft pf redirect-regels voor u. Leer eerst de basiscommando's en voeg Bastille toe wanneer het aantal jails het typwerk bewerkelijk maakt.