オンプレの環境にdockerを使ってwebサーバを構築した話



## 概要

やりたいことは１つの物理サーバ(CentOS)に２つの仮想環境を作りたいです。
作った仮想環境は２つともWebサーバとして使いたいです。
作った仮想環境に手元のMacから直接SSHしたいです。

※ https://hub.docker.com/u/yanap/
  のプライベートリポジトリにpushしたのでが2014-11-14なので、ちょっと古いかもしれないです。

## 環境

### 親サーバ

CentOS6.5

### 作る予定のdockerコンテナ

親に合わせてCentOS6.5
apache,php,sshdとかがデフォルトで入ってる感じです。

## 親サーバにdockerをインストール

### epelを有効にする

```
sudo rpm -ivh http://ftp.jaist.ac.jp/pub/Linux/Fedora/epel/6/i386/epel-release-6-8.noarch.rpm
```

### docker install

インストールして、起動して
centosの最新版 centos7のdockerコンテナを起動させて
bashで中に入るとこまで

```
yum --enablerepo=epel install docker-io -y

sudo service docker start

sudo chkconfig docker on

sudo docker pull centos:latest

sudo docker images centos

sudo docker run -i -t centos /bin/bash
```

## 構築手順

### 1. sshの鍵を作る

親のサーバにsshの鍵を作ります

```
ssh-keygen -t rsa -C "root@server01"
```

### 2. centos6.5のイメージを作る

登録されているデフォルトイメージ(centpos:latest)はcentos7なので

http://qiita.com/hnakamur/items/8e3136488fcfe763802c

上記のQiitaの記事を参考にCentOS6.5のイメージを作成する
上記の記事に書いてあるshellscriptを実行して
dockerにimageをimportするだけです。

```
./cent65.sh
cat centos-65.tar.xz | sudo docker import - centos65
```

### 3. Dockerfileを作る

作りたい構成のDockerfileを書きます。

```
FROM hnakamur/centos:6.5
MAINTAINER yanap

ENV ROOT_USER_PASSWORD root-password
ENV USER_NAME yanap
ENV USER_PASSWORD yanap-passwrod
ENV LDAP_SEREVER 192.168.0.1
ENV LDAP_BASE_DN dc=yanap,dc=com

# yumで必要なパッケージをインストール
RUN yum update -y
RUN yum install wget -y
RUN wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm ;\
rpm -ivh epel-release-6-8.noarch.rpm
RUN yum --enablerepo=epel install git vim tree htop lsof -y
# ssh
RUN yum --enablerepo=epel install sudo passwd openssh openssh-clients openssh-server python-setuptools -y
# apache
RUN yum --enablerepo=epel install httpd mod_ssl php -y
# netns対応してるiprouteをインストール
RUN yum install -y http://rdo.fedorapeople.org/openstack/openstack-havana/rdo-release-havana.rpm
RUN yum update --enablerepo=openstack-havana -y iproute
# ldap
RUN yum install authconfig nss-pam-ldapd nfs-utils -y
RUN yum clean all
RUN easy_install supervisor

# timezone変更
RUN cp -p /usr/share/zoneinfo/Japan /etc/localtime

# sshdの設定
RUN sed -ri "s/^UsePAM yes/#UsePAM yes/" /etc/ssh/sshd_config
RUN sed -ri "s/^#UsePAM no/UsePAM no/" /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

RUN mkdir -m 700 /root/.ssh
ADD Addfiles/authorized_keys /root/.ssh/authorized_keys
RUN chmod 600 /root/.ssh/authorized_keys && chown root:root /root/.ssh/authorized_keys
RUN echo "root:$ROOT_USER_PASSWORD" | chpasswd

RUN useradd -g wheel -G wheel $USER_NAME
RUN echo "$USER_NAME:$USER_PASSWORD" | chpasswd
RUN echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
ADD Addfiles/su /etc/pam.d/su

# apacheの設定
RUN chmod 755 /var/log/httpd
RUN touch /etc/sysconfig/network
ADD Addfiles/index.html /var/www/html/
#RUN sed -ri "s/^ServerTokens OS/ServerTokens ProductOnly/" /etc/httpd/conf/httpd.conf
#RUN sed -ri "s%^LoadModule autoindex_module modules/mod_autoindex.so%#LoadModule autoindex_module modules/mod_autoindex.so%" /etc/httpd/conf/httpd.conf
#RUN sed -ri "s%^LoadModule speling_module modules/mod_speling.so%#LoadModule speling_module modules/mod_speling.so%" /etc/httpd/conf/httpd.conf
#ADD Addfiles/server.crt /etc/httpd/
#ADD Addfiles/server.key /etc/httpd/
#RUN sed -ri "s#SSLCertificateFile /etc/pki/tls/certs/localhost.crt#SSLCertificateFile /etc/httpd/server.crt#" /etc/httpd/conf.d/ssl.conf
#RUN sed -ri "s#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key#SSLCertificateFile /etc/httpd/server.key#" /etc/httpd/conf.d/ssl.conf

# php
RUN sed -ri "s/expose_php = On/; expose_php = On/" /etc/php.ini
RUN yum install php-pear php-devel httpd-devel php-pdo php-pgsql php-mbstring php-gd php-zlib-devel libjpeg-devel -y
RUN yum install php-xml php-xmlrpc libxml2-devel -y
RUN yum install ImageMagick-devel -y
RUN pear channel-update pear.php.net
RUN pear install -a Mail
RUN pear install -a Mail_Mime
RUN pear install --onlyreqdeps -f mail_mimedecode
RUN pear install -a Log
RUN pear install Image_Color2-alpha
RUN pear install Image_Graph-alpha
RUN pear install Auth

# 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 Addfiles/supervisor.conf /etc/supervisord/conf/service.conf

# ポート開放
EXPOSE 22 80 443

# 起動時にsupervisordを実行
CMD ["/usr/bin/supervisord"]

```

