Docker: busybox のイメージサイズはなぜ小さい

まあ、このあたりは初心者なので新しい発見が多いわけですが…

この前も使った busybox ですが、サイズがやたらと小さいことに気づきました。

$ docker images
 REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
 busybox       latest    c55b0f125dc6   11 hours ago   1.24MB

えっ、busybox って一通りの基本コマンドが揃っていたような、と思ったわけです。普通 /bin とかこのサイズで収まらないでしょう、と。で、調べてみるとそもそも busybox って十徳ナイフのようなコマンドとして組み込み用に存在していてそれを Docker 用イメージにしたのですね。

Linux の man ページには以下のようにあります。

NAME
        BusyBox - The Swiss Army Knife of Embedded Linux

つまり、複数のコマンドを一つの実行ファイルにし共有できるところを共有・最適化することによりこのサイズを実現しているわけです。そして起動時にどのような名前で呼ばれたかによって動作を変えると。

試しに busybox を起動して中身を確認してみます。

$ docker run -i -t busybox:latest
/ # ls -li /bin
total 449684
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 [
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 [[
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 acpid
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 add-shell
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 addgroup
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 adduser
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 adjtimex
  84754 -rwxr-xr-x  400 root     root       1149184 May  3 21:57 ar
(...省略)

ls に ‘-i’ オプションをつけて inode 番号を表示するようにして /bin の中身を見ました。上の例で一番最初の数字が inode 番号ですが、これはファイルシステム上のどのファイル実体を指しているかを表しています。このように 400 の実行ファイルの inode 番号が同じに表示され (注)、これらの実行コマンドファイルの実体が同じものであることがわかります。ちなみにこの 400 という数はオーナー (root) の前に表示されているリンク数 (400) からもわかりますね。

busybox のサイズの小ささと共に 400 もの機能をひとまとめにしていることに感嘆するわけです。

(注: /bin の中で getconf だけ別の inode 番号を持っていました)

参考: https://busybox.net/