在FreeBSD 14.3上部署轻量级Linux jail环境 仅仅占用10M内存

Creating a Linux Jail 手册:

https://docs.freebsd.org/en/books/handbook/jails/#thin-jail

FreeBSD系统里创建Linux的jail的思路是:

跟主系统启动Linux兼容层协议一样。主系统启动Linux是使用FreeBSD内核,然后使用Linux兼容层来实现Linux软件的运行(具体是Linux ABI 实现Linux的调用)。所以创建Linux jail,思路就是先创建一个FreeBSD的jail,然后里面使用debootstrap安装Ubuntu兼容系统。

先启动FreeBSD主系统linux兼容协议

配置linux兼容

复制代码
sysrc linux_enable="YES"

启动linux兼容协议

复制代码
service linux start

这样启动后,linux兼容要多大约内存耗费增加300k

使用OpenZFS创建一个轻量级jail的快照 a Thin Jail Using OpenZFS Snapshots

这部跟创建轻量级FreeBSD jail的方法一模一样,完全可以参考官网a Thin Jail Using OpenZFS Snapshots这部分,除了设置的名字不一样(名字也可以跟官方一样用ubuntu,但是我还是喜欢用ubjail1这个名字),其它都可以跟官方一样。

参考这里:https://skywalk.blog.csdn.net/article/details/154576901

先创建目录

复制代码
zfs create -o mountpoint=/usr/local/jails zroot/jails
zfs create zroot/jails/media
zfs create zroot/jails/templates
zfs create zroot/jails/containers

创建一个模版

复制代码
zfs create -p zroot/jails/templates/14.3-RELEASE

下载linux的base.txz

可以使用阿里镜像,非常快!

复制代码
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

创建Linux jail

创建一个普通的FreeBSD轻量级jail ,名字叫ubjail1,所以目录放在了zroot/jails/containers/ubjail1

复制代码
zfs clone zroot/jails/templates/14.3-RELEASE@base zroot/jails/containers/ubjail1

一直到这一步,创建Linux jail的过程跟创建FreeBSD jail的步骤一模一样,就是创建了一个FreeBSD jail的快照。

启动和配置jail

跟普通的FreeBSD轻量级jail不一样,这里没有jail的配置文件(不先配置,先启动,最后还是要写一个配置文件),而是在启动jail的时候这样写命令配置并启动jail:

复制代码
jail -cm \
    name=ubjail1 \
    host.hostname="ubjail1.example.com" \
    path="/usr/local/jails/containers/ubjail1" \
    interface="igb0" \
    ip4.addr="192.168.1.12" \
    exec.start="/bin/sh /etc/rc" \
    exec.stop="/bin/sh /etc/rc.shutdown" \
    mount.devfs \
    devfs_ruleset=4 \
    allow.mount \
    allow.mount.devfs \
    allow.mount.fdescfs \
    allow.mount.procfs \
    allow.mount.linprocfs \
    allow.mount.linsysfs \
    allow.mount.tmpfs \
    allow.raw_sockets \
    allow.socket_af \
    allow.sysvipc \
    enforce_statfs=1

注意,这里加上了4句官方手册里没有句子,否则网络不会通:

复制代码
    allow.mount.tmpfs \
    allow.raw_sockets \
    allow.socket_af \
    allow.sysvipc \

启动成功:

复制代码
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
32-bit compatibility ldconfig path: /usr/lib32
Updating motd:.
Creating and/or trimming log files.
Clearing /tmp (X related).
Updating /var/run/os-release done.
Starting syslogd.
Starting cron.

Sat Nov 15 11:56:01 CST 2025

这时候jls看看,可以看到确实启动成功了

复制代码
jls
   JID  IP Address      Hostname                      Path
     8                  wwwjail                       /usr/local/jails/containers/wwwjail
     9                  datajail                      /usr/local/jails/containers/datajail
    14  192.168.1.12    ubjail1.example.com           /usr/local/jails/containers/ubjail1

配置jail的Linux部分

登录jail

复制代码
jexec -u root ubjail1

可以看到当前还是FreeBSD的jail

复制代码
jexec -u root ubjail1
root@ubjail1:/ # uname -a
FreeBSD ubjail1.example.com 14.3-RELEASE FreeBSD 14.3-RELEASE releng/14.3-n271432-8c9ce319fef7 GENERIC amd64

安装jammy

