Docker のコンテナ間通信のベンチマーク

Docker 1.7.0 でヘアピンNAT対応が入った。そこで、link の代わりに Publish を使った場合にどの程度パフォーマンスが落ちるのかベンチマークしてみる。

まず、Docker の link機能を使う際には例えば link 元コンテナが再起動した場合に破綻するなど扱いが難しい面がいくつかある。そこで、代わりに Publish でコンテナ間を繋ぐという方法が考えられるが、この方法はポートの重複が許容されないなどとともに転送用の Proxy ソフトウェア(docker-proxy)を経由するのでパフォーマンスが低かった。 今回のアップデートで daemon 起動時のオプションに--userland-proxy(デフォルトは true なので今までどおり)が追加され、上記転送用 Proxy ソフトウェアを利用するか、iptables + route_localnet を使うか選択できるようになった。後者の場合、転送処理は kernel 空間で完結し TCP セッションも管理しなくていいのでパフォーマンスが上がるだろうと考えている。

構成

今回の memcached コンテナに対して、memslapベンチマークを行うが、その際の構成は次のようになる。

link の場合

f:id:mapk0y:20150620122637p:plain

--userland-proxy=true の場合

f:id:mapk0y:20150620122646p:plain

--userland-proxy=false の場合(Ver 1.7.0 以降可能)

f:id:mapk0y:20150620122651p:plain

ベンチマーク

ベンチマーク環境

サバフェス の景品で頂いた Intel NUC。静かで小さくて使いやすい。ありがとうございます!!!!!

ベンチマーク方法

memcached のコンテナに対して、memslap の入ったコンテナでアタックをしてみる。

実行するコマンドは以下。

  • memched コンテナの起動コマンド
$ docker run -d -p 11211:11211 memcached
  • memslap コンテナの起動コマンド
$ # docker ホスト経由
$ docker run --rm mapk0y/memslap \
  --servers=172.17.42.1:11211
  --flush --test set
  --concurrency=4
  --execute-number=100000
$ # link 経由の場合
$ docker run --rm --link=memcached mapk0y/memslap
  --servers=memcached:11211
  --flush --test set
  --concurrency=4
  --execute-number=100000

172.17.42.1 は docker0 のデフォルトのIPアドレス。これはホストマシンのホスト名や外側のIPアドレスなどでも良いが、link の代わりにこれらをエンドポイントして使う。

ベンチマーク結果

各1回だけ

タイプ 結果
link 4.466 sec
userland-proxy=true(今まで) 8.481 sec
userland-proxy=false 4.690 sec

期待通り今までより性能の劣化が圧倒的に少ない。また、今回ベンチマークは取っていないがコンテナ間だけでなくホストから 127.0.0.1:11211 などへの通信のような場合も性能の劣化が少なくなるはず。

ただし、kernel のバージョン(3.5以前?)によっては設定できないので注意が必要。