FreeBSD 14.3 轻量级Jail虚拟机:内存资源占用仅13MB的实战指南
首先确认一下,直接使用FreeBSD原生的工具创建jail,而不使用cbsd等工具。原因是用cbsd创建的jail在两台FreeBSD14.3服务器上没有启动成功,有一台可能是内存2G太少的缘故。(后来发现不是,8G也不行。以前14.1版本的时候8G是ok的)
轻量级Jail虚拟机非常节省资源,比如有一台FreeBSD,在运行两台Jail虚拟机的情况下(虚拟机只是启动,没有其它负载),内存占用仅有区区13MB,在2025年真的有种惊天地泣鬼神的美!

原生瘦jail放置的目录是/usr/local/jails ,也不是cbsd工具的/usr/jails
官方文档:Chapter 17. Jails and Containers | FreeBSD Documentation Portal
文档中文版:17.5.瘦 jail | FreeBSD 中文手册
首先进行系统配置
第一台服务器使用了sudo来提权执行命令,其实FreeBSD用户更习惯于在root账户下直接操作。手册就是直接在root账户下操作的。如果使用sudo提权执行,很多命令未必能一次黏贴运行成功,要注意这一点。
第二台服务器使用了zfs磁盘分区,并且是在root账户下操作,感觉就丝滑很多。
设置jail服务启动
sudo sysrc jail_enable="YES"
sudo sysrc jail_parallel_start="YES"
创建放置jail的目录
sudo mkdir /usr/local/jails/
sudo mkdir /usr/local/jails/media
sudo mkdir /usr/local/jails/templates
sudo mkdir /usr/local/jails/containers
网络配置
基本不用提前配置,只要规划好ip地址即可。
使用 NullFS 创建瘦 jail 虚拟机
NullFS的方法支持zfs和ufs 。如果系统是zfs,可以使用OpenZFS Snapshots 来创建,效果会更好。所以这里以ufs为例进行实践。
ufs的 NullFS方法会比zfs方法略微繁琐一点。但是有些服务器不是zfs分区,只好用ufs分区的方法。
先创立目录
mkdir /usr/local/jails/templates/14.3-RELEASE-base
下载用户空间文件base.txz
可以使用阿里镜像,非常快!
sudo fetch https://download.freebsd.org/ftp/releases/amd64/amd64/14.3-RELEASE/base.txz -o /usr/local/jails/media/14.3-RELEASE-base.txz
# 阿里镜像 非阿里云也可以用
sudo fetch https://mirrors.aliyun.com/freebsd/releases/amd64/14.3-RELEASE/base.txz -o /usr/local/jails/media/14.3-RELEASE-base.txz
下载完成解压
sudo tar -xf /usr/local/jails/media/14.3-RELEASE-base.txz -C /usr/local/jails/templates/14.3-RELEASE-base --unlink
设定jail虚拟机相关
待用户空间提取到模板目录中,就需要通过以下命令将时区和 DNS 服务器文件复制到模板目录中:
sudo cp /etc/resolv.conf /usr/local/jails/templates/14.3-RELEASE-base/etc/resolv.conf
sudo cp /etc/localtime /usr/local/jails/templates/14.3-RELEASE-base/etc/localtime
将文件移动到模板中后,接下来的步骤是通过以下命令更新到最新的补丁级别:
sudo freebsd-update -b /usr/local/jails/templates/14.3-RELEASE-base/ fetch install
除了基础模板外,还需要创建一个目录来存放 skeleton。一些目录将从模板复制到 skeleton 中。
使用 UFS,请执行以下命令:
sudo mkdir /usr/local/jails/templates/14.3-RELEASE-skeleton
然后创建 skeleton 目录。skeleton 目录将存放 jail 的本地目录。
执行以下命令创建这些目录:
sudo mkdir -p /usr/local/jails/templates/14.3-RELEASE-skeleton/home
sudo mkdir -p /usr/local/jails/templates/14.3-RELEASE-skeleton/usr
sudo mv /usr/local/jails/templates/14.3-RELEASE-base/etc /usr/local/jails/templates/14.3-RELEASE-skeleton/etc
sudo mv /usr/local/jails/templates/14.3-RELEASE-base/usr/local /usr/local/jails/templates/14.3-RELEASE-skeleton/usr/local
sudo mv /usr/local/jails/templates/14.3-RELEASE-base/tmp /usr/local/jails/templates/14.3-RELEASE-skeleton/tmp
sudo mv /usr/local/jails/templates/14.3-RELEASE-base/var /usr/local/jails/templates/14.3-RELEASE-skeleton/var
sudo mv /usr/local/jails/templates/14.3-RELEASE-base/root /usr/local/jails/templates/14.3-RELEASE-skeleton/root
注意,root目录是没有的(其实不是,前面有些命令没有正常执行导致的)。
接下来的步骤是通过执行以下命令创建指向 skeleton 的符号链接:
cd /usr/local/jails/templates/14.3-RELEASE-base/
sudo mkdir skeleton
sudo ln -s skeleton/etc etc
sudo ln -s skeleton/home home
sudo ln -s skeleton/root root
sudo ln -s ../skeleton/usr/local usr/local
sudo ln -s skeleton/tmp tmp
sudo ln -s skeleton/var var
skeleton 准备好后,需要将数据复制到 jail 目录中。
使用 UFS,可以使用 cp(1) 程序,执行以下命令:
sudo cp -R /usr/local/jails/templates/14.3-RELEASE-skeleton /usr/local/jails/containers/thinjail
然后创建一个目录,用于挂载基础模板和 skeleton:
sudo mkdir -p /usr/local/jails/thinjail-nullfs-base
在 /etc/jail.conf 或 jail.conf.d 文件中添加 jail 条目,我习惯放在/etc/jail.conf.d/目录下,使用jail.conf文件如下所示.
后来还是修改的/etc/jail.conf文件,添加(如果没有,就创建):
复制
thinjail {# 启动/日志记录exec.start = "/bin/sh /etc/rc";exec.stop = "/bin/sh /etc/rc.shutdown";exec.consolelog = "/var/log/jail_console_${name}.log";# 权限allow.raw_sockets;exec.clean;mount.devfs;# 主机名/路径host.hostname = "${name}";path = "/usr/local/jails/${name}-nullfs-base";# 网络ip4.addr = 192.168.1.15;interface = em0;# 挂载mount.fstab = "/usr/local/jails/${name}-nullfs-base.fstab";
}
然后创建 /usr/local/jails/thinjail-nullfs-base.fstab 文件,
sudo vi /usr/local/jails/thinjail-nullfs-base.fstab
内容如下:
/usr/local/jails/templates/14.3-RELEASE-base /usr/local/jails/thinjail-nullfs-base/ nullfs ro 0 0
/usr/local/jails/containers/thinjail /usr/local/jails/thinjail-nullfs-base/skeleton nullfs rw 0 0
启动jail
执行以下命令启动 jail:
sudo service jail start thinjail
没有报错,就证明我们配置正确,jail成功启动了!
管理jail
jls列表
jlsJID IP Address Hostname Path6 192.168.1.153 thinjail /usr/local/jails/thinjail-nullfs-base
启动jail
sudo service jail start thinjail
停止jail
sudo service jail stop jailname
比如
sudo service jail stop thinjail
进入jail系统
# jexec -u root jailname
比如:
sudo jexec -u root thinjail1
进入后查看一下
# ping quye.com
PING quye.com (123.56.226.145): 56 data bytes
64 bytes from 123.56.226.145: icmp_seq=0 ttl=59 time=3.186 ms
64 bytes from 123.56.226.145: icmp_seq=1 ttl=59 time=3.184 ms
^C
--- quye.com ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 3.184/3.185/3.186/0.001 ms
# uname -a
FreeBSD thinjail 14.3-RELEASE-p5 FreeBSD 14.3-RELEASE-p5 GENERIC amd64
果然是jail,果然可以连通外网。
创建wwwjail和datajail
依葫芦画瓢,再创建datajail和wwwjail ,只需要修改这些配置:
创建容器
sudo cp -R /usr/local/jails/templates/14.3-RELEASE-skeleton /usr/local/jails/containers/wwwjail
sudo cp -R /usr/local/jails/templates/14.3-RELEASE-skeleton /usr/local/jails/containers/datajail
创建挂载目录
创建目录,用于挂载基础模板和 skeleton:
sudo mkdir -p /usr/local/jails/wwwjail-nullfs-base
sudo mkdir -p /usr/local/jails/datajail-nullfs-base
添加jail条目
在 /etc/jail.conf 文件中添加 jail 条目,又加了这两部分
wwwjail {# 启动/日志记录exec.start = "/bin/sh /etc/rc";exec.stop = "/bin/sh /etc/rc.shutdown";exec.consolelog = "/var/log/jail_console_${name}.log";# 权限allow.raw_sockets;exec.clean;mount.devfs;# 主机名/路径host.hostname = "${name}";path = "/usr/local/jails/${name}-nullfs-base";# 网络ip4.addr = 192.168.1.5;interface = vtnet0;# 挂载mount.fstab = "/usr/local/jails/${name}-nullfs-base.fstab";
}
datajail {# 启动/日志记录exec.start = "/bin/sh /etc/rc";exec.stop = "/bin/sh /etc/rc.shutdown";exec.consolelog = "/var/log/jail_console_${name}.log";# 权限allow.raw_sockets;exec.clean;mount.devfs;# 主机名/路径host.hostname = "${name}";path = "/usr/local/jails/${name}-nullfs-base";# 网络ip4.addr = 192.168.1.7;interface = vtnet0;# 挂载mount.fstab = "/usr/local/jails/${name}-nullfs-base.fstab";
}
启动这些jail
sudo service jail start wwwjail
sudo service jail start datajail
好了,两个瘦jail虚拟机就创立好并启动成功了!
登录查看
登录到datajail,可以看到jail只有4个进程:
sudo jexec -u root datajail
# uname -a
FreeBSD datajail 14.3-RELEASE-p5 FreeBSD 14.3-RELEASE-p5 GENERIC amd64
# psPID TT STAT TIME COMMAND
29305 2 SJ 0:00.01 /bin/sh -i
29310 2 R+J 0:00.00 ps
# ps -aux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 29059 0.0 0.2 13904 3008 - SsJ 21:24 0:00.00 /usr/sbin/syslogd -s
root 29103 0.0 0.1 13944 2896 - IsJ 21:24 0:00.00 /usr/sbin/cron -s
root 29305 0.0 0.2 14484 3544 2 SJ 21:24 0:00.01 /bin/sh -i
root 29311 0.0 0.2 14564 3456 2 R+J 21:24 0:00.00 ps -aux
#
启动3个容器后,FreeBSD的内存占用还是低的可怕:
CPU: 0.4% user, 0.0% nice, 0.0% system, 0.2% interrupt, 99.4% idle
Mem: 41M Active, 1414M Inact, 14M Laundry, 378M Wired, 191M Buf, 51M Free
当前活跃内存只占用了41M,Wired (固定内存):378M, Buf (缓冲区缓存):191M 。总共占用了600M内存。
当然可以说是因为那三个容器还没跑服务,问题是即使不跑服务,很多其它容器光启动,就需要占用很多内存了!
实践OpenZFS Snapshots的使用zfs系统的瘦客户端
这是最佳的方法,装好后两个jail启动后内存才占用13M,注意,是13M,不是xxG 。
先创建目录
zfs create -o mountpoint=/usr/local/jails zroot/jails
zfs create zroot/jails/media
zfs create zroot/jails/templates
zfs create zroot/jails/containers
配置jail文件
存放在/etc/jail.conf文件里,注意,这个跟前面NullFS的配置不一样
wwwjail {# STARTUP/LOGGINGexec.start = "/bin/sh /etc/rc";exec.stop = "/bin/sh /etc/rc.shutdown";exec.consolelog = "/var/log/jail_console_${name}.log";# PERMISSIONSallow.raw_sockets;exec.clean;mount.devfs;# HOSTNAME/PATHhost.hostname = "${name}";path = "/usr/local/jails/containers/${name}";# NETWORKip4 = inherit;interface = igb0;
}
datajail {# STARTUP/LOGGINGexec.start = "/bin/sh /etc/rc";exec.stop = "/bin/sh /etc/rc.shutdown";exec.consolelog = "/var/log/jail_console_${name}.log";# PERMISSIONSallow.raw_sockets;exec.clean;mount.devfs;# HOSTNAME/PATHhost.hostname = "${name}";path = "/usr/local/jails/containers/${name}";# NETWORKip4 = inherit;interface = igb0;
}
创建一个数据
zfs create -p zroot/jails/templates/14.3-RELEASE
下载
可以使用阿里镜像,非常快!
fetch https://download.freebsd.org/ftp/releases/amd64/amd64/14.3-RELEASE/base.txz -o /usr/local/jails/media/14.3-RELEASE-base.txz# 阿里镜像 非阿里云也可以用
fetch https://mirrors.aliyun.com/freebsd/releases/amd64/14.3-RELEASE/base.txz -o /usr/local/jails/media/14.3-RELEASE-base.txz
下载完成解压
tar -xf /usr/local/jails/media/14.3-RELEASE-base.txz -C /usr/local/jails/templates/14.3-RELEASE --unlink
设定jail虚拟机相关
待用户空间提取到模板目录中,就需要通过以下命令将时区和 DNS 服务器文件复制到模板目录中:
cp /etc/resolv.conf /usr/local/jails/templates/14.3-RELEASE/etc/resolv.conf
cp /etc/localtime /usr/local/jails/templates/14.3-RELEASE/etc/localtime
升级补丁
将文件移动到模板中后,接下来的步骤是通过以下命令更新到最新的补丁级别:
freebsd-update -b /usr/local/jails/templates/14.3-RELEASE/ fetch install
生成快照
zfs snapshot zroot/jails/templates/14.3-RELEASE@base
创建jail
zfs clone zroot/jails/templates/14.3-RELEASE@base zroot/jails/containers/wwwjail
zfs clone zroot/jails/templates/14.3-RELEASE@base zroot/jails/containers/datajail
启动jail
service jail start wwwjail
登录jail
jexec -u root wwwjail
看看top信息,真的太省内存了
last pid: 73495; load averages: 1.32, 1.20, 1.14 up 0+06:43:14 15:09:00
4 processes: 1 running, 3 sleeping
CPU: 4.1% user, 0.0% nice, 22.5% system, 0.0% interrupt, 73.4% idle
Mem: 11M Active, 109M Inact, 1602M Wired, 6078M Free
ARC: 932M Total, 361M MFU, 532M MRU, 264K Anon, 6538K Header, 31M Other832M Compressed, 1452M Uncompressed, 1.74:1 Ratio
Swap: 2048M Total, 2048M FreePID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
68569 root 1 20 0 15M 3312K CPU1 1 0:00 0.03% top2546 root 1 20 0 14M 2544K nanslp 0 0:00 0.01% cron
66217 root 1 20 0 14M 3216K wait 1 0:00 0.00% sh2453 root 1 20 0 14M 2772K select 1 0:00 0.00% syslogd
收工!
调试
启动jail报错
sudo service jail start thinjail
Starting jails: cannot start jail "thinjail":
ifconfig: interface em0 does not exist
jail: thinjail: /sbin/ifconfig em0 inet 192.168.1.153 netmask 255.255.255.255 alias: failed
确实没有em0这个卡,而是vtnet0
在jail.conf文件里修改一下就好了