在jail里安装debootstrap,然后再安装Ubuntu的jammy版本:

复制代码
pkg install debootstrap
debootstrap jammy /compat/ubuntu

如果pkg速度慢,就设置镜像

创建路径及文件 /usr/local/etc/pkg/repos/USTC.conf 来覆盖配置,文件内容如下:

复制代码
ustc: { 
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/quarterly"
}
FreeBSD: { enabled: no }

debootstrap jammy /compat/ubuntu 的速度非常慢,不知道该怎么解决。

找到解决方法了:

在运行 debootstrap 命令时,可以通过 --mirror 参数指定国内的镜像源地址。以下是一些稳定且速度较快的国内镜像源:

‌清华大学镜像源‌:https://mirrors.tuna.tsinghua.edu.cn/ubuntu/

‌中国科学技术大学镜像源 (USTC)‌:https://mirrors.ustc.edu.cn/ubuntu/

‌华为云镜像源‌:https://mirrors.huaweicloud.com/ubuntu/

‌阿里云镜像源‌:https://mirrors.aliyun.com/ubuntu/

‌网易镜像源‌:http://mirrors.163.com/ubuntu/

比如可以这样写:

复制代码
 debootstrap jammy /compat/jammy https://mirrors.aliyun.com/ubuntu/

然后写一个配置文件

写到/etc/jail.conf文件中:

复制代码
ubjail1 {
  # 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;
  devfs_ruleset = 4;

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

  # NETWORK
  ip4.addr = 192.168.1.12;
  interface = igb0;

  # MOUNT
  mount += "devfs     $path/compat/ubuntu/dev     devfs     rw  0 0";
  mount += "tmpfs     $path/compat/ubuntu/dev/shm tmpfs     rw,size=1g,mode=1777  0 0";
  mount += "fdescfs   $path/compat/ubuntu/dev/fd  fdescfs   rw,linrdlnk 0 0";
  mount += "linprocfs $path/compat/ubuntu/proc    linprocfs rw  0 0";
  mount += "linsysfs  $path/compat/ubuntu/sys     linsysfs  rw  0 0";
  mount += "/tmp      $path/compat/ubuntu/tmp     nullfs    rw  0 0";
  mount += "/home     $path/compat/ubuntu/home    nullfs    rw  0 0";
}

停机

复制代码
service jail onestop ubjail1

重新启动

按照常规jail的方法启动

复制代码
service jail start ubjail1

进入jail

注意进入方式跟普通FreeBSD jail不同,因为如果用同样的命令,进入的就是FreeBSD,只有靠chroot,可以进入Linux兼容环境

复制代码
jexec ubjail1 chroot /compat/ubuntu /bin/bash

看看当前系统

复制代码
jexec ubjail1 chroot /compat/ubuntu /bin/bash
root@ubjail1:/# uname -a
Linux ubjail1 5.15.0 FreeBSD 14.3-RELEASE releng/14.3-n271432-8c9ce319fef7 GENERIC x86_64 x86_64 x86_64 GNU/Linux

果然是linux了 。

后续工作

设置Ubuntu jammy加速

修改/etc/apt/sources.list文件,

复制代码
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
 
# 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
# deb-src http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
 
# 预发布软件源,不建议启用
# deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse
# # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-proposed main restricted universe multiverse

查看当前内存占用

Mem: 21M Active

linux内核起来还是有点占内存的,一个Linux jail几乎比主机+两个FreeBSD jail占用的都多。

但是也总共只占用了21M,还是相当可以的。全部内存信息:Mem: 20M Active, 259M Inact, 2451M Wired, 5068M Free

总结

这大约是第一次整明白FreeBSD轻量级Linux jail ,以前大部分时候都是用easyjail或者cbsd自动生成的。而且cbsd自动生成的Linux jail,有时候启动进去还是FreeBSD,这里也弄明白了,因为如果是用的Linux兼容技术,那么就不能直接用/bin/bash ,那个是FreeBSD,而是应该用chroot /compat/linux/ /bin/bash 进入的才是Linux jail !

看着步骤还是非常繁琐,直接用cbsd来安装要方便很多,可以参考这篇文档:https://skywalk.blog.csdn.net/article/details/139719880

调试

jail -cm启动的时候报错

jail: mount.devfs: /usr/local/jails/ubjail1/dev: No such file or directory

ifconfig: ioctl (SIOCDIFADDR): Can't assign requested address

