Ubuntu Weekly Recipe

第594回 mmdebstrapで最小のルートファイルシステムを作る

この記事を読むのに必要な時間:およそ 8 分

ルートファイルシステムのクロスビルド

もちろんホストとは異なるCPUアーキテクチャーのルートファイルシステムの構築も可能です。あらかじめqemu-user-staticとbinfmt-supportをインストールしておきます。これによりホストと異なるアーキテクチャーのバイナリを実行する際に,自動的にqemu-user-staticを経由してくれます。

$ sudo apt install qemu-user-static binfmt-support

あとは次のコマンドを実行するだけです。

$ mmdebstrap --components="main restricted universe multiverse" \
  --architecture=arm64 \
  eoan eoan-arm64-rootfs http://ports.ubuntu.com/ubuntu-ports

--architecture=arm64でCPUアーキテクチャーを指定できます。

注意しなければならないのはミラーサーバーの部分です。Ubuntuの公式リポジトリサーバーでサポートしているアーキテクチャーはamd64とi386だけです※4⁠。それ以外のUbuntuでサポートしているアーキテクチャーについては,⁠http://ports.ubuntu.com/ubuntu-ports」を指定する必要があります※5⁠。具体的にはarmhf,arm64,ppc64el,s390xがこれに該当します。

※4
さらにUbuntu Weekly Topicsでも何度も話題にしているように,i386は段階的にリポジトリから削除されていく見込みです
※5
日本向けの非公式なミラーサーバーとして「http://jp.archive.ubuntu.com/ports」も存在しますが,⁠必要としているユーザーがそれなりに存在すると思われる」アーキテクチャー・リリースしか用意されていません。

残念ながら,Ubuntu 18.04 LTS上のLXDコンテナ上で実行した場合,上記コマンドは次のように失敗します。

$ mmdebstrap --components="main restricted universe multiverse" \
  --architecture=arm64 \
  eoan eoan-arm64-rootfs http://ports.ubuntu.com/ubuntu-ports
I: automatically chosen mode: unshare
I: arm64 cannot be executed, falling back to qemu-user
update-binfmts: warning: qemu-aarch64 not in database of installed binary formats.
update-binfmts: exiting due to previous errors
E: qemu-aarch64 is not a supported binfmt name

これは権限や名前空間の都合上,binfmt関連の情報をうまく読めないためです。4.15カーネルではうまくいきませんでしたが,5.3カーネルだと設定によっては,ホストにもqemu-user-staticとbinfmt-supportをインストールすればうまく動いたので,将来的にはコンテナ上でもクロスビルドができるようになるかもしれません。

ちなみに--architecturesオプションにはカンマ区切りで複数のCPUアーキテクチャーを指定可能です。その場合,2つ目以降の指定は,dpkgで言うところの--add-architectureオプションが指定された状態でルートファイルシステムが作られます。MultiArchな環境を作りたい場合に便利でしょう。

ルートファイルシステムのサイズを減らす方法

実はこの時点で,ルートファイルシステムのサイズとしては,debootstrapで作ったものと大差ありません。

$ sudo du -hs eoan-*rootfs/ | sort -nr
334M    eoan-debootstrap-rootfs/
269M    eoan-rootfs/

サイズとしてはそこそこ差が出ていますが,⁠どちらも大きい」という意味ではあまり差がない状態です。より小さいルートファイルシステムが欲しいのであれば,--variantオプションを利用します。

debootstrapの--variantはminbaseを指定するとさらに小さくなります。mmdebstrapの場合,さらに様々なvariantオプションが存在します

もっとも小さくなるのはcustomを指定して,--includeで個別にインストールするパッケージを指定する方法ですが,必要なパッケージをリストアップする設定が大変です※6⁠。単に--variant単体で最小となるのはessentialでしょう。

※6
0.4.1以前にはcustomを指定すると,パッケージをうまくインストールできない問題があるようです。
$ mmdebstrap --components="main restricted universe multiverse" \
  --variant=essential \
  eoan eoan-essential-rootfs http://jp.archive.ubuntu.com/ubuntu

ちなみにessentialはaptコマンドすらインストールしないので,今後のカスタマイズを考えるならessentialよりはaptパッケージも追加でインストールするaptのほうが良いかもしれません。

