systemd-nspawn上でGitea Actionsのランナー(Dockerコンテナ)を動作させた記録
はじめに
私のサーバーでは、systemd-nspawnを利用してサービス毎に環境を分離させています。
そのため、Gitea Actionsを利用するためにはコンテナ上でさらにDockerを動作させる必要があるのですが、そのままDockerを入れただけでは下記のようなエラーが出て動作しませんでした。
|
|
nspawnの設定を変更し、動作させることができたので共有します。
環境
- ホストOS
- Ubuntu 20.04
- Linux 5.4 (デフォルト)
- cgroup v1 (デフォルト)
- コンテナOS
- Arch Linux
手順
以前Arch Wikiに記載されていた方法では、コンテナのnamespaceを無効にし、nspawnの利点であるrootの分離などを全て無効化した上で/sys/fs/cgroup
を直接マウントする事でなんとか動作させていました。
しかし、最近更新された方法を用いると、cgroup v2環境では、nspawnコンテナのセキュリティ機能を大きく損なう事無くDockerを動作させる事ができるようです。
Ubuntu20.04上にて上記の方法を利用するには、以下の手順が必要です。
- systemd-nspawnのユニットファイルを編集
- コンテナにfuse-overlayfsを導入
ホスト側設定
cgroup v2に変更
コンテナ上で、mount | grep cgroup
を実行し、/sys/fs/cgroupがtmpfs
であればcgroup v1が使用されています。
-
cgroup v1の場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
[root@arch ~]# mount | grep cgroup tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,size=4096k,nr_inodes=1024,mode=755,uid=1742209024,gid=1742209024) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd) cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
-
cgroup v2の場合
1 2
[root@arch ~]# mount | grep cgroup cgroup on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
検索すると、grubの設定を変更してカーネルパラメータにsystemd.unified_cgroup_hierarchy=1
を付加する事でv2に変更している記事が多くヒットします。1
しかし、systemd-nspawnを使っている場合、ユニットファイルを変更するだけでコンテナ上だけv2動作させる事が可能です。
むしろ検証の結果、Ubuntu20.04ではカーネルパラメータを用いてホストをv2としても、コンテナはv1のままだったため、ホストの設定を変更する必要は全くないです。
-
-
ユニットファイルを編集
1
systemctl edit systemd-nspawn@arch.service
-
下記を記述
[Service] Environment=UNIFIED_CGROUP_HIERARCHY=1
-
反映
1 2
systemctl daemon-reload systemctl restart systemd-nspawn@arch.service
-
よく見るとカーネルパラメータと同じ値をセットしている事がわかります。
これが再起動要らずでコンテナに限って反映できるのはsystemd-nspawnの魅力の一つだと思います。
逆に、例えば新しいディストリビューションを使いながら、古いアプリケーションの為にコンテナ上はcgroup v1で動作させるといった事も可能だと考えられます。
nspawn設定の変更
ここからは上で貼ったArch Wiki通りです。
- 設定を開く
1
nano /etc/systemd/nspawn/arch.nspawn
- 以下を記述
[Files] Bind=/dev/fuse [Exec] SystemCallFilter=add_key keyctl bpf
- Fuseを許可
1
systemctl set-property systemd-nspawn@arch DeviceAllow='/dev/fuse rwm'
コンテナ側設定
overlayfs導入
Wiki通りに
|
|
あとは、Dockerで確認します。
|
|
act_runner導入
Gitea Actionsの為にはact_runnerをインストールする必要があります。
AURにsystemdユニット付きのパッケージがあるので利用すると良いと思います。
設定は以下の感じで
|
|
おわりに
昔はsystemd-nspawn上でDockerを動かすのがとんでもなく無駄な気がしていましたが、現在の方法であればより安全に、かつホストを汚すことなく動作できて良いかなと思います。
nspawnのcgroup変更など、ドキュメントに書いてあった?みたいな技を使う事になりましたが、とりあえずActionsできて良かった…
おまけ: act_runnerでカスタム名前解決を利用したい
Giteaと同じコンテナで動いているにも拘わらず、外側のURLを設定する事を強要される関係で、デフォルトだと(ヘアピンNAT非対応環境であれば)checkoutなどが利用できません。
ホストをlocalhostに転送するために/etc/act_runner/act_runner.yaml
を以下のように編集します。
|
|
試してないですがnetworkをhostにするのでも良いらしい? 流石に危険な気がするのでbridgeにしますが…