2014年2月24日月曜日

Dockerってなんじゃ?(docker+nginxで複数コンテナにWEBサーバーをたてる)




dockerを使って複数のWEBサーバーを立ててみたいと思います。
複数の外部ポートを使うため、プロキシとしてnginxと併用してみます。

今回は2つのWEBサーバーのコンテナを立て、1つにはwordpress on apache、もう一つは素のnginxを入れてみます。


コンテナにはそれぞれ

  • memorycrat.cloudpack.jp
  • tenkaippin.cloudpack.jp

というドメインを割り当てます。
また、sshも立ちあげます。

今回はDockerfileを使ってイメージを構築します。
それぞれのコンテナのDockerfileとsupervisorの設定ファイルテンプレートは以下の様にホスト側に配置しておきます。
 $ tree .
.
└── templates
    ├── memorycraft
    │   └── conf
    │       ├── Dockerfile
    │       └── supervisor.conf
    └── tenkaippin
        └── conf
            ├── Dockerfile
            └── supervisor.conf



wordpressコンテナの設定


memorycraftコンテナでは、httpdとsshのサービスを立ちあげます。
また、wordpressをダウンロードし、RDSに接続するように設定ファイルを書き換えます。

./templates/memorycraft/conf/Dockerfile
# centosがベース
FROM centos
# 作成者
MAINTAINER memorycraft
# yumでいろいろインストール
RUN yum install sudo passwd openssh openssh-clients openssh-server httpd vim python-setuptools php php-devel php-mysql php-mbstring php-gd -y
# sshdの設定
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
RUN sed -ri 's/#UsePAM no/UsePAM no/g' /etc/ssh/sshd_config
# キーの生成
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
# sshでログインするユーザーを用意
RUN useradd memorycraft
RUN echo 'memorycraft:memorycraft_password' | chpasswd
RUN echo 'memorycraft ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/memorycraft
# wordpress
RUN curl http://ja.wordpress.org/wordpress-3.8.1-ja.tar.gz | tar -xz -C /var/www
RUN mv /var/www/html /var/www/html.org
RUN mv /var/www/wordpress /var/www/html
RUN cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php
RUN sed -ri 's/database_name_here/memorycraft/g' /var/www/html/wp-config.php
RUN sed -ri 's/username_here/memorycraft_user/g' /var/www/html/wp-config.php
RUN sed -ri 's/password_here/memorycraft_pass/g' /var/www/html/wp-config.php
RUN sed -ri 's/localhost/memorycraft.xxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com/g' /var/www/html/wp-config.php
# supervisordのインストール
RUN easy_install supervisor
# supervisordの設定
RUN echo_supervisord_conf > /etc/supervisord.conf
RUN echo '[include]' >> /etc/supervisord.conf
RUN echo 'files = supervisord/conf/*.conf' >> /etc/supervisord.conf
RUN mkdir -p /etc/supervisord/conf/
ADD supervisor.conf /etc/supervisord/conf/service.conf
# ポート開放
EXPOSE 22 80
# 起動時にsupervisordを実行
CMD ["/usr/bin/supervisord"]
view raw Dockerfile hosted with ❤ by GitHub

./templates/memorycraft/conf/supervisor.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
autostart=true
autorestart=true
[program:httpd]
command=/usr/sbin/httpd -c "ErrorLog /dev/stdout" -DFOREGROUND
redirect_stderr=true
view raw supervisor.conf hosted with ❤ by GitHub
コンテナをビルドします。
docker build --no-cache --rm -t memorycraft/wordpress templates/memorycraft/conf/

できたら、起動します。
docker run -p 80 -p 22 -d memorycraft/wordpress /usr/bin/supervisord



nginxコンテナの設定


tenkaippinコンテナでは、nginxとsshのサービスを立ちあげます。

