2017年1月28日土曜日

Pound と Apache で docker-compose(version2) を試す


下記のdocker-compose の日本語ドキュメントを参考にして、試してみました。
http://docs.docker.jp/index.html 
Pound コンテナ1個と Apache のコンテナを複数作成して、負荷分散してみます。
Dockerホストの環境は以下のとおり。
  • CentOS7
  • docker1.10.3
  • docker-compose1.10.0


docker-compose 設定


docke-compose でコンテナを作成して、動作確認できるように準備します。

ディレクトリ・ファイル構成


テスト用に作成したファイルは以下のとおり。
demo ディレクトリ以下に配置しました。
デフォルトだと、ディレクトリ名の demo が docker-compose のプロジェクト名として使用され、コンテナ名などに設定されます。
[root@centos0702 docker]# tree -F demo
demo
├── docker-compose-scale.yml
├── docker-compose.yml
├── http/
│   ├── Dockerfile
│   └── entry.sh*
└── pound/
    ├── Dockerfile
    └── entry.sh*

2 directories, 6 files
[root@centos0702 docker]# ls -Rl demo
demo:
合計 8
-rw-r--r-- 1 root root 114  1月 22 11:21 docker-compose-scale.yml
-rw-r--r-- 1 root root 233  1月 22 10:41 docker-compose.yml
drwxr-xr-x 2 root root  38  1月 22 11:19 http
drwxr-xr-x 2 root root  38  1月 22 11:21 pound

demo/http:
合計 8
-rw-r--r-- 1 root root  98  1月 21 22:46 Dockerfile
-rwxr-xr-x 1 root root 395  1月 22 11:19 entry.sh

demo/pound:
合計 8
-rw-r--r-- 1 root root  203  1月 22 11:20 Dockerfile
-rwxr-xr-x 1 root root 1400  1月 22 11:17 entry.sh

Webコンテナ


Webコンテナ構築用の Dockerfile は以下のとおり。
centos6 に apache をインストールして /entry.sh を ENTRYPOINT に設定します。
[root@centos0702 demo]# cat ./http/Dockerfile
FROM centos:6
MAINTAINER blue21
RUN yum -y install httpd
COPY entry.sh /
ENTRYPOINT ["/entry.sh"]

entry.sh の内容は以下のとおり。
コンテナのホスト名を index.html で返すようにして、Apache を起動します。
[root@centos0702 demo]# cat ./http/entry.sh
#!/bin/bash
###################################
# WebコンテナのEntryPoint
###################################

#----------------------------------
# 1. ホスト名を返す index.html 作成
#----------------------------------
uname -n > /var/www/html/index.html

#----------------------------------
# 2. ApacheHTTP 起動
#----------------------------------
/usr/sbin/httpd -D FOREGROUND

Poundコンテナ


Pound コンテナ構築用の Dockerfile は以下のとおり。
CentOS6 に Pound をインストールして /entry.sh を ENTRYPOINT に設定します。
[root@centos0702 demo]# cat ./pound/Dockerfile
FROM centos:6
MAINTAINER blue21
RUN yum -y install epel-release
RUN yum -y install Pound
COPY entry.sh /
ENTRYPOINT ["/entry.sh"]
# entry.sh の引数を指定する(Wbeコンテナの数)
CMD ["1"]

entry.sh の内容は以下のとおり。
/etc/pound.cfg を作成して、Pound を起動します。
バックエンドの数は、entry.sh の引数で指定します。
[root@centos0702 demo]# cat ./pound/entry.sh
#!/bin/bash
###################################
# PoundコンテナのEntryPoint
#
#   $1 : webコンテナ数
#
###################################

CONFIG_FILE='/etc/pound.cfg'
PARAMS="-f ${CONFIG_FILE}"

#----------------------------------
# 1. pound 設定ファイルの作成
#----------------------------------
cat<<EOF > ${CONFIG_FILE}
User "pound"
Group "pound"
Daemon 0
LogLevel 3
LogFacility local1
Alive 25

