📦

DockerfileのCOPY --fromでお手軽にBusyBoxを足す

2022/06/06に公開

Dockerやk8s等でコンテナをデバックする際、どうしてもコンテナの中に入って各種コマンドを打ってみたくなることがあると思います。
しかし、よくできた軽量なコンテナほど余計なものが入っていないので、必要最低限のコマンドすらない……となるのもありがちです。下手するとシェルすら入っていません。

そんな時に備えてDockerfileに

# タグ等は適宜変更してください
COPY --from=busybox:1.28 /bin/busybox /bin/busybox

を書き足しておくといいかもよ、という話をまとめた記事です。

BusyBoxとは

BusyBoxは、数多くのUNIXコマンド類を一つのバイナリに詰め合わせたものです。例えばsh, vi, grep, awkなど馴染みのあるコマンドがサブコマンドの形で格納されています。

$ busybox echo 'Hello BusyBox'
Hello BusyBox

BusyBoxはたくさんコマンドが入っているのに1MB程度のサイズしかありません。そのため、これをコンテナイメージに含めておくと、大きなコストを伴わずにコンテナ内でできることを増やせます。

コンテナイメージにBusyBoxを入れる

そういうわけで、コンテナイメージにBusyBoxを入れることを考えます。シングルバイナリなので足す方法はいろいろあると思いますが、簡潔なのは最初に紹介した書き方です。

Dockerfileの例
FROM hello-world
COPY --from=busybox:1.28 /bin/busybox /bin/busybox

すなわち、Dockerfile中のCOPY --fromでBusyBoxのDockerイメージを指定し、その中にあるbusyboxバイナリをコピーします。

--from はマルチステージビルドの前段ステージを指すフラグじゃなかったの? と思うかもしれません。Dockerfileのドキュメントを読むと、こんなことが書かれています。

Optionally COPY accepts a flag --from=<name> that can be used to set the source location to a previous build stage (created with FROM .. AS <name>) that will be used instead of a build context sent by the user. In case a build stage with a specified name can’t be found an image with the same name is attempted to be used instead.
https://docs.docker.com/engine/reference/builder/#copy

どうやら指定された名前がステージ名に見つからなかったとき、Dockerはそれをイメージ名として解決しようとするようです。結果的にこのコマンドはbusyboxイメージを解決してその中のバイナリをコピーしてくれます。

まとめ

  • BusyBoxというのがある。軽量でいろいろなコマンドが詰まっているので何かの時に便利
  • DockerfileのCOPY --fromは参照先に別のイメージを選ぶこともできる

参考書籍

筆者はこのテクニックを『Kubernetesで実践するクラウドネイティブDevOps』で知りました。

https://www.oreilly.co.jp/books/9784873119014/

Discussion