dockerコンテナ + nginx WEBサーバのレスポンスを計測

このエントリーは、<a href="http://qiita.com/advent-calendar/2017/excite" target="_blank">エキサイト Advent Calendar 2017</a>の12/18の記事です。

## 本エントリーの概要
あらたにdockerコンテナ上でWEBサーバを稼動させたいと思い、現状動作環境と新規dockerコンテナ環境のWEBサーバレスポンスをJMeterで計測したレポートになります。
また、各種設定時にはまってしまった点を備忘録として残しています。

環境A（現状環境）は、Ubuntu16.04 + nginx/1.10.3 です。
環境B（新規dockerコンテナ環境）は、Ubuntu16.04 + docker(17.09.0-ce) + nginx/1.10.3 です。
ハード環境は、同じスペックで静的コンテンツhtmlを設置しリクエストを負荷をかけました。

|  | 環境A<br>(Ubuntu16.04 + nginx) | 環境B<br>(Ubuntu16.04 + docker + nginx) |
|:-----:|:-----:|:-----:|
|ホストOS|Ubuntu16.04|Ubuntu16.04|
|dockerコンテナ| なし | あり |
|webサーバ|nginx|nginx(※)|
|vhost|環境A.jp|環境B.jp|
※docker コンテナで nginxを起動。

## Ubuntu16.04 + nginx 環境の構築
シンプルにnginxをインストールした構成になります。

`sudo apt-get update`
`sudo apt-get install -y nginx`

バーチャルホスト環境A.jpのconf設定

```nginx:環境A.jp.conf
server {
    listen 80;
    server_name 環境A.jp;

    location / {
        root /home/hoge-hoge/環境A.jp/htdocs;
        index  index.html;
    }
}
```

**本環境構築ではまったポイント**
特に何事もなく環境が構築できました。

## Ubuntu16.04 + docker + nginx 環境の構築
Docker CEをインストールし、nginxが動作するdockerコンテナを起動した構成になります。
dockerイメージは、プロキシ経由で取得しています。

### dockerインストール
Docker CE(Community Edition)をインストールしました。
下記は、Docker CEのインストールコマンド備忘録となります。

```
#
# docker-ce インストール（※1）
#
sudo apt-get update
sudo apt-get -y install apt-transport-https  ca-certificates  curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-cache madison docker-ce
sudo apt-get install -y docker-ce
sudo service docker status
sudo docker info

#
# dockerでプロキシ設定（※2）
#
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
=====ファイルの中身
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:80/" "HTTPS_PROXY=http://proxy.example.com:80/" "NO_PROXY=localhost,127.0.0.1"
=====
sudo systemctl daemon-reload
sudo service docker restart

#
# プロキシ情報が参照できれば設定完了です。
#
docker info | grep 'Proxy'
> Http Proxy: http://proxy.example.com:80
> Https Proxy: http://proxy.example.com:80
> No Proxy: localhost,127.0.0.1

#
# 任意ユーザ(hoge-user)でdockerコマンドが実行できるように設定
#
sudo gpasswd -a hoge-user docker
sudo service docker restart

#
# hoge-userでログインしコマンドが実行できれば設定完了です。
#
docker info
```
※1 docker-ceインストールについて
インストールについて公式なドキュメントがありますのでそちらを確認いただくのがよいかと思います。
https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/#trusty-1404

※2 docker プロキシ設定について
HTTP プロキシサーバの背ろにいる場合の設定について
http://docs.docker.jp/engine/articles/systemd.html

### dockerコンテナでnginx webサーバ環境を構築
下記構成でdockerコンテナを作成しました。

```text:環境B.jp構成
環境B.jp
  ┣ docker/
  ┃   ┣ Dockerfile
  ┃
  ┣ nginx/
  ┃   ┣ log/
  ┃   ┣ sites-enabled/
  ┃       ┣ 環境B.jp.conf
  ┃
  ┣ htdocs/
    　 ┣ hello.html
```

docker image のベースイメージは、ubuntu:16.04になります。
https://hub.docker.com/_/ubuntu/

```text:dockerfile
# base image
FROM ubuntu:16.04

# set proxy
ARG http_proxy
RUN echo "http_proxy : ${http_proxy}"

# set up nginx
RUN set -ex \
    && apt-get update \
    && apt-get install -y nginx \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

CMD ["nginx", "-g", "daemon off;"]
```

ビルドコマンド 

```
cd /home/hoge-user/環境B.jp/docker
docker build --network host --build-arg http_proxy=${http_proxy} -t 環境B-image -f ./Dockerfile .
```

バーチャルホスト環境B.jpのconf設定

```nginx:環境B.jp.conf
server {
    listen 80;
    server_name 環境B.jp;

    location / {
        root  /var/www/htdocs;
        index index.html;
    }
}
```

構築したdockerイメージからdockerコンテナ起動をします。
起動時に環境B.jp バーチャルホストconf、ドキュメントルート、nginxログ出力パスをdockerコンテナ内にマウントします。

```text:コンテナ起動
docker run \
  -d \
  -v /home/hoge-user/環境B.jp/nginx/sites-enabled:/etc/nginx/sites-enabled \
  -v /home/hoge-user/環境B.jp/nginx/log:/var/log/nginx \
  -v /home/hoge-user/環境B.jp/htdocs:/var/www/htdocs:ro \
  --name 環境B-container \
  --net=host \
  環境B-image
```

**本環境構築ではまったポイント**
docker環境にプロキシ設定を追加したものの dockerコンテナ内からapt-get updateを実行してもまったく進行しない（通信できてない？）状況にはまりました。
試行錯誤の末、ネットワークをhost モードにすることで無事 apt-get update, install が実施できました。
`--net=host` オプションの追加。
bridgeモードは、引き続きの課題です。

## JMeter でレスポンス計測
JMeter で環境A.jp(Ubuntu16.04 + nginx) と環境B.jp(Ubuntu16.04 + docker + nginx)環境のサーバレスポンスを計測しました。
計測内容は、秒間50・100リクエスト送信を1秒スリープで100回・50回試行し、総リクエストが5,000リクエストになるように調整しています。
それぞれの結果を散布図でレポートします。

**秒間50リクエスト送信を1秒スリープで100回試行**

5000リクエストに対するサーバレスポンスの散布図です。
![環境A-02-50.png](https://qiita-image-store.s3.amazonaws.com/0/214346/0b814a89-4d91-3306-497b-48de91b6c23f.png)

**秒間100リクエスト送信を1秒スリープで50回試行**

5000リクエストに対するサーバレスポンスの散布図です。
![環境A-02-100.png](https://qiita-image-store.s3.amazonaws.com/0/214346/85f4e128-97ab-d1ad-033e-1ee065710ac4.png)


計測結果として、環境A、環境Bともほとんどのリクエストが200ms内でレスポンスされており、環境間に大きな差異はありませんでした。
ひきつづきdocker環境の構築を進めようと思います。

## 参考
* [Get Docker CE for Ubuntu](https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/)
* [systemd と Docker の管理・設定](http://docs.docker.jp/engine/articles/systemd.html)
* [OFFICIAL REPOSITORY ubuntu](https://hub.docker.com/_/ubuntu/)


お忙しい中、お付き合いくださりありがとうございました。

明日、<a href="http://qiita.com/advent-calendar/2017/excite" target="_blank">エキサイト Advent Calendar 2017</a> 12/19の記事もお楽しみに！