2018-04-07 追記
Docker for Mac の 18.03.0-ce の新機能として、NFS Volume Sharing というのが追加されました。これにより、ローカルファイルシステムのマウント性能が大幅に改善されたので、再度ベンチマークを取っていますので、そちらの結果も参照してみてください。
はじめに
2017/10/21に開催された Fukuoka.php Vol.24 において、「Docker for Mac/Winってどうなの?」というタイトルで発表させていただきました。
その中で Mac および Win での Docker の動作環境によるベンチマーク結果をデモを行いました。
- Fukuoka.php Vol.24 の発表資料
その結果をあらためてまとめ直したのがこの記事です。
測定内容1 - symfony-3.0 のベンチマーク結果
@kenji_s さんが公開されている各フレームワークのベンチマークを測定するためのセットを使用させていただいて、その中で「symfony-3.0」のベンチマークを使って、環境によってどのような結果の違いがでるかというのを比較しました。
なお、kenji_s さんが配布されているリポジトリの内容を mac 上に git clone し、それを各環境にマウントして使用するという形をとりました。
これは、Docker for Mac がローカルマウントしたボリュームに対する読み書きが極端に遅いということをベンチマーク結果に反映させるためです。
測定内容2 - dd コマンドの実行スピード
Docker for Mac のローカルマウントしたボリュームが極端に遅いという 記事を @hanhan1978 さんがブログで公開されてます。
この記事によると、以下のコマンドの実行速度が環境によって極端に変わってくるということなので、その時間を測定しました。
time dd if=/dev/zero of=test bs=1k count=100000
※ 1kb を 100万回書き込む(100MBを書き込む)形となる
測定環境
測定した環境は以下のもの。
- Vagrant + Virtualbox
- Virtualbox 上の CentOS 6.9 の上で、Apache 2.2 + PHP 5.6 を動作させる
- Mac 上のローカルディスクを nfs マウントして使用する
- Vagrant + Virtualbox + CoreOS
- https://github.com/coreos/coreos-vagrant
- Virtualbox 上の CoreOS の上で、Docker環境を作成
- Docker コンテナとして CentOS 6.9 + Apache 2.2 + PHP 5.6 を動作させる
- Mac 上のローカルディスクをVirtualbox のCoreOS上に nfs マウントし、それを更にDockerコンテナにマウントする
- Docker for Mac(通常)
- Macにインストールした Docker for Mac を使用し、Mac上から直接 CentOS 6.9 + Apache 2.2 + PHP 5.6 を動作させる
- Mac 上のローカルディスクをDockerコンテナに普通にマウントする
- Docker for Mac(cached)
- Macにインストールした Docker for Mac を使用し、Mac上から直接 CentOS 6.9 + Apache 2.2 + PHP 5.6 を動作させる
- Mac 上のローカルディスクをDockerコンテナにcachedオプション付きでマウントする
- Docker for Mac(docker-sync)
- Macにインストールした Docker for Mac を使用し、Mac上から直接 CentOS 6.9 + Apache 2.2 + PHP 5.6 を動作させる
- Mac 上に docker-sync を gem install し、それを使って、マウントするためのデータボリュームを作成する
- docker-sync で作成したデータボリュームをDockerコンテナにマウントする
- 実際の同期には rsync を使っている
- Docker for Win
- Windows 10 Proにインストールした Docker for Win を使用し、Win上から直接 CentOS 6.9 + Apache 2.2 + PHP 5.6 を動作させる
- Win 上のローカルディスクをDockerコンテナに普通にマウントする
PHPの実行環境としては以下のもので揃えています。
- CentOS 6.9
- yum で install した Apache 2.2
- remi リポジトリを使用して、yum で install した PHP 5.6
使用した Docker for Mac/Win は以下のバージョン。
- Docker for Mac
- Docker CE edge Version 17.09.0-ce-mac24(19605)
- Docker for Win
- Docker CE edge Version 17.09.0-ce-win34(13622)
測定結果
symfony-3.0 のベンチマーク結果
OS | 環境 | requests per second |
---|---|---|
Mac | Vagrant + Virtualbox | 90.59 |
Mac | Vagrant + Virtualbox + CoreOS Docker環境 | 85.78 |
Mac | Docker for Mac(通常) | 38.10 |
Mac | Docker for Mac(cached) | 83.04 |
Mac | Docker for Mac(docker-sync) | 108.08 |
Win10Pro | Docker for Win | 109.42 |
Vagrant + Virtualbox の組み合わせを基準と考えた場合、
- Vagrant + Virtualbox + CoreOS Docker環境はほぼ変わらない性能がでる
- Docker for Mac の通常のマウント方法はかなり足をひっぱり、性能に対する影響がでかい
- Docker for Mac の cached 方式のマウント方法はかなり頑張っていて、遜色ない性能がでている
- Docker for Mac の docker-sync 方式のマウント方法はかなり性能がでている
- Vagrant環境の NFS を使ったマウントは、それはそれで前々から性能に文句がでているものなので、それよりは rsync を使っている docker-sync のほうが性能がでたということになる
- Docker for Win はかなり頑張っていて、docker-sync を使ったものと同じくらいの性能を発揮する
dd コマンドの実行スピード
環境 | real | user | sys |
---|---|---|---|
Vagrant + Virtualbox | 0m0.238s | 0m0.003s | 0m0.231s |
Vagrant + Virtualbox + CoreOS Docker環境 | 0m0.955s | 0m0.007s | 0m0.179s |
Docker for Mac(通常) | 0m20.227s | 0m0.150s | 0m2.770s |
Docker for Mac(cached) | 0m13.480s | 0m0.090s | 0m0.520s |
Docker for Mac(docker-sync) | 0m0.292s | 0m0.000s | 0m0.290s |
Docker for Win | 0m0.369s | 0m0.030s | 0m0.140s |
Vagrant + Virtualbox の組み合わせ(0.238秒)を基準と考えた場合、
- Vagrant + Virtualbox + CoreOS Docker環境は、少し書き込みスピードに影響がでている(1秒弱)
- Docker for Mac の通常のマウント方法は、@hanhan1978 さんのブログの記事通り、書き込み性能にかなり問題があり、20秒もかかってしまっている
- Docker for Mac の cached 方式のマウント方法は、通常マウントよりは少しマシになっているが、それでもかなり遅い(13秒強)
- Docker for Mac の docker-sync 方式のマウント方法は、素の Virtualbox の時間とほぼ変わらない時間で実行が完了する(0.3秒弱)
- Docker for Win は、素の Virtualbox の時間とほぼ変わらない時間で実行が完了する(0.369秒)
まとめ
現時点での Mac および Windows のDocker環境に関しては以下のような形になると思います。
- Mac でDocker環境を作るならば、Docker for Mac + docker-sync を試してみて、それでも支障がでるならば、Virtualbox を利用する Docker toolbox か、CoreOS ベースのDocker環境を選ぶのがいいと思う
- Docker for Windows は、性能面での心配はほぼない。Hyper-V を ON できる環境であれば使えるので、積極的に使っていくのがいいと思う
使用したファイルたち
Dockerfile
各Docker環境で使用した Dockerfile
FROM centos:6.9
RUN yum -y update \
&& yum -y install epel-release \
&& rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm \
&& yum -y install httpd httpd-devel \
&& yum install -y --enablerepo=remi,remi-php56 php php-cli php-pear php-devel php-mbstring php-mcrypt php-pdo php-mysqlnd php-gd php-xml php-zip php-opcache php-pecl-apcu php-pecl-xdebug
WORKDIR /var/www/html
EXPOSE 80
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
docker-compose.yml
以下の環境で使用した docker-compose 用の設定ファイル
- Vagrant + Virtualbox + CoreOS Docker環境
- Docker for Mac(通常)
- Docker for Win
version: '3.3'
services:
db:
image: mysql:5.7
hostname: db
container_name: db
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- ./data:/var/lib/mysql
ports:
- "3306:3306"
web:
build: .
image: centos69-apache-php
hostname: web
container_name: web
volumes:
- ../htdocs:/var/www/html
ports:
- "8080:80"
depends_on:
- db
docker-compose-cached.yml
Docker for Mac(cached)で使用した、docker-compose 用の設定ファイル
version: '3.3'
services:
db:
image: mysql:5.7
hostname: db
container_name: db
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- ./data:/var/lib/mysql
ports:
- "3306:3306"
web:
build: .
image: centos69-apache-php
hostname: web
container_name: web
volumes:
- ../htdocs:/var/www/html:cached
ports:
- "8080:80"
depends_on:
- db
docker-sync.yml
Docker for Mac(docker-sync)で使用した、docker-sync 用の設定ファイル
version: '2'
syncs:
htdocs-sync:
src: '../htdocs'
docker-compose-with-docker-sync.yml
Docker for Mac(docker-sync)で使用した、docker-compose 用の設定ファイル
version: '3.3'
services:
db:
image: mysql:5.7
hostname: db
container_name: db
environment:
- MYSQL_ROOT_PASSWORD=root
volumes:
- ./data:/var/lib/mysql
ports:
- "3306:3306"
web:
build: .
image: centos69-apache-php
hostname: web
container_name: web
volumes:
- htdocs-sync:/var/www/html:nocopy
ports:
- "8080:80"
depends_on:
- db
volumes:
htdocs-sync:
external: true