ListenHTTP
        Address 0.0.0.0
        Port    80
End
Service
        HeadRequire "Host: .*"
EOF

# 引数で指定された数のバックエンドを設定
#   コンテナ名で名前解決して IPアドレスを取得する
#   コンテナ名は <プロジェクト名>-<サービス名>-<連番>
#   プロジェクト名とサービス名は、docker-compose.yml で環境変数に設定
BACKEND_MAX=$1
BACKEND_HOSTNAME="${POUND_PROJECT_NAME}_${POUND_BACKEND_NAME}"
for ((i=1; i < ${BACKEND_MAX}+1; i++)); do
    ip=`host -4 -t a ${BACKEND_HOSTNAME}_${i} | awk '{print $4}'`
    echo "        BackEnd"               >> ${CONFIG_FILE}
    echo "                Address ${ip}" >> ${CONFIG_FILE}
    echo "                Port    80"    >> ${CONFIG_FILE}
    echo "        End"                   >> ${CONFIG_FILE}
done

echo "End" >> ${CONFIG_FILE}

#----------------------------------
# 2. pound の起動
#----------------------------------
/usr/sbin/pound ${PARAMS}

基本構成(docker-compose.yml)


コンテナの基本構成を定義します。デフォルトで、このファイルが使用されます。
pound コンテナと web コンテナが 1個づつです。
pound コンテナは、entry.sh の渡す環境変数を定義し、webコンテナが先に起動するように依存関係を設定しています。
[root@centos0702 demo]# cat docker-compose.yml
version: '2'
services:
  web:
    build: ./http
    image: centos6_http
  pound:
    build: ./pound
    image: centos6_pound
    environment:
      - POUND_PROJECT_NAME=demo
      - POUND_BACKEND_NAME=web
    depends_on:
      - web

スケールアウト構成(docker-compose-scale.yml)


webコンテナが2台にスケールアウトしたときの構成を定義します。
上記の基本構成との差分のみ設定しています。
command で entry.sh の引数 を 2 に変更し、WEBコンテナ2台をバックエンドにします。
80 ポートを公開して外部から pound コンテナにアクセスできるようにします。
[root@centos0702 demo]# cat docker-compose-scale.yml
version: '2'
services:
  pound:
    environment:
      - DEBUG=on
    ports:
      - "80:80"
    command: [ "2" ]


動作確認


準備ができたので、docker-compose コマンドを実行して試していきます。
docker-compose.yml のあるディレクトリで docker-compose コマンドを実行します。

コンテナのイメージ作成


webコンテナとpoundコンテナのイメージを作成してローカルに保存します。
[root@centos0702 demo]# docker-compose build
Building web
Step 1 : FROM centos:6
 ---> 8315978ceaaa
Step 2 : MAINTAINER blue21
 ---> Running in c9f0ef882d96
 ---> 9de1ba110090
~省略~
Removing intermediate container 458db4b56969
Step 7 : CMD 1
 ---> Running in 36c142efba74
 ---> 104519202f48
Removing intermediate container 36c142efba74
Successfully built 104519202f48

ローカルのイメージを確認します。centos6_http と centos6_pound が作成されたイメージです。
[root@centos0702 demo]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos6_pound       latest              104519202f48        3 minutes ago       547.6 MB
centos6_http        latest              5f6b06a8687e        9 minutes ago       501.9 MB

基本構成のコンテナ起動


デタッチモードでコンテナを起動します。依存関係を設定しているので webコンテナ→pound コンテナの順番で起動します。
[root@centos0702 demo]# docker-compose up -d
Creating network "demo_default" with the default driver
Creating demo_web_1
Creating demo_pound_1

コンテナの状態を確認します。
webコンテナとpoundコンテナが1台づつ起動しています。
コンテナ名は、自動的に設定されます。
[root@centos0702 demo]# docker-compose ps
    Name         Command     State   Ports
