Dockerイメージの最適化

http://www.centurylinklabs.com/optimizing-docker-images/

1 comment | 1 point | by WazanovaNews 3年弱前 edited


Jshiike 3年弱前 | ▲upvoteする | link

米国キャリアのリサーチ部門であるCenturyLink Labsが、

Dockerイメージは1Gを超えることがよくあって、ローカルで実験しているうちはよいが、ネットワークを介して頻繁にやり取りしはじめると、サイズが問題になる。

ということで、dockerイメージのサイズを減らす取り組みについて、ブログで紹介しています。

Layers

  • レイヤの構成の詳細については、Dockerのドキュメントを参照されたし。本議論のポイントとして理解しておかなくてはいけないのは、Dockerfileでの各操作の結果、新しいイメージのレイヤが順次生成されるということ。
  • イメージとレイヤを別物として議論していることが多いが、実はレイヤもイメージであり、イメージを構成するレイヤ群は、イメージの集合体である。

Image size

  • イメージのサイズとはそれを構成する各イメージ(= レイヤ)のサイズの合計である。
  • 各操作は、イメージ全体のサイズを増やす方にしか働かない。(原文の例では試しに、サンプルイメージのサイズのほとんどを占めるfallocateコマンドから生成されたファイルを、すぐにrm で削除しているが、結果は、fallocateコマンドから生成されたファイルのサイズはそのままで、最後にrmで生成されたゼロバイトのレイヤが付加されている。)

Choose your base

  • 当たり前ではあるが、ベースのイメージのサイズが全体へ与える影響は大きい。
  • Centurylink Labsの場合は、ubuntuイメージからdebianイメージに変更すると、100+MB削減できた。
  • UbuntuでBusyBoxを利用すると、不要なスペースをかなりつくってしまう。
  • Docker registryでイメージのサイズを確認するには、ローカルにpullするしかない。

Re-use your base

  • イメージをつくるのにレイヤを使う手法のメリットは、再利用ができること。
  • 例えば、一つのイメージの中で、debian:wheezyイメージ(レイヤ)をベースにした操作を三種類行ったとしても、Debianのコピーが三つあるわけではない。一つのDebian例やのインスタンスへの参照を保持しているだけである。つまり、debian:wheezyイメージを一度pullしたら、それ以上はpullする必要がない。
  • 共通イメージの再利用は、スペースとネットワークのトラフィックの節約に効く。

Chain your commands

  • 現実にありえるシナリオとして、tarファイルをもってきて => 抽出 => ファイルを移動 => 削除という操作をした場合、前述の通り、各ステップでイメージ(レイヤ)を生成してしまう。tarファイルを取得するwgetコマンドで55MB、tarから抽出する過程で99MB、計150MB+が無駄なスペースとなる。
  • そこで、これまでのように各操作を順次実行するのではなく、&&オペレータで一連の操作を一つにまとめて実行する。Dockerfileがやや読みづらくなるものの、イメージレイヤがコミットされる前に、tarファイルの削除とディレクトリの抽出を完了できる。
  • 全てのコマンドを&&オペレータでつなぐことはお薦めしないが、このように、利用したファイルを削除するような一連の操作があるときは、使ってみるとよい。

Flatten your image

  • 自分でイメージをビルドする、もしくはDockerfileにアクセスできるというパターンだけではなく、他人がつくったイメージのサイズを削減したいケースもありうる。その際は、イメージからコンテナを生成する場合は、全てのイメージレイヤがマージされるという仕組みをうまく利用する。
  • 生成したコンテナをexportして、docker importコマンドでコンテンツをパイプすると、コンテナをイメージに戻すことができる。その結果は、一つのレイヤしかなり軽量なイメージとなり、中間で無駄な作業をしたときのファイルサイズがなくなってくれる。
  • 便利なテクニックであるが、デメリットも当然ある。前述のレイヤ間で共通のイメージを使う効果はなくなる。イメージとともに保存されることの多いメタデータは、run/export/importのプロセスで失われる。元々定義してたであろう、ポート / 環境変数 / デフォルトコマンドがなくなる。
  • ということで、いつも利用できるテクニックではないが、どれくらいスペースを節約できるのか確認するには便利。

Adriaan de Jongeのアプローチとの違い

また、Adriaan de Jongeが “Create the smallest possible docker container” で紹介している、「中身を空にして、静的にGoバイナリにリンクしたイメージを用意し、コンテナの起動時に実行することで、3.6MBにする。」というアプローチとの比較については、

  • PythonやRubyを使いたい。
  • もう少しOSレベルのサポートが必要で、数百メガ程度は使っていいので、Debianを実行し、依存関係をapt-get installしたい。

というユースケースの違いだと説明しています。

#docker

Back