前書き
Dockerfileとして基本的な部分も守らずchefからそのまま移行したようなDockerfileでDockerImageを作成している案件があった。その案件で使用しているDockerImageのサイズが約3GBと肥大化していた。
基本的な変更で約30%軽量化できたため備忘録としてやったことを記載する。
対象とする環境
CentOS6+PHP7+apache2.2 という構成
yumのcacheを削除する。
Dockerfileで yum install時には以下のようになっていた
yum install -y wget vim ....
これは単純に
yum install -y wget vim ... \
&& rm -rf /var/cache/yum/* \
&& yum clean all
でyum のcacheを消してあげれば良い。
ソースインストール時の中間ファイルを削除する
なぜかソースインストールでgitをインストールしていた。
(しかも1.9.0 2014年のものである...)
RUN cd /usr/local/src \
&& wget "https://www.kernel.org/pub/software/scm/git/git-1.9.0.tar.gz" \
&& tar zxf /usr/local/src/git-1.9.0.tar.gz \
&& cd /usr/local/src/git-1.9.0.tar.gz}/ \
&& ./configure \
&& make && make install \
dockerなので make uninstallとかもしないし make cleanで中間ファイルを削除してあげればいい
RUN cd /usr/local/src \
&& wget "https://www.kernel.org/pub/software/scm/git/git-1.9.0.tar.gz" \
&& tar zxf /usr/local/src/git-1.9.0.tar.gz \
&& cd /usr/local/src/git-1.9.0.tar.gz}/ \
&& ./configure \
&& make && make install && make clean \
不要なtar.gzとかの削除
お気付きだろうか。上記で落としてきたgit.tar.gzを削除していないことを
RUN cd /usr/local/src \
&& wget "https://www.kernel.org/pub/software/scm/git/git-1.9.0.tar.gz" \
&& tar zxf /usr/local/src/git-1.9.0.tar.gz \
&& cd /usr/local/src/git-1.9.0.tar.gz/ \
&& ./configure \
&& make && make install && make clean \
&& rm /usr/local/src/git-1.9.0.tar.gz
のように削除する。
気をつけないと行けないのは同一レイヤで行うこと。
別レイヤで行うと削除した。というレイヤが作られるので逆にサイズが増加する。
レイヤの結合
Dockerfileの可読性とのトレードオフだがレイヤ結合出来るものは
\
と &&
で結合すればよい。
サイズの削減
上記を行っただけで 3GB -> 2.1GBと約30%削減できた。
(それでも大きい)
理由としてはchef時代のものを精査せず 不要なパッケージやライブラリまでインストールしているため。
現行で動作しているコンテナなので削除できるかどうかの判断ができずかなりつらい所
アンチパターンまとめ
- cacheを削除しない
- 中間ファイル削除しない
- レイヤ結合しない
- chefなど昔の資産に引っ張られてライブラリの精査をしない
その他
たとえばalpineなど軽量のイメージを使用して、必要のあるパッケージだけ使用すればかなり軽量化はできると思われるが、それを良しとしない人間が多いと推し進めていくのは大変である。
どんな技術でもそうだが本質を見失ってとりあえず使えればいいやで導入すると後からメンテナンスする人が困る。
新しい技術を導入するのもいいが、本質を理解した上で適切に使用していく必要がある
参考文献
軽量なDockerイメージで
CIのビルド時間を短くしてみる // Speaker Deck
Dockerイメージの最適化 - ワザノバ | wazanova
Dockerイメージのレイヤー構造について - めもめも