------------------------------------------
demo_pound_1   /entry.sh 1   Up
demo_web_1     /entry.sh     Up

webコンテナでコマンドを実行して、ホスト名を確認します。
[root@centos0702 demo]# docker-compose exec web uname -n
af210e87d396

pound コンテナでコマンド実行して、pound経由でwebコンテナにリクエストしてみます。
webコンテナのホスト名が表示されたらOKです。
[root@centos0702 demo]# docker-compose exec pound curl -s http://localhost
af210e87d396

webコンテナのスケールアウト


webコンテナを2台に増やしてみます。
[root@centos0702 demo]# docker-compose scale web=2
Creating and starting demo_web_2 ... done

コンテナを確認すると web コンテナが1台追加されて2台に増えています。
[root@centos0702 demo]# docker-compose ps
    Name         Command     State   Ports
------------------------------------------
demo_pound_1   /entry.sh 1   Up
demo_web_1     /entry.sh     Up
demo_web_2     /entry.sh     Up


pound コンテナの再構築


バックエンドが2台になるようにpoundコンテナを再構築します。
まず、スケールアウト用の差分設定をマージして設定内容を確認してみます
[root@centos0702 demo]# docker-compose -f docker-compose.yml -f docker-compose-scale.yml config
networks: {}
services:
  pound:
    build:
      context: /root/workspace/docker/demo/pound
    command:
    - '2'
    depends_on:
    - web
    environment:
      DEBUG: 'on'
      POUND_BACKEND_NAME: web
      POUND_PROJECT_NAME: demo
    image: centos6_pound
    ports:
    - 80:80
  web:
    build:
      context: /root/workspace/docker/demo/http
    image: centos6_http
version: '2.0'
volumes: {}

pound コンテナを作り直して置き換えます。
--no-deps を指定すると依存関係を無視して pound だけ再構築します。
[root@centos0702 demo]# docker-compose -f docker-compose.yml -f docker-compose-scale.yml up -d --no-deps pound
Recreating demo_pound_1

コンテナを確認します。
entry.sh の引数が "2" になり、80ポートが公開されています。
[root@centos0702 demo]# docker-compose ps
    Name         Command     State         Ports
-------------------------------------------------------
demo_pound_1   /entry.sh 2   Up      0.0.0.0:80->80/tcp
demo_web_1     /entry.sh     Up
demo_web_2     /entry.sh     Up

Dockerホストからリクエストすると、poundコンテナが負荷分散してwebコンテナ2台のホスト名が表示されます。
[root@centos0702 demo]# curl -s http://localhost
4bd9e6481714
[root@centos0702 demo]# curl -s http://localhost
af210e87d396
[root@centos0702 demo]# curl -s http://localhost
4bd9e6481714
[root@centos0702 demo]# curl -s http://localhost
4bd9e6481714
[root@centos0702 demo]# curl -s http://localhost
af210e87d396

pound の設定ファイルを見ると、バックエンドが2台になっています。
[root@centos0702 demo]# docker-compose exec pound cat /etc/pound.cfg
User "pound"
Group "pound"
Daemon 0
LogLevel 3
LogFacility local1
Alive 25

ListenHTTP
        Address 0.0.0.0
        Port    80
End
Service
        HeadRequire "Host: .*"
        BackEnd
                Address 172.18.0.2
                Port    80
        End
        BackEnd
                Address 172.18.0.4
                Port    80
        End
End

コンテナの破棄


以下のようにコンテナを破棄できます。
起動中のコンテナを停止して削除します。
[root@centos0702 demo]# docker-compose down
Stopping demo_pound_1 ... done
Stopping demo_web_2 ... done
Stopping demo_web_1 ... done
Removing demo_pound_1 ... done
Removing demo_web_2 ... done
Removing demo_web_1 ... done
Removing network demo_default