$ sudo du -hs eoan-*rootfs/ | sort -nr
334M    eoan-debootstrap-rootfs/
269M    eoan-rootfs/
119M    eoan-debootstrap-minbase-rootfs/
65M     eoan-essential-rootfs/

かなり小さくなりましたね。

dpkgにはパッケージのインストール時に「特定のファイルパスを除外する」オプションが存在します。このオプションを駆使すれば「パッケージについてくるものの目的の用途では不要なもの」を除外できます。よく除外対象になるのが「manpageのファイル」「翻訳データ」です。

$ mmdebstrap --components="main restricted universe multiverse" \
  --variant=essential \
  --dpkgopt='path-exclude=/usr/share/man/*' \
  --dpkgopt='path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo' \
  --dpkgopt='path-exclude=/usr/share/doc/*' \
  --dpkgopt='path-include=/usr/share/doc/*/copyright' \
  eoan eoan-essential-min-rootfs http://jp.archive.ubuntu.com/ubuntu

--dpkgoptでdpkg固有のオプションを追加できます。追加できるのはdpkgコマンドのオプションから先頭のハイフンを取り除いたものです。

上記の例だと「/usr/share/man/」以下と翻訳データであるmoファイルをすべて削除しています。また,ドキュメント類が格納されている「/usr/share/doc/」以下は削除していますが,ルートファイルシステムの再配布も想定してコピーライトファイルだけは残しています。

$ sudo du -hs eoan-*rootfs/ | sort -nr
334M    eoan-debootstrap-rootfs/
269M    eoan-rootfs/
119M    eoan-debootstrap-minbase-rootfs/
74M     eoan-apt-min-rootfs/
65M     eoan-essential-rootfs/
57M     eoan-essential-min-rootfs/

さらに小さくなりました。⁠eoan-apt-min-rootfs」「eoan-essential-min-rootfs」--variant=essentialの代わりに--variant=aptを指定したものです。

これ以上はもう個別にファイルを削除したり,パッケージを省いたりすることになります。ただし,そこまでくるともう,aptシステムを使えるかどうかも怪しくなってきますし,あえてDebianベースで構築する必要はない気もします。

Dockerイメージとして活用する

作ったルートファイルシステムをDockerイメージにしてみましょう。

$ cd eoan-apt-min-rootfs/
$ sudo tar -c . | docker import - eoan

公式のUbuntu 19.10のイメージと比べると「ほんの少しだけ」小さくなったようです。

$ docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
eoan                     latest              603b264ef4ea        7 seconds ago       68.7MB
ubuntu                   eoan                09604a62a001        3 weeks ago         72.9MB

Ubuntu BaseやUbuntu Minimalとの比較

Ubuntuには組み込み・コンテナ向けの「小さなイメージファイル」として,Ubuntu BaseUbuntu Minimalが存在します。これらとサイズを比較してみましょう。Ubuntu 19.10のイメージは,それぞれ次のURLからダウンロードできます。

$ sudo du -hs * | sort -nr
404M    minimal
77M     base

Ubuntu Baseのほうはeoan-apt-min-rootfsと大差ありませんね。当たり前と言えば当たり前なのですが,Ubuntu Baseも次のような内容の設定ファイルを/etc/dpkg/dpkg.cfg.d/excludesに保存しています。

# Drop all man pages
path-exclude=/usr/share/man/*

# Drop all translations
path-exclude=/usr/share/locale/*/LC_MESSAGES/*.mo

# Drop all documentation ...
path-exclude=/usr/share/doc/*

# ... except copyright files ...
path-include=/usr/share/doc/*/copyright

# ... and Debian changelogs
path-include=/usr/share/doc/*/changelog.Debian.*

http://cdimage.ubuntu.com/ubuntu-base/releases/

まさにmmdebstrapで指定した内容です。その結果,同じようなサイズになっているのです。イメージ作成時にカスタムする必要がないのであれば,Ubuntu Baseも選択肢のひとつとして考えておきましょう。

なおUbuntu Baseには/usr/local/sbin/unminimizeというコマンドが存在します。これを使うと,上記設定を無効化した上で,除外されていたファイルを再インストールしてくれるのです。

ちなみにUbuntu Minimalは,Ubuntu Baseに加えてubuntu-minimalパッケージをインストールしたイメージです。よってどうしてもサイズは大きくなってしまいます。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。