./templates/tenkaippin/conf/Dockerfile
# centosがベース
FROM centos
# 作成者
MAINTAINER memorycraft
# yumでいろいろインストール
RUN rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
RUN yum install sudo passwd openssh openssh-clients openssh-server vim python-setuptools nginx -y
# sshdの設定
RUN sed -ri 's/UsePAM yes/#UsePAM yes/g' /etc/ssh/sshd_config
RUN sed -ri 's/#UsePAM no/UsePAM no/g' /etc/ssh/sshd_config
# キーの生成
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
# sshでログインするユーザーを用意
RUN useradd tenkaippin
RUN echo 'tenkaippin:tenkaippin_password' | chpasswd
RUN echo 'tenkaippin ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/tenkaippin
# supervisordのインストール
RUN easy_install supervisor
# supervisordの設定
RUN echo_supervisord_conf > /etc/supervisord.conf
RUN echo '[include]' >> /etc/supervisord.conf
RUN echo 'files = supervisord/conf/*.conf' >> /etc/supervisord.conf
RUN mkdir -p /etc/supervisord/conf/
ADD supervisor.conf /etc/supervisord/conf/service.conf
# ポート開放
EXPOSE 22 80
# 起動時にsupervisordを実行
CMD ["/usr/bin/supervisord"]
view raw Dockerfile hosted with ❤ by GitHub
./templates/tenkaippin/conf/supervisor.conf
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx -c /etc/nginx/nginx.conf
redirect_stderr=true
view raw supervisor.conf hosted with ❤ by GitHub
コンテナをビルドします。
docker build --no-cache --rm -t tenkaippin/nginx templates/tenkaippin/conf/

できたら、起動します。
docker run -p 80 -p 22 -d tenkaippin/nginx /usr/bin/supervisord



ホスト側nginxの設定


まず、プロキシ用にnginxをインストールします。
# rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
# yum install nginx -y

ここで一度コンテナの起動状況を調べてみます。
# docker ps -a
CONTAINER ID        IMAGE                          COMMAND                CREATED             STATUS              PORTS                                          NAMES
5499f267f670        tenkaippin/nginx:latest        /usr/bin/supervisord   About an hour ago   Up About an hour    0.0.0.0:49185->22/tcp, 0.0.0.0:49186->80/tcp   determined_shockley
9b361ac4aaef        memorycraft/wordpress:latest   /usr/bin/supervisord   5 hours ago         Up 5 hours          0.0.0.0:49173->22/tcp, 0.0.0.0:49174->80/tcp   loving_nobel

これで、
  • memorycraft:80 → 49174 
  • tenkaippin:80 → 49186 

というマッピングになっているのが分かります。(起動時にホスト側のIPを指定することも出来ます。)

次に、仮想サーバごとにプロキシ設定します。まずプロキシの基本設定です。

/etc/nginx/conf.d/proxy.conf
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
view raw proxy.conf hosted with ❤ by GitHub

次に、仮想サーバーで、memorycraft.cloudpack.jpとtenkaippin.cloudpack.jpの設定をします。
プロキシの転送先ポートとして、先ほど調べたポートを指定します。

/etc/nginx/conf.d/virtual.conf
server {
listen 80;
server_name memorycraft.cloudpack.jp;
location / {
proxy_pass http://127.0.0.1:49174;
}
}
server {
listen 80;
server_name tenkaippin.cloudpack.jp;
location / {
proxy_pass http://127.0.0.1:49186;
}
}
view raw virtual.conf hosted with ❤ by GitHub



DNSの設定


次にRoute53で、2つのサブドメインでこのサーバーに向けたAレコードを登録します。

これで作業は完了です。


確認


それでは、SSH確認してみます。


memorycraft.cloudpack.jp

まずは、ホストサーバでssh接続してみます。
# ssh memorycraft@127.0.0.1 -p 49173
The authenticity of host '[127.0.0.1]:49173 ([127.0.0.1]:49173)' can't be established.
RSA key fingerprint is a2:c9:81:fb:f5:84:57:ee:06:db:8b:18:7e:3c:2a:2e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49173' (RSA) to the list of known hosts.
memorycraft@127.0.0.1's password:
[memorycraft@9b361ac4aaef ~]$
[memorycraft@9b361ac4aaef ~]$
接続出来ました。

次に、ブラウザを確認します。

おお!接続出来ました!



tenkaippin.cloudpack.jp

ssh接続してみます。
# ssh tenkaippin@127.0.0.1 -p 49175
ssh: connect to host 127.0.0.1 port 49175: Connection refused
[root@ip-10-157-38-165 ~]# ssh tenkaippin@127.0.0.1 -p 49185
The authenticity of host '[127.0.0.1]:49185 ([127.0.0.1]:49185)' can't be established.
RSA key fingerprint is c3:87:55:75:0b:d4:ce:f3:5c:0a:e9:71:e1:0f:fd:ca.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[127.0.0.1]:49185' (RSA) to the list of known hosts.
tenkaippin@127.0.0.1's password:
[tenkaippin@5499f267f670 ~]$
[tenkaippin@5499f267f670 ~]$
接続出来ました。

ブラウザを見てみます。



ちゃんと表示されています!

このように、サーバー資源が限られていてユーザースペースを確実に分離したい場合などには、複数コンテナをつかうと便利かもしれません。

以上です。