FreeBSD jails kumpara sa Docker containers
Alamin kung paano naiiba ang FreeBSD jails at Docker sa userland, layered images, state, networking, software at resource limits, pati ang caveat sa FreeBSD images.
FreeBSD jails kumpara sa Docker containers, sa isang talata
Parehong nilulutas ng FreeBSD jails at Docker containers ang parehong problema, pero magkaiba ang anyo ng pagpapatupad ng mga ito. Pareho silang nagpapatakbo ng magkakahiwalay na userland sa iisang shared kernel, kaya hindi virtual machine ang alinman sa mga ito. Ang pagkakaiba ay nasa nilalaman ng mga ito. Nagpapatakbo ang Docker container ng isang process mula sa layered image na kinuha mo sa registry. Nagpapatakbo naman ang jail ng kumpletong FreeBSD userland: sarili nitong /etc, sarili nitong rc startup scripts, sarili nitong pkg database, at kahit ilang process na kailangan mo. Halos lahat ng iba pang pagkakaiba sa page na ito ay nagmumula sa puntong iyon.
Hindi nag-aalok ang SSD Nodes ng FreeBSD images. Hindi ka makakapag-rent ng FreeBSD server sa platform na ito, at hindi install guide para sa machine na mabibili mo rito ang anumang nasa ibaba. Paghahambing ito ng dalawang isolation model, na isinulat upang matukoy mo kung alin ang talagang kailangan ng isang workload at upang mabasa mo ang setup ng isang FreeBSD team nang hindi nanghuhula.
Kung ano talaga ang jail
Dumating ang jails sa FreeBSD 4.0 noong March 2000, kaya mas luma ang mga ito kaysa sa cgroups at humigit-kumulang isang dekada na mas luma kaysa sa Docker. Isang kernel call ang mekanismong ito. Kinukuha ng jail(8) ang isang directory tree at sinisimulan ang mga process sa loob nito na may kalakip na jail ID. Pagkatapos, tinatanggihan ng kernel ang isang takdang hanay ng mga operation para sa anumang process na may ID na iyon. Hindi makikita ng isang jailed process ang mga process sa labas ng jail nito. Hindi rin ito makakapag-mount o makakapag-unmount ng filesystem, makakapag-load ng kernel module, o makakapag-bind sa network address na hindi itinalaga sa jail. Walang hiwalay na namespace type na kailangang pag-aralan at walang opt-in para sa bawat feature. Dumarating ang mga restriction bilang isang unit at ina-adjust sa pamamagitan ng mga parameter sa config ng jail.
Sa host, inililista ng jls ang mga tumatakbong jail. Ang jexec web sh naman ay nagbubukas ng shell sa jail na pinangalanang web.
Gumagawa ka ng jail sa pamamagitan ng paglalagay ng FreeBSD userland sa isang directory. Awtomatikong ginagawa ito ng base system:
sudo bsdinstall jail /usr/local/jails/containers/webKinukuha nito ang base distribution set para sa iyong release at pinapatakbo ang karaniwang post-install steps. Kaya magse-set ka ng root password at pipili ng timezone gaya ng ginagawa mo sa isang bagong server. Ang resulta ay isang FreeBSD installation na nasa loob ng isang folder. Pagkatapos, inilalarawan mo ito sa /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;
}Simulan ito, pagkatapos ay i-check:
sudo service jail start web
jlsDapat nang ilista ng jls ang web kasama ang JID, hostname, at IP address nito. Kung hindi lumitaw ang jail, direktang patakbuhin ang sudo jail -c web. Pareho nitong ginagamit ang configuration sa foreground at ipinapakita ang parameter na hindi nito matanggap, sa halip na iwan ang failure sa service output.
Ang linyang dapat basahin nang dalawang beses ay exec.start = "/bin/sh /etc/rc". Kapag nagsimula ng jail, pinapatakbo nito ang normal na boot script ng FreeBSD sa loob nito. Dahil dito, sinisimulan ng jail ang bawat service na naka-enable sa sarili nitong /etc/rc.conf. Walang katumbas na hakbang ang Docker container, dahil pinapatakbo nito ang entrypoint process ng image at humihinto kapag huminto ang process na iyon.
Paano kumukuha ng software: images at registries kumpara sa userland na ikaw ang nagse-set up
Ito ang pagkakaibang mararamdaman mo sa unang araw pa lang.
Sa Docker, tinutukoy mo ang software at natatanggap mo ito. Kinukuha ng docker pull nginx ang layered at content-addressed na image na binuo at sinubukan ng ibang tao, at sinisimulan ito ng docker compose up -d kasama ang mga volume at network nito. Ang registry ang pangunahing produkto. Karamihan sa halaga ng Docker workflow ay nagmumula sa libo-libong project na nagpa-publish ng gumaganang image. Dahil dito, nagiging maikling gawain lang ang pagpapatakbo ng Docker sa isang VPS sa halip na isang buong proyekto.
Walang default na public registry ng jail images ang FreeBSD. Gumagawa ka ng walang laman na userland at nag-i-install dito, gaya ng pagse-set up ng bare server. Mas marami itong tina-type. Mas transparent din ito, dahil ang tumatakbo sa jail ay ang inilagay ng pkg, mula sa parehong package set na ginagamit ng host.
Pinapadali ito ng tooling. Ang BastilleBSD ang karaniwang jail manager, at isa itong package:
sudo pkg install bastille
sudo sysrc bastille_enable=YES
sudo bastille setup
sudo bastille bootstrap 15.1-RELEASEKino-configure ng bastille setup ang networking, storage, at firewall para sa iyo. Isang beses lang nagda-download ng release ang bastille bootstrap, at muling ginagamit ito ng bawat jail na gagawin mo pagkatapos. Ang FreeBSD 15.1 ang kasalukuyang production release, na inilabas noong June 2026; palitan ito ng release na ginagamit mo.
Isang command lang ang paggawa ng jail, at isa pa ang paglalagay ng software dito:
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 webBinibigyan ka ng bastille console web ng login shell sa loob ng jail, at ipinapakita ng bastille list kung ano ang nasa host. Para maulit ang isang build, inilalagay ng Bastille templates ang mga hakbang sa isang file at ina-apply ang mga ito sa isang jail. Ito ang pinakamalapit na katumbas ng Dockerfile sa ganitong environment. Inuulit ang template sa bawat jail. Walang dumarating na prebuilt.
Maikli ang tapat na buod. Ibinibigay sa iyo ng Docker ang mga build ng ibang tao. Ibinibigay sa iyo ng jails ang sarili mong mga installation. Kung ang software sa shortlist mo ay inilalabas bilang container image at wala nang ibang anyo, iyon na ang nagpapasya bago pa bumoto ang ibang pamantayan.
State at upgrades: ang bahaging binabago ng ZFS
Sadyang hinahati ng Docker ang state. Disposable ang container filesystem, nasa named volume o bind mount ang data mo, at ang upgrade ay docker compose pull na sinusundan ng docker compose up -d. Pinapalitan ang container, at mawawala ang anumang hindi mo inilagay sa volume. Feature ito kapag sinusunod mo ang rule, pero magiging insidente ng data loss kapag nakalimutan mo ito. Kaya napakahalaga sa Compose stack ng pagpili sa pagitan ng bind mounts at named volumes.
Hindi hinahati ng jail ang state, at ZFS ang dahilan kung bakit gumagana ito. Isang dataset ang buong jail:
sudo zfs snapshot zroot/jails/containers/web@pre-upgrade
sudo pkg -j web upgrade
sudo zfs rollback zroot/jails/containers/web@pre-upgradeTingnan ang aktuwal na dataset name gamit ang zfs list bago mo ito patakbuhin. Ang path sa itaas ang layout na ginagamit ng handbook. Humigit-kumulang isang segundo ang snapshot at halos walang ginagamit na space hanggang sa magbago ang laman ng jail. Kung masira ng upgrade ang serbisyo, ibinabalik ng rollback ang buong userland sa dating state nito, kabilang ang package database at mga config file na mano-mano mong in-edit noong 2am. Walang built-in na katumbas nito ang Docker dahil ipinapalagay ng model nito na hindi mo kailanman kailangan ang ganitong capability.
zfs clone ang kabilang bahagi. Ang clone ng snapshot ay isang bagong writable jail na nagse-share ng mga block na hindi nagbago sa parent nito. Kaya halos walang dagdag na disk space ang staging copy ng 3 GB jail hanggang sa magsimula kang magbago rito. Sa ganitong paraan gumagawa ang isang FreeBSD admin ng jail na “kapareho ng production” para isagawa muna ang upgrade.
Hiwalay ang upgrade ng base system sa packages. Para sa jail na may sarili nitong kopya ng userland:
sudo freebsd-update -b /usr/local/jails/containers/web fetch installHindi na inuulit ng thin jails ang gawaing ito. Nagmo-mount ang mga ito ng isang shared read-only base sa pamamagitan ng nullfs at binibigyan ang bawat jail ng sarili nitong maliit na writable layer. Kaya isang beses mo lang ipa-patch ang base at makikita ng bawat jail ang resulta. Bilang default, gumagawa ang Bastille ng thin jails.
Networking: mga published port kumpara sa pagpili ng addressing model
Si Docker ang nagdedesisyon ng networking at hinihiling sa iyo na i-publish ang mga exception. Napupunta ang mga container sa isang bridge, nagkakaugnayan sila gamit ang service name sa isang user-defined network, at inilalantad ng -p 8080:80 ang isa sa mga ito sa host. Gumagawa si Docker ng sarili nitong packet filter rules para mangyari ito. Ito rin ang dahilan kung bakit direktang nalalampasan ng published container port ang ufw.
Pinapapili ka ng jail ng model mula sa simula, at may dalawang opsyon.
Shared IP. Idinaragdag ng ip4.addr = "10.0.0.10" ang address na iyon sa isang umiiral na host interface at nililimitahan dito ang jail. Walang sarili nitong network stack ang jail, kaya hindi ito makapagpapatakbo ng sarili nitong firewall. Hindi rin nito tunay na maibind ang sarili sa bawat address: kapag humingi ang isang jailed socket ng 0.0.0.0, nire-rewrite ito ng kernel bilang sariling address ng jail. Hindi maaaring parehong makinig ang dalawang jail sa port 80 ng iisang address. Kaya binibigyan mo ng tig-iisang address ang mga ito, o naglalagay ka ng reverse proxy sa unahan.
VNET. Idinaragdag ang vnet; sa jail at nakakakuha ito ng buong network stack: sarili nitong interfaces, routing table, at firewall rules. Ikinokonekta mo ito sa host gamit ang epair, isang virtual cable na may tig-isang dulo sa magkabilang panig, at inilalagay ang dulo sa host sa isang bridge. Ito ang pinakamalapit na katumbas ng ibinibigay ni Docker, at ito ang mode sa likod ng -V at -B jail types ng Bastille.
Ang pag-forward ng host port papunta sa jail ay isang pf redirect rule. Binabalot ito ng Bastille:
sudo bastille rdr web tcp 80 80Walang EXPOSE at walang automatic publishing. Walang makararating sa jail maliban kung pinapayagan ito ng address nito o ng redirect rule. Mas mabagal itong simulan, pero mas tahimik ang firewall.
Mga limit sa resource: cgroups kumpara sa rctl
Nililimitahan ng Docker ang isang container gamit ang cgroups, at nasa definition ng container ang mga limit: --memory=1g --cpus=1.5 sa command line, o ang katumbas na key sa isang Compose file. Kung nasa Docker Compose file sa isang VPS na ang stack mo, nasa tabi ng service na sakop nito ang limit at kasama itong napapanatili sa git.
Gumagamit ang FreeBSD ng rctl, at kailangan mong i-enable ang subsystem na ito. Naka-off bilang default ang resource accounting dahil may maliit itong dagdag na gastos sa bawat allocation. Idagdag ang tunable sa /boot/loader.conf at mag-reboot:
kern.racct.enable=1Pagkatapos, magtakda ng rule at i-monitor ito:
sudo rctl -a jail:web:vmemoryuse:deny=1g
rctl -hu jail:webIpinapakita ng rctl -hu jail:web ang kasalukuyang resource usage ng jail sa mga unit na madaling basahin, kaya makikita mo kung gaano na ito kalapit sa limit bago magkaroon ng problema. Dahil sa deny action, magfa-fail ang allocation na lumampas sa limit sa loob ng jail. Dahil dito, makikita mo ang sariling allocation error ng application sa halip na kill message sa host.
Nawawala sa susunod na reboot ang mga rule na idinagdag gamit ang rctl -a. Nire-reload ng FreeBSD's rctl service ang mga ito mula sa /etc/rctl.conf, kaya isulat ang rule sa file na iyon at i-enable ang service:
sudo sysrc rctl_enable=YESIto ang aspeto kung saan malinaw na mas convenient ang Docker. Sa Compose file, nire-review ang limit kasama ng service na nililimitahan nito. Ang rctl rule ay isang line sa hiwalay na file na tumutukoy sa isang jail na nade-define sa ibang lugar.
Kapag virtual machine ang kailangan: bhyve
Ibinabahagi ng jail ang kernel ng host, kaya may mga bagay na permanente nitong hindi maa-access. Hindi ito makakapagpatakbo ng ibang kernel version, hindi ito makakapag-load ng kernel module, at hindi ito makakapagpatakbo ng Linux binaries sa paraang ginagawa ng Linux container. May Linux compatibility layer ang FreeBSD na tinatawag na linuxulator, ngunit subset lamang ng Linux system calls ang ipinapatupad nito. Hindi ito pangkalahatang solusyon para sa anumang Linux image.
Ang bhyve ang hypervisor ng FreeBSD, at ito ang tamang tool kapag kailangan mo ng tunay na boundary sa pagitan ng mga machine: ibang operating system, ibang kernel, o tenant na mas gusto mong hindi makibahagi sa kernel. Kapalit nito ang memory na nire-reserve sa halip na ibinabahagi, pati ang karagdagang kernel na kailangang i-patch. Ito rin ang parehong desisyong ginagawa mo sa Linux sa pagitan ng containers at full virtual machines. Ito ang nagtatakda kung kailangan mo ng VPS na sumusuporta sa nested virtualization sa ilalim.
Ang ecosystem, ang tapat na dahilan kung bakit Docker ang ginagamit ng karamihan sa mga team
Ang lahat ng nasa itaas ay tungkol sa modelo. Para sa karamihan ng mga team, ang laki ng ecosystem sa paligid ng bawat modelo ang tunay na nagdedesisyon sa pagpili.
Kasama sa Docker ang Docker Hub at GHCR, docker compose, Kubernetes kapag hindi na sapat ang isang server, mga CI runner na may naka-configure nang container support, at one-command quickstart sa README ng halos bawat project. Kasama naman sa Jails ang FreeBSD ports tree, na malawak at maingat na mina-maintain, pati ang mas maliit na set ng mga application bundle na handa nang patakbuhin. Kapag container image lang at wala nang ibang package ang inilabas ng isang project, ang FreeBSD route ay basahin ang documentation nito at ikaw mismo ang mag-assemble ng mga bahagi.
May malinaw na gamit ang Jails sa kabilang panig ng trade-off na ito. Piliin ang mga ito kung gumagamit ka na ng ZFS at mahalaga sa iyo ang snapshot at rollback ng isang buong service, kung FreeBSD-native ang mga service mo, kung gusto mo ng kumpletong userland para sa bawat tenant sa halip na iisang process lang, o kung gusto mong sama-samang i-maintain ang kernel, packet filter, filesystem, at documentation bilang iisang system. Ito ang tinutukoy ng mga tao kapag sinasabi nilang coherent ang FreeBSD, at mas malawak itong tinatalakay sa mas malawak na paghahambing ng Linux at FreeBSD bilang mga server platform at sa mga pagbabagong ginawa ng FreeBSD 15 para sa paggamit bilang server.
Isang huling hatol. Kung marunong na ang team mo sa Docker, tunay ang cost ng paglipat at dapat tiyak ang pakinabang. Huwag lumipat dahil lang sa kalidad ng isolation; sapat na magkalapit ang dalawang modelo kaya mas mahalaga ang configuration mo. Lumipat dahil gusto mo ng ZFS-backed rollback para sa buong service, o dahil gumagamit ka na ng FreeBSD.
FAQ
Maaari ba akong magpatakbo ng Docker images sa FreeBSD?
Hindi Linux images, at hindi ito isang suportadong paraan. May suporta ang FreeBSD para sa OCI containers: ini-install ng sudo pkg install -y podman-suite ang Podman, na nagpapatakbo ng containers sa pamamagitan ng ocijail, isang runtime na lumilikha ng aktuwal na jails sa ilalim nito. Kailangan nitong naka-mount ang fdescfs sa /dev/fd para sa container monitor, at ang pf para sa container NAT (network address translation). Pinakamahusay gumana ang mga OCI image na native sa FreeBSD. Kailangan din ng Linux compatibility layer para sa Linux images, at hanggang Agosto 2026, inilalarawan pa rin bilang experimental ang FreeBSD Podman port. Kung stack ng Linux images ang deployment mo, patakbuhin ito sa Linux.
Mas secure ba ang FreeBSD jails kaysa sa Docker containers?
Pareho silang gumagamit ng iisang host kernel, kaya panganib sa pareho ang kernel bug, at hindi ang alinman sa mga ito ang boundary na pipiliin mo para sa talagang untrusted na code. Ang kaibahan ay nasa panimulang configuration. Nagsisimula ang jail na may malawak na set ng mga operasyong tinatanggihan, at isa-isa mong muling ie-enable ang mga ito gamit ang mga parameter. Nagsisimula naman ang Docker container bilang root sa loob ng set ng namespaces na may ilang capability na inalis, at opt-in ang karagdagang hardening. Sa praktika, mas malaki ang epekto ng configuration kaysa sa modelo: ang jail na may naka-enable na allow.mount at allow.raw_sockets ay hindi mas ligtas kaysa sa maingat na naka-configure na container.
Paano ako magba-back up ng jail?
Gumawa ng snapshot ng dataset at ipadala ito. sudo zfs snapshot zroot/jails/containers/web@backup, saka zfs send ang snapshot sa ibang pool o sa isang file na kokopyahin mo palabas ng server. Dahil nasa iisang dataset ang buong userland ng jail, kasama sa snapshot ang mga naka-install na package at data sa isang magkakaparehong punto ng oras, pati ang bawat config file na mano-mano mong in-edit. Kabaligtaran ito ng nakasanayan sa Docker, kung saan bina-back up mo ang named volumes at ang Compose file, at muli mong binubuo ang iba pa mula sa image.
Kailangan ko ba ang BastilleBSD, o sapat na ang base system?
Sapat na ang base system, at ito ang mas magandang panimulang punto. Saklaw ng jail.conf, jls, jexec at service jail start ang buong modelo, at kapag alam mo na ang mga ito, mababasa mo ang anumang FreeBSD host nang hindi muna kailangang pag-aralan ang tooling ng host na iyon. Convenience layer ang Bastille sa ibabaw nito: nagbo-bootstrap ito ng releases, lumilikha ng thin jails, nag-a-apply ng templates, at nagsusulat ng pf redirect rules para sa iyo. Matutunan muna ang mga base command, saka idagdag ang Bastille kapag naging matrabaho na ang pagta-type dahil sa dami ng jail.