jail: /sbin/ifconfig igb0 inet 192.168.1.22/24 -alias: failed

原来的命令:

复制代码
jail -cm \
    name=ubjail1 \
    host.hostname="ubjail1.example.com" \
    path="/usr/local/jails/ubjail1" \
    interface="igb0" \
    ip4.addr="192.168.1.22" \
    exec.start="/bin/sh /etc/rc" \
    exec.stop="/bin/sh /etc/rc.shutdown" \
    mount.devfs \
    devfs_ruleset=4 \
    allow.mount \
    allow.mount.devfs \
    allow.mount.fdescfs \
    allow.mount.procfs \
    allow.mount.linprocfs \
    allow.mount.linsysfs \
    allow.mount.tmpfs \
    enforce_statfs=1

手工创建这个目录试试:

sudo mount -t devfs devfs /usr/local/jails/ubjail1/dev

哦了,没有dev的报错了。后来弄明白了,不是这个问题,是目录写错了,应该是/usr/local/jails/containers/ubjail1 配置文件应该是:

复制代码
jail -cm \
    name=ubjail1 \
    host.hostname="ubjail1.example.com" \
    path="/usr/local/jails/containers/ubjail1" \
    interface="igb0" \
    ip4.addr="192.168.1.12" \
    exec.start="/bin/sh /etc/rc" \
    exec.stop="/bin/sh /etc/rc.shutdown" \
    mount.devfs \
    devfs_ruleset=4 \
    allow.mount \
    allow.mount.devfs \
    allow.mount.fdescfs \
    allow.mount.procfs \
    allow.mount.linprocfs \
    allow.mount.linsysfs \
    allow.mount.tmpfs \
    enforce_statfs=1

修改启动文件参数后,配置和启动完成:

复制代码
ELF ldconfig path: /lib /usr/lib /usr/lib/compat
32-bit compatibility ldconfig path: /usr/lib32
Updating motd:.
Creating and/or trimming log files.
Clearing /tmp (X related).
Updating /var/run/os-release done.
Starting syslogd.
Starting cron.

Sat Nov 15 11:56:01 CST 2025

启动后无法连外网

发现没有ip

复制代码
igb0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
        ether 00:e2:69:13:67:f6
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active

jail -cm \
    name=ubjail1 \
    host.hostname="ubjail1.example.com" \
    path="/usr/local/jails/containers/ubjail1" \
    interface="igb0" \
    ip4.addr="10.168.1.12" \
    exec.start="/bin/sh /etc/rc" \
    exec.stop="/bin/sh /etc/rc.shutdown" \
    mount.devfs \
    devfs_ruleset=4 \
    allow.mount \
    allow.mount.devfs \
    allow.mount.fdescfs \
    allow.mount.procfs \
    allow.mount.linprocfs \
    allow.mount.linsysfs \
    allow.mount.tmpfs \
    enforce_statfs=1

在jail内部修改ip试试

复制代码
echo 'ifconfig_igb0="inet 192.168.1.12 netmask 255.255.255.0"'

不行,用命令试试

复制代码
ifconfig_igb0="inet 192.168.1.12 netmask 255.255.255.0"
defaultrouter="192.168.1.1"

不行,jail内部会报错:

复制代码
/etc/netstart
Starting devd.
devd: Can't open devctl device /dev/devctl: No such file or directory
/etc/rc.d/devd: WARNING: failed to start devd
/etc/rc.d/hostid: WARNING: hostid: unable to figure out a UUID from DMI data, generating a new one
Setting hostuuid: 0f360e44-9944-41e5-b2ca-fdb949f43733.
Setting hostid: 0xbc850509.
ifconfig: up: permission denied
ifconfig: ioctl (SIOCAIFADDR): Operation not permitted
ifconfig: ioctl (SIOCAIFADDR): Operation not permitted
ifconfig: up: permission denied
Starting Network: lo0 igb0 cbsdbr0.
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        groups: lo
igb0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=4e527bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,LRO,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
        ether 00:e2:69:13:67:f6
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
cbsdbr0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=0
        ether 58:9c:fc:10:ff:83
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        groups: bridge
add host 127.0.0.1: gateway lo0 fib 0: Operation not permitted
add net default: gateway 192.168.1.1 fib 0: Operation not permitted
sysctl: net.inet.icmp.bmcastecho=0: Operation not permitted
sysctl: net.inet.icmp.drop_redirect=0: Operation not permitted
sysctl: net.inet.icmp.log_redirect=0: Operation not permitted
sysctl: net.inet.ip.forwarding=0: Operation not permitted
sysctl: net.inet.ip.sourceroute=0: Operation not permitted
sysctl: net.inet.ip.accept_sourceroute=0: Operation not permitted
sysctl: net.link.ether.inet.proxyall=0: Operation not permitted
add host ::1: gateway lo0 fib 0: Operation not permitted
add net fe80::: gateway ::1 fib 0: Operation not permitted
add net ff02::: gateway ::1 fib 0: Operation not permitted
add net ::ffff:0.0.0.0: gateway ::1 fib 0: Operation not permitted
add net ::0.0.0.0: gateway ::1 fib 0: Operation not permitted
sysctl: net.inet6.ip6.forwarding=0: Operation not permitted

