##Docker運用の困りどころ
dockerを運用していて困るところがイメージのビルドと転送にかかる時間です。
僕の環境ではマシンは非力な上にミドルウェアをソースビルドしているのですべてのイメージをビルドすると30分とかかかります。
dockerレジストリへイメージをpushしたりpullしてくるのにかかる時間も相当なものです。
そんな困ったところを少しでも効率的にするために気をつけていることを書いていきたいと思います。
##イメージはレイヤー化する
Dockerイメージをうまくレイヤー化して構成することで、ビルドや転送にかかる時間を減らすことができます。
たとえば下記のようなレイヤー構成です。
-centos6
|- mybase : 自身のサービス用のベースイメージ
| - web_base : ウェブサーバー向けのミドルウェアを追加したイメージ
| | - webapp : 自身のサービスのウェブアプリを追加したイメージ
| - reverse_proxy : リバースプロキシ(Nginx)
fluentdやsupervisorなどほとんどのイメージで使うパッケージと基本的な設定を含めたmybaseイメージを作成しておきます。
他のイメージはmybaseをベースイメージとして作成します。こうしておけば、mybaseに変更が入らない限り差分のビルドと転送で済みます。
web_baseのように中間のイメージを増やすことで更に効率化できる場合があります。ミドルウェアとその設定などの変更が入りにくい部分とサービスように変更が入りやすい部分を別レイヤーにしておくことでビルド時間や転送を最小限にすることができます。
##中間レイヤーを削除してイメージを小さくする。
上記の例でいうmybaseにあたるイメージに関してはdocker exportとdocker importを使って単一レイヤーのイメージとなるようにしています。
それより下層のイメージでは差分で転送できなくなってしまうので同様の処理は行いません。
##Dockerfileのコマンドの記述に気をつける
1.変更が発生しやすいコマンドをなるべく後に記述する
docker build はコマンドごとに中間レイヤーを作成してキャッシュしてくれます。
次にdocker buildしたときに変更がなければ処理は飛ばすことができるため、変更が発生しやすいコマンドを後に記述することでビルド時間を短縮できます。
2.RUNコマンドは&&オペレータでつなげて回数を減らす
Dockerfileのコマンドごとに中間イメージが作成されるためコマンドの回数を減らすことでビルドの時間やレイヤー数を減らすことができます。
3.Dockerに追加したいファイルはディレクトリにまとめてADD一回で追加。その後各ファイルをRUN cpなどで必要な場所に移動。
これもコマンドの数を減らすことでビルド時間とレイヤー数を減らすためにしています。
##ビルドサーバーを用意する
Dockerは実はビルドだけでなくdocker pushやpullにも多量のCPUリソースを使います。
イメージをgzip圧縮または展開しながら転送するからです。
このため、CPUの性能によって転送速度がまったく違ってきます。
開発サーバーが非力な場合、別途CPUが強力なビルドサーバーを用意できると効率的にDokcerの作業ができます。
ビルドサーバーを用意できない場合、以下の様な代替策があります。
1.Docker作業の時だけAWSのスポットインスタンスなどで高速なマシンを借りる
2.ローカルマシンが強力であれば、Docker関連はリモートサーバーではなくVagrantなどを使ってローカルマシンで作業する