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.confjail.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列表

复制代码
jls
   JID  IP Address      Hostname                      Path
     6  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
# ps
  PID 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/LOGGING
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  allow.raw_sockets;
  exec.clean;
  mount.devfs;

  # HOSTNAME/PATH
  host.hostname = "${name}";
  path = "/usr/local/jails/containers/${name}";

  # NETWORK
  ip4 = inherit;
  interface = igb0;
}
datajail {
  # STARTUP/LOGGING
  exec.start = "/bin/sh /etc/rc";
  exec.stop = "/bin/sh /etc/rc.shutdown";
  exec.consolelog = "/var/log/jail_console_${name}.log";

  # PERMISSIONS
  allow.raw_sockets;
  exec.clean;
  mount.devfs;

  # HOSTNAME/PATH
  host.hostname = "${name}";
  path = "/usr/local/jails/containers/${name}";

  # NETWORK
  ip4 = 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 Other
     832M Compressed, 1452M Uncompressed, 1.74:1 Ratio
Swap: 2048M Total, 2048M Free

  PID USERNAME    THR PRI NICE   SIZE    RES STATE    C   TIME    WCPU COMMAND
68569 root          1  20    0    15M  3312K CPU1     1   0:00   0.03% top
 2546 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% sh
 2453 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文件里修改一下就好了

相关推荐
nandezizai_ddc2 小时前
Debian 初始设置
运维·debian
R.lin2 小时前
浅谈Nginx
运维·nginx
羑悻的小杀马特2 小时前
JuiceSSH+cpolar解锁手机远程Linux新姿势,无需公网IP,固定地址稳定用
linux·服务器·coplar
远程软件小帮手2 小时前
好用的远程软件!ToDesk、向日葵、UU远程横测
运维·服务器·游戏·电脑
std78792 小时前
核电站里,机器人当起“侦察兵”
运维·安全·机器人
顾安r2 小时前
11.14 脚本网页 青蛙过河
服务器·前端·python·游戏·html
HIT_Weston2 小时前
30、【Ubuntu】【远程开发】内网穿透:反向隧道建立(二)
linux·运维·ubuntu
Percep_gan2 小时前
在Linux中安装字体
linux·运维·服务器
ZStack开发者社区3 小时前
VMware替代 | ZStack ZSphere虚拟化平台金融级高可用能力解析
服务器·jvm·金融·云计算