尝试加入这几句

复制代码
    allow.raw_sockets \
    allow.socket_af \
    allow.sysvipc \

jail -cm \
    name=ubjail1 \
    host.hostname="ubjail1.example.com" \
    path="/usr/local/jails/containers/ubjail1" \
    interface="igb0" \
    ip4.addr="192.168.1.12" \
    exec.start="/bin/sh /etc/rc" \
    exec.stop="/bin/sh /etc/rc.shutdown" \
    mount.devfs \
    devfs_ruleset=4 \
    allow.mount \
    allow.mount.devfs \
    allow.mount.fdescfs \
    allow.mount.procfs \
    allow.mount.linprocfs \
    allow.mount.linsysfs \
    allow.mount.tmpfs \
    allow.raw_sockets \
    allow.socket_af \
    allow.sysvipc \
    enforce_statfs=1

网络终于通了,问题解决

apt update的时候报错 Updates for this repository will not be applied.

复制代码
apt update
Get:1 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy InRelease [270 kB]
Get:2 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates InRelease [128 kB]
Get:3 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports InRelease [127 kB]
Get:4 http://security.ubuntu.com/ubuntu jammy-security InRelease [129 kB]
Get:5 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/main amd64 Packages [1395 kB]
Get:6 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/main Translation-en [510 kB]
Get:7 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/restricted amd64 Packages [129 kB]
Get:8 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/restricted Translation-en [18.6 kB]
Get:9 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/universe amd64 Packages [14.1 MB]
Get:10 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/universe Translation-en [5652 kB]
Get:11 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/multiverse amd64 Packages [217 kB]
Get:12 https://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy/multiverse Translation-en [112 kB]
Reading package lists... Done
E: Release file for https://mirrors.tuna.tsinghua.edu.cn/ubuntu/dists/jammy-updates/InRelease is not valid yet (invalid for another 6h 36min 10s). Updates for this repository will not be applied.
E: Release file for https://mirrors.tuna.tsinghua.edu.cn/ubuntu/dists/jammy-backports/InRelease is not valid yet (invalid for another 4h 37min 57s). Updates for this repository will not be applied.
E: Release file for http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease is not valid yet (invalid for another 6h 33min 25s). Updates for this repository will not be applied.

我的理解是要等6个小时之后才可以update ?

相关推荐
Gofarlic_OMS7 小时前
Windchill的license合规使用报告自动化生成与审计追踪系统
大数据·运维·人工智能·云原生·自动化·云计算
迷途之人不知返8 小时前
shell相关知识与Linux权限
linux
SPC的存折8 小时前
3、主从复制实现同步数据过滤
linux·运维·服务器
SPC的存折8 小时前
openEuler 24.03 MariaDB Galera 集群部署指南(cz)
linux·运维·服务器·数据库·mysql
xcbrand8 小时前
文旅行业品牌策划公司找哪家
大数据·运维·人工智能·python
SPC的存折8 小时前
MySQL 8.0 分库分表
linux·运维·服务器·数据库·mysql
风吹迎面入袖凉8 小时前
【Redis】Redisson分布式锁原理
java·服务器·开发语言
cyber_两只龙宝8 小时前
【Oracle】Oracle之DQL中WHERE限制条件查询
linux·运维·数据库·云原生·oracle
斌味代码8 小时前
Shell 性能监控:指标采集、告警规则与可视化大盘设计
运维
22信通小白9 小时前
USRP初学者使用手册(基础配置及bug记录)——Linux+Clion(单台X310收发)
linux·运维·c++·5g·bug·信息与通信