FreeBSD jails vs Docker containers: Ano ang pinagkaiba?
Alamin kung paano nagkakaiba ang FreeBSD jail at Docker sa userland, layered images, state, networking, software at resource limits, pati sa shared kernel model.
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 mga ito. Pareho silang nagpapatakbo ng mga isolated userland sa iisang shared kernel, kaya walang isa sa mga ito ang isang virtual machine. Ang pinagkaiba ay kung ano ang nasa loob. Ang Docker container ay nagpapatakbo ng isang process mula sa layered image na kinuha mo sa registry. Ang jail ay nagpapatakbo 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 pahinang ito ay nagmumula sa puntong iyon.
Hindi nag-aalok ang SSD Nodes ng FreeBSD images. Hindi ka maaaring umarkila ng FreeBSD server sa platform na ito, at walang bahagi sa ibaba ang gabay sa pag-install para sa machine na mabibili mo rito. Paghahambing ito ng dalawang isolation model, na isinulat upang matukoy mo kung alin ang tunay na kailangan ng isang workload at upang mabasa mo ang setup ng isang FreeBSD team nang hindi nanghuhula.
Ano nga ba 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 ang tanda kumpara sa Docker. Isang kernel call ang mekanismo. Kinukuha ng jail(8) ang isang directory tree at sinisimulan dito ang mga process na may nakatalagang jail ID. Pagkatapos, tinatanggihan ng kernel ang isang nakatakdang set 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 mga filesystem, makakapag-load ng mga kernel module, o makakapag-bind sa mga network address na hindi ibinigay sa jail. Walang hiwalay na namespace type na kailangang pag-aralan at walang per-feature opt-in. Dumarating ang mga restriction bilang isang unit at ina-adjust gamit ang mga parameter sa config ng jail.
Sa host, inililista ng jls ang mga tumatakbong jail, at inilalagay ka ng jexec web sh sa isang shell sa loob ng 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 tulad ng ginagawa mo sa 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 suriin:
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. Inilalapat nito ang parehong configuration sa foreground at ipinapakita ang parameter na hindi nito matanggap, sa halip na iwan ang error sa service output.
Ang linyang dapat basahin nang dalawang beses ay exec.start = "/bin/sh /etc/rc". Kapag nagsisimula ng jail, pinapatakbo sa loob nito ang normal na boot script ng FreeBSD. Kaya 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 ka kumukuha ng software: mga image at registry kumpara sa userland na ikaw ang bubuo
Ito ang pagkakaibang mararamdaman mo sa unang araw pa lang.
Sa Docker, tinutukoy mo ang software at makukuha mo ito. Ang docker pull nginx ay kumukuha ng layered, content-addressed image na binuo at sinubukan ng ibang tao, at ang docker compose up -d ay sinisimulan ito kasama ang mga volume at network nito. Ang registry ang mismong produkto. Karamihan ng halaga sa Docker workflow ay nagmumula sa libo-libong project na naglalabas ng gumaganang image. Dahil dito, ang pagpapatakbo ng Docker sa isang VPS ay nagiging maikling gawain 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 pag-set up ng bare server. Mas marami itong kailangang i-type. Mas transparent din ito, dahil ang tumatakbo sa jail ay ang inilagay ng pkg, mula sa parehong package set na ginagamit ng host.
Pinapabilis 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 ang bastille bootstrap ng release, at ginagamit itong muli ng bawat jail na gagawin mo pagkatapos. Ang FreeBSD 15.1 ang kasalukuyang production release, na inilabas noong June 2026; palitan ito ayon sa release na ginagamit mo.
Isang command lang ang paggawa ng jail, at isa pang command ang pagpuno rito:
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 umiiral sa host. Para maulit ang isang build, inilalagay ng Bastille templates ang mga hakbang sa isang file at ipinapatupad ang mga ito sa isang jail. Ito ang pinakamalapit na katumbas ng Dockerfile sa environment na ito. 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 mga jail ang sarili mong installation. Kung ang software sa shortlist mo ay inilalabas bilang container image at wala nang iba, iyon na ang nagtatakda ng sagot bago pa makaboto ang iba pang criteria.
State at mga upgrade: ang bahaging binabago ng ZFS
Sadyang hinahati ng Docker ang state. Disposable ang filesystem ng container, 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 panuntunan, pero data-loss incident kapag nakalimutan mo ito. Kaya napakahalaga sa isang 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. Iisang 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 ito patakbuhin. Ang path sa itaas ang layout na ginagamit ng handbook. Tumatagal nang humigit-kumulang isang segundo ang snapshot at halos walang karagdagang space na ginagamit hanggang sa mabago ang laman ng jail. Kung masira ng upgrade ang serbisyo, ibinabalik ng rollback ang buong userland sa dati nitong state, kasama ang package database at mga config file na mano-mano mong in-edit nang 2am. Walang built-in na katumbas nito ang Docker dahil ipinapalagay ng model nito na hindi mo kailanman kailangan ang ganitong feature.
zfs clone ang kabilang bahagi. Ang clone ng snapshot ay bagong writable jail na nagbabahagi ng mga block na hindi nagbago sa parent nito. Kaya halos walang disk space ang staging copy ng 3 GB jail hanggang sa magsimula kang gumawa ng mga pagbabago rito. Ganito bumubuo ang isang FreeBSD admin ng jail na “katulad ng production” para subukan ang upgrade.
Hiwalay ang upgrade ng base system sa mga package. Para sa jail na may sarili nitong kopya ng userland:
sudo freebsd-update -b /usr/local/jails/containers/web fetch installIniiwasan ng thin jails ang paulit-ulit na gawaing ito. Mina-mount nila ang 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 i-patch ang base at makikita ng bawat jail ang resulta. Bilang default, gumagawa ang Bastille ng thin jails.
Networking: mga port na inilathala kumpara sa pagpili ng addressing
Si Docker ang nagdedesisyon ng networking para sa iyo at hinihiling sa iyong i-publish ang mga exception. Napupunta ang mga container sa isang bridge, naaabot nila ang isa't isa 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 diretsong nalalampasan ng published container port ang ufw.
Pinapapili ka ng jail ng modelo bago magsimula, at may dalawa rito.
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 mai-bind ang sarili sa bawat address: kapag humiling ang isang jailed socket ng 0.0.0.0, nire-rewrite ito ng kernel sa sariling address ng jail. Hindi maaaring parehong makinig ang dalawang jail sa port 80 ng iisang address. Kaya binibigyan mo ang bawat isa ng sariling address, o naglalagay ka ng reverse proxy sa harap ng mga ito.
VNET. Idinaragdag ang vnet; sa jail at binibigyan 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 bawat 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. Ibinabalot 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 isang redirect rule. Mas mabagal ang pagsisimula nito, ngunit mas tahimik ang firewall.
Resource limits: cgroups kumpara sa rctl
Nililimitahan ng Docker ang isang container gamit ang cgroups, at nakalagay ang mga limit sa kung saan dine-define ang container: --memory=1g --cpus=1.5 sa command line, o ang katumbas na key sa Compose file. Kung nasa Docker Compose file na sa isang VPS na ang stack mo, nakalagay ang limit sa tabi ng service na sakop nito 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 kaunting dagdag na gastos ito 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 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=YESDito mas malinaw na mas maginhawa 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 jail na dine-define sa ibang lugar.
Kapag virtual machine ang kailangan: bhyve
Ibinabahagi ng jail ang kernel ng host, kaya may mga bagay na permanenteng hindi nito maaabot. Hindi ito makakapagpatakbo ng ibang kernel version, hindi ito makakapag-load ng kernel module, at hindi ito makakapagpatakbo ng Linux binary gaya ng ginagawa ng Linux container. May Linux compatibility layer ang FreeBSD na tinatawag na linuxulator, pero 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 mabuting hindi makibahagi ng 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. Dito nakasalalay kung kailangan mo ng VPS na sumusuporta sa nested virtualization sa ilalim nito.
Ang ecosystem, na siyang totoong dahilan kung bakit Docker ang ginagamit ng karamihan ng mga team
Tungkol sa model ang lahat ng nasa itaas. Ang karaniwang nagdidikta sa pagpili ng karamihan ng mga team ay ang lawak ng ecosystem sa paligid ng bawat isa.
Kasama sa Docker ang Docker Hub at GHCR, docker compose, Kubernetes kapag hindi na sapat ang isang box, CI runners na may nakahandang container support, at quickstart na isang command 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 ang inilalabas ng isang project at wala nang iba, ang FreeBSD route ay basahin ang documentation nito at ikaw mismo ang mag-assemble ng mga bahagi.
May lugar ang jails dahil sa kabilang panig ng trade-off na ito. Piliin ang mga ito kapag gumagamit ka na ng ZFS at mahalaga sa iyo ang snapshot at rollback ng isang buong service, kapag FreeBSD native ang mga service mo, kapag gusto mo ng kumpletong userland para sa bawat tenant sa halip na iisang process, o kapag gusto mong sabay na mina-maintain ang kernel, packet filter, filesystem, at documentation bilang isang system. Ito ang ibig sabihin kapag tinatawag ng mga tao na coherent ang FreeBSD, at mas malawak itong tinatalakay sa paghahambing ng Linux at FreeBSD bilang server platform at sa mga binago ng FreeBSD 15 para sa paggamit sa server.
Isang huling pagtatasa. Kung pamilyar na ang team mo sa Docker, tunay ang gastos sa paglipat at dapat tiyak ang pakinabang nito. Huwag lumipat dahil lang sa kalidad ng isolation; sapat na magkalapit ang dalawang model kaya mas mahalaga ang configuration mo. Lumipat dahil gusto mo ng ZFS-backed rollback para sa buong service, o dahil FreeBSD na ang ginagamit mo.
FAQ
Maaari ba akong magpatakbo ng Docker images sa FreeBSD?
Hindi mga Linux image, at hindi ito isang supported na paraan. May suporta ang FreeBSD para sa OCI container: ini-install ng sudo pkg install -y podman-suite ang Podman, na nagpapatakbo ng mga container sa pamamagitan ng ocijail, isang runtime na lumilikha ng aktuwal na jail sa ilalim nito. Kailangan nito ang fdescfs na naka-mount 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 ang mga Linux image, at noong August 2026, inilalarawan pa rin bilang experimental ang FreeBSD Podman port. Kung stack ng Linux image ang deployment mo, patakbuhin ito sa Linux. Sa RHEL family, nangangahulugan ito ng pag-install ng Docker sa Rocky Linux o AlmaLinux, kung saan muling lumilitaw ang Podman bilang package na siyang may-ari ng docker command bago ka pa may mai-install.
Mas secure ba ang FreeBSD jail kaysa sa Docker container?
Pareho silang gumagamit ng iisang host kernel, kaya panganib sa pareho ang kernel bug, at hindi ang alinman sa mga ito ang pipiliin mong boundary para sa code na tunay na hindi pinagkakatiwalaan. Ang kaibahan ay nasa panimulang configuration. Nagsisimula ang jail na maraming operation ang 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 isang set ng namespace na may ilang capability na tinanggal, at opt-in ang karagdagang hardening. Sa aktuwal na paggamit, 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, pagkatapos ay 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, nakukuha ng snapshot ang mga naka-install na package at data sa iisang consistent na punto, pati ang bawat config file na mano-mano mong in-edit. Kabaligtaran ito ng nakasanayang Docker workflow, kung saan bina-back up mo ang named volume at ang Compose file, at nire-rebuild ang iba pa mula sa image.
Kailangan ko ba ang BastilleBSD, o sapat na ang base system?
Sapat ang base system, at mas mabuting dito magsimula. 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 matutunan ang tooling ng host na iyon. Convenience layer lang ang Bastille sa ibabaw nito: nagbo-bootstrap ito ng release, gumagawa ng thin jail, nag-a-apply ng template, at nagsusulat ng pf redirect rule para sa iyo. Alamin muna ang mga base command, saka idagdag ang Bastille kapag naging matrabaho na ang pagta-type dahil sa dami ng jail.