centos6.5
ssh,apache,php
supervisordで１つのコンテナで複数プロセス動かしてます。
FreeBSDのjail的な使い方です。
こんな感じです。

Addfiles以下は

```
ree Addfiles
Addfiles
├── authorized_keys
├── httpd.conf
├── index.html
├── mime.types
├── ntp.conf
├── server.crt
├── server.csr
├── server.key
├── ssl.conf
├── su
└── supervisor.conf
```

こうなってます。

### 仮想環境を作る

Dockerfileができたところで、Dockerfileをもとにイメージを作って
作ったイメージをdockerコンテナとして起動させます。

#### Dockerfileからイメージをビルドするコマンド

--no-cache=trueはキャッシュしないオプション
-t はタグ名をつけるオプション
--rm-falseオプションをつけるとはDockerfieでRUNしたあとのプロセスを消さない

```
docker build --no-cache=true -t server01/yanap_web .
```

#### imageが作成されたか確認

```
docker images
```

#### コンテナ起動

例えば、10080:80という書き方をすると
外からアクセスするときは10080番ポートでコンテナ内部では80ポート使ってますよという風に
ポートフォーワリングを指定できる

```
docker run --name web1 -p 10080:80 -p 2222:22 -d server01/web1
```

#### 起動してるコンテナのプロセス確認

```
docker ps -a
```

#### ssh できるか確認

親サーバから構築したdockerコンテナにsshする

※そもそも、親サーバからdockerコンテナに向かってSSHするのは非推奨なので
1.3以上の場合はdocker execしましょう。

```
ssh -p 2222 -i /root/.ssh/id_rsa root@localhost
```

#### httpdが起動しているか確認

```
curl http://localhost:10080/
```

#### もう一個立ち上げる

```
docker run --name web1 -p 20080:80 -p 3333:22 -d server01/web2
```

### 5. IPアドレスを割り当てる

```
192.168.0.10 // 親
192.168.0.11 // web1
192.168.0.12 // web2
```

ネットワークの設定は力技ですが、１つのbrigeに対して、一つの仮想環境を割り当ててます。
色々、試したんですが、それしか実現できなかった。。。

#### web1

NICにbrigeを追加して
追加したbrigeにdockerコンテナのIPを割り当てて
NICを有効にします。

```
brctl addbr br1
ip addr add 192.168.0.11 dev br1
ip a show dev br1
ip l set br1 up
```

#### web2

web1と同じです。

```
brctl addbr br1
ip addr add 192.168.0.12 dev br2
ip a show dev br2
ip l set br2 up
```

これで、手元のMacから各dockerコンテナにsshできるようになりました。(ネットワーク設定上はね)

### 6. IPを指定してdockerコンテナを立ち上げる

5と前後するかもしれないですが、dockerコンテナを立ち上げます

```
docker run --name web1 -t -i -p 192.168.0.11:80:80 -p 192.168.0.11:22:22 -d yanap_web

docker run --name web2 -t -i -p 192.168.0.12:80:80 -p 192.168.0.12:22:22 -d yanap_web
```

#### ssh

ちなみに、構築したときはdocker1.2だったので親サーバからコンテナにsshするのに

```
WEB1IP=$(docker inspect --format='{{.NetworkSettings.IPAddress}}' web1) && ssh $WEB1IP
```

こういうことしてました。