FreeBSDでは14.2Rより、OCI互換のIMAGEが用意されています。これによってPodmanでOCIフォーマットのイメージを読み込み、それをJailコンテナとして利用することができます。
これはocijailというバックエンドによって動作しています。
まだまだFreeBSDのPodmanは荒削りでありPoCレベルを超えていませんが、それでもdockerのような決定的なインターフェイスがなかなか出なかったJail界においては大きな前進と言えるのではないでしょうか。
このイメージは3つ用意されており、static
,dynamic
,minimal
があります。
これらの詳細は参照元を確認してください。
簡単にいうと、staticではlibcなどもない完全に最小のシステム、dynamicはstatic+libc,shared libs、minimalはdynamic+sh,minimal baseです。
Install podman
podmanのインストール自体はpkg
ですぐにできます。
# pkg install podman
その後、pf.confやfstabの設定等をします。sampleファイルがあるのでそれを基に設定します。
# pkg list buildah podman conmon ocijail containers-common \ containernetworking-plugins \ |grep /etc/ /usr/local/etc/containers/containers.conf.sample /usr/local/etc/containers/policy.json.sample /usr/local/etc/containers/registries.conf.sample /usr/local/etc/containers/storage.conf.sample /usr/local/etc/containers/pf.conf.sample
pf.confは私は以下のように設定しました。
$ cat /etc/pf.conf
v4egress_if = "eth0"
v6egress_if = "eth0"
nat on $v4egress_if inet from <cni-nat> to any -> ($v4egress_if)
nat on $v6egress_if inet6 from <cni-nat> to !ff00::/8 -> ($v6egress_if)
rdr-anchor "cni-rdr/*"
nat-anchor "cni-rdr/*"
table <cni-nat>
pass in on cni-podman0
pass out on cni-podman0
$ service pf reload # pfのリスタートはお忘れなく
Make jailed container with podman
では、miminalイメージを取得してpodmanに読み込ませましょう。
# export OCIBASE=https://download.freebsd.org/releases/OCI-IMAGES/14.2-RELEASE/amd64/Latest
# podman load -i=$OCIBASE/FreeBSD-14.2-RELEASE-amd64-container-image-minimal.txz
# podman image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/freebsd14-minimal 14.2-RELEASE-amd64 c5f3e77557a9 5 months ago 35.1 MB
以下のようにすることで、jailが作成され、shに入ることができます。
# podman run -it localhost/freebsd14-minimal:14.2-RELEASE-amd64 /bin/sh
# freebsd-version -kru
freebsd-version: unable to locate kernel # <- in jails!
# freebsd-version -ru
14.2-RELEASE-p1
14.2-RELEASE <- jailなのでユーザーランドだけ見える
さて、このままだとネットワークがうまくいったり行かなかったりします。私はlocal-unbound
を使用しているため、ホストのnameserverが 127.0.0.1となっており、jail内の方がnameserverを認識できませんでした。
そのため、jail側の/etc/resolv.conf
を編集します。viやeeはないのでechoやsedでやりましょう。
# echo nameserver <HOST-IP> >> /etc/resovle.conf
# echo nameserver 8.8.8.8 >> /etc/resovle.conf
これでDNS名前解決ができるようになっているはずです。drillもないので、pingなどでいい感じに切り分けましょう。
Using pkg in jail
さて、これでpkg
がbootstrapできる段階になりました。
しかし、pkg -f
してもpkgが見つからないなどと怒られてbootstrapできません。
これはrepoがbaseを参照する設定が入っており、こっちを優先してみてしまうことでpkgが存在せず、エラーとなっています。
そのため、以下のファイルを編集してreleaseにrepoを向けます。
# cat /usr/local/etc/pkg/repos/base.conf
FreeBSD-base: {
url: "https://pkg.FreeBSD.org/${ABI}/base_release_2",
mirror_type: "srv",
signature_type: "fingerprints",
fingerprints: "/usr/share/keys/pkg",
enabled: yes
}
# sed -i '' 's/enabled: yes/enabled: no/' /usr/local/etc/pkg/repos/base.conf
これでpkg
が利用可能になります。
# pkg
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:14:amd64/quarterly, please wait...
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
[8afcf3ac578f] Installing pkg-2.1.0...
[8afcf3ac578f] Extracting pkg-2.1.0: 100%
これで、アプリケーションをインストールできるようになりました。
例えばapache
をインストールしましょう。
# pkg install apache24
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Updating database digests format: 100%
The following 20 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
apache24: 2.4.63
apr: 1.7.5.1.6.3_4
brotli: 1.1.0,1
curl: 8.12.1
expat: 2.7.0
gdbm: 1.24
gettext-runtime: 0.23.1
indexinfo: 0.3.1_1
jansson: 2.14.1
libidn2: 2.3.8
liblz4: 1.10.0,1
libnghttp2: 1.65.0
libpsl: 0.21.5_2
libssh2: 1.11.1,3
libunistring: 1.3
libxml2: 2.11.9
pcre2: 10.45
perl5: 5.36.3_3
readline: 8.2.13_2
zstd: 1.5.7
Number of packages to be installed: 20
The process will require 123 MiB more space.
28 MiB to be downloaded.
Proceed with this action? [y/N]: y
[8afcf3ac578f] [1/20] Fetching indexinfo-0.3.1_1.pkg: 100% 6 KiB 6.0kB/s 00:01
...
[8afcf3ac578f] [20/20] Extracting apache24-2.4.63: 100%
これでインストールが成功しました。Apacheを立ち上げて、依存で入ってるcurlで確認してみましょう。
# service apache24 onestart
Performing sanity check on apache24 configuration:
[Mon Apr 28 13:20:30.677209 2025] [so:warn] [pid 86066] AH01574: module mpm_prefork_module is already loaded, skipping
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.14. Set the 'ServerName' directive globally to suppress this message
Syntax OK
Starting apache24.
[Mon Apr 28 13:20:30.730944 2025] [so:warn] [pid 86067] AH01574: module mpm_prefork_module is already loaded, skipping
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.0.14. Set the 'ServerName' directive globally to suppress this message
# curl localhost
<html><body><h1>It works!</h1></body></html>
これでHTTPサーバーが立ち上がりました。host側からpsでどう見えるか見てみましょう。
$ ps aux | grep httpd
root 56269 0.0 0.0 17616 5700 - SsJ 23:37 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
www 56270 0.0 0.0 17616 5716 - SJ 23:37 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
www 56271 0.0 0.0 17616 5716 - SJ 23:37 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
www 56272 0.0 0.0 17616 5716 - SJ 23:37 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
www 56273 0.0 0.0 17616 5716 - SJ 23:37 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
www 56274 0.0 0.0 17616 5716 - SJ 23:37 0:00.00 /usr/local/sbin/httpd -DNOHTTPACCEPT
stateにJが入っているのでJailで稼働していることがわかります。
問題点
- なんかsoが足りないってなったりshスクリプトが動かないよ。 <= baseシステム全体がインストールされているわけではないので、共有ライブラリが足りてなかったり標準のコマンドが入ってなかったりします。うまい事
pkg
をつかってインストールするか(baseをYESにしてごにょごにょ)、ホスト側からコピーしてくるなどの対策が必要です。 - rootlessは? <= まだFreeBSDでは未実装です。
- 設定とかは? <=基本はdocker/podmanの手法でできるはずですが、動作確認が完全に取れているわけでもないです。ocijailの方でもいろいろできるのでそっちもあるかも
参考文献