FreeBSD jail を利用したコンテナランタイムrunjを試してみる

FreeBSD のJail を利用して動作するコンテナランタイムであるrunj をインストールからコンテナ動作まで試してみたので書いてみました。

## キッカケ

以前、jail を使った FreeBSD Dockerを動かすプレゼン見ていて「jailを使ったコンテナってどうなのか？」と調べていたところqiitaのこの記事を発見

https://qiita.com/YuheiTakagawa/items/9a13912330fcb3de8ab8


その中にrunjというのがあったので読んでいたところ、jailで動作してOCIを沿ったものを作ろうとしているというのを読んで興味を持ったので情報を集めて試してみようと思ったのが始まりです。

## runjとは

Samuel Karpという人が作っているjail を利用したコンテナランタイムで、本人はFreeBSDのjailの勉強のために作っている？？みたいなものらしいです。

https://samuelkarp.com

Github があります。
https://github.com/samuelkarp/runj


※ただしREAD.mdを読んだだけではわからないことが多いのでブログを参照する必要あるかと思います。
https://samuel.karp.dev/blog/2021/05/running-freebsd-jails-with-containerd-1-5/

今のところFreeBSDで動作するコンテナランタイムとしては更新が頻繁なのかと思います。

これよりインストールから、コンテナの動作までを書いていこうと思います。

※ports/sysutil にリポジトリがあり、パッケージ化もされてますが現状ソースからインストールした方が最新の機能が使えるとのことです。@610tさんありがとうございました。


## 事前準備

まずは、githubからソースをダウンロードするためgitと、runjや関連のアプリケーションがgoで記述されていることからgoをインストールします。

```
pkg install git
pkg install go
```

Containerd をgithubからクローンしてcontainerdとctrを直接ビルドします。

```
$ git clone https://github.com/containerd/containerd.git
$ cd containerd
$ go build ./cmd/containerd
$ go build ./cmd/ctr
```

ビルドしたcontainerd と ctrを/usr/local/binにインストールします。

```
$ install -o 0 -g 0 containerd ctr /usr/local/bin
```

## runjのインストール

githubからrunjのソースをクローンします。

```
$ git clone https://github.com/samuelkarp/runj.git
```

クローンしたrunjに移動してビルド・インストールします。

```
$ cd runj
$ make
$ make install
```

## インストール後の操作

zfsマウントポイントを作成します(rootユーザーにsuもしくはsudo等をインストールして操作)

```
# zfs create -o mountpoint=/var/lib/containerd/io.containerd.snapshotter.v1.zfs zroot/containerd
```

containerdを起動します。/etc/rc.d/ に起動の設定を加えておくといいかもしれません。

```
# containerd &
```

## FreeBSDのコンテナを動作させる

コンテナイメージをpullします。


```
$ ctr image pull --snapshotter zfs public.ecr.aws/samuelkarp/freebsd:13.1-RELEASE
```

コンテナを起動します。


 ```
 # ctr run \
    --runtime wtf.sbk.runj.v1 \
    --rm \
     public.ecr.aws/samuelkarp/freebsd:13.1-RELEASE \
    my-container \
    sh -c 'echo "Hello from the container!"'
Hello from the container!　←動いた！！
```

## linuxのコンテナは動くのか

FreeBSDにはlinuxのエミュレーション機能があり「もしかしたら公開されているdockerコンテナイメージが動作するかもしれない」と思い試してみました。

最初にそのままdockerのイメージをpullしようとしたところ失敗

```
$ ctr images pull docker.io/library/busybox:latest
docker.io/library/busybox:latest:                                              resolved       |++++++++++++++++++++++++++++++++++++++| 
index-sha256:ad9bd57a3a57cc95515c537b89aaa69d83a6df54c4050fcf2b41ad367bec0cd5: done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 4.5 s                                                                 total:   0.0 B (0.0 B/s)                                         
unpacking freebsd/amd64 sha256:ad9bd57a3a57cc95515c537b89aaa69d83a6df54c4050fcf2b41ad367bec0cd5...
ctr: no match for platform in manifest sha256:ad9bd57a3a57cc95515c537b89aaa69d83a6df54c4050fcf2b41ad367bec0cd5: not found
```

しかしエラーメッセージを調べてオプションに--platform linux/amd64を加えたところ成功しました。


```
$ ctr images pull --platform linux/amd64 docker.io/library/busybox:latest
~中略~                                      
unpacking linux/amd64 sha256:ad9bd57a3a57cc95515c537b89aaa69d83a6df54c4050fcf2b41ad367bec0cd5...
done: 33.723877ms
```

しかしイメージはpullできましたがコンテナは動作できず。


```
 $ ctr run --rm -t  --runtime wtf.sbk.runj.v1 --platform linux/amd64 --snapshotter zfs  docker.io/library/busybox:latest busy1
ctr: failed to create shim task: runj create failed: unknown
```

無理かなと考えていたのですが、以前HPE の古賀さんが紹介していたFreeBSD Docker の記事があり、その記事を元に記事に掲載されていたコンテナが動作するか確認してみたところ動作しました。


https://www.itmedia.co.jp/enterprise/articles/1606/15/news001.html?fbclid=IwAR3GjY3ih6LOIZla6pWzvJcyByknhFPZAsqDApaSQ8cn_3YQ_g5emulcP8Q


linuxエミュレーションを有効化します。

```
# pkg install linux_base-c7
# kload linux
# kload linux64
```

イメージのpull→成功


```
$ ctr images pull --platform linux/amd64 docker.io/library/centos:7.2.1511
   ~ 中略~
   total:   0.0 B (0.0 B/s)                                         
unpacking linux/amd64 sha256:50cca1e74da4b6a4eb4ade029c8fdd4ee8564776801914d9bd89df8c6344add0...
done: 4.011513ms	
```
動作も成功

```
# ctr run --rm -t  --runtime wtf.sbk.runj.v1 --platform linux/amd64 --snapshotter zfs  docker.io/library/centos:7.2.1511 cent7_01 /bin/bash
[root@ /]#  ←動作した!!
```

Samuel Karpさんのブログを参照して、設定ファイルとオプションを追加するとネットワークも使えるようになります。


```
# cat <<EOF >runj.ext.json
> {"network":{"ipv4":{"mode":"inherit"}}}

# ctr run --rm -t --runtime wtf.sbk.runj.v1 --platform linux/amd64 --runtime-config-path $(pwd)/runj.ext.json --snapshotter zfs  docker.io/library/centos:7.2.1511 cent7_01 /bin/bash
[root@ /]#
[root@ /]# yum update
Loaded plugins: fastestmirror
~中略~   
Complete!
[root@ /]#
```

ということで、一応CentOS系のコンテナが動作したのですが、debian系のエミュレーションを追加すればもしかすると他に動作するコンテナが出てくるかもしれません。

runjは現在も開発が進んでおり、色々と面白そうなので時間があれば色々と試してみようかと思います。