« サブディレクトリ型の複数サイトでtwitter cardを設定した | メイン | AmazonWebServicesアカウントの強制停止から復活 »

2014年9月30日 (火)

DockerでLAMPサーバをつくる話

こんにちは。最近業務マシンがMac Book Airになって気を良くしているエンジニアの佐藤です。

世間ではDockerが注目を集めていますので、今回はこの話題をお届けしたいと思います。

Dockerとは

ものすごく簡単に言うと、従来(ハイパーバイザー型)より少ないリソース(CPU、メモリ、ストレージ)で同等のサービスをホストする仮想化技術です。 Linuxカーネルのコンテナと呼ばれる機能により、ある「おまじない」をして開始したプロセスはそれぞれ独立した以下の一式を受け取ります。

  • ファイルシステムルート
  • rootユーザ(およびその他のカーネルサービスID空間)
  • ネットワーク

したがってこのプロセス(およびその子プロセス)は、あたかも独立したホスト(「コンテナ」と呼ばれます)であるようにふるまうことができるのです。プロセスのカーネルメモリ空間は全コンテナで共有使用するので、CPUとメモリが節約でき、カーネルの初期化をスキップして高速起動できます。

Dockerの問題点

ただしこの仕組みが成立するためには、コンテナ内のプロセスが、Dockerの用意した上記の仮想リソースの範囲で「おとなしく」動作することが必要です。Dockerを飛び越えてのリソースアクセスはご法度となり、失敗するか、コンテナの動作障害につながる恐れがあります。

LAMPのすべてをコンテナに収容できるか

それではLinuxサーバの定番用途の一つであるLAMPサーバ(Liux Apache MySQL PHP)は、コンテナ上で動作するのでしょうか?もしこれが可能なら、サーバのポータビリティが飛躍的に向上し、便利です。そこで今回はこのテーマに挑戦してみることにしました。

LAMPサーバ「コンテナ」の作成

結果からお伝えすると、以下の手順でLAMPサーバ「コンテナ」が作成できました。

  1. Dockerのインストール
  2. CentOS 6イメージをDocker hubからpull
  3. /bin/bashでスタート
  4. あとは普通にセットアップ
  5. 最後に起動スクリプトを書く
  6. イメージを保存して、docker run

1. Dockerのインストールと開始

今どきのLinuxディストリビューションでは、コマンド一発です。筆者のUbuntu 14.04では以下のようにしました。

# apt-get install docker.io
# service docker.io start

2. CentOS 6イメージをDocker hubからpull

これもコマンド一発です。

# docker pull centos

3. /bin/bashでスタート

次に「bash」コマンドを指定してコンテナをスタートします。この時「-i -t」オプションを指定し、コンテナ内で起動したbashの標準入力と標準出力を、今まさにdockerコマンドを打っているターミナルに接続します。

# docker images | grep centos6  <-- CentOS 6 のイメージIDを確認
centos              centos6             68eb857ffb51        2 weeks ago         212.7 MB 
# docker run -i -t 68eb /bin/bash <-- bashを指定してコンテナを起動。イメージIDは前方一致で指定できる。
bash-4.1# whoami <-- コンテナ内のbashのプロンプト
root

4. あとは普通にセットアップ

ここまできたら後はapt-getとかyumとかを用いて通常のサーバと同じように設定していきます。

# apt-get install httpd openssh-server mysql-server php
...

5. 最後に起動スクリプトを書く

ここがちょっと難しい部分です。 Dockerは「docker run」で開始されたプロセスに特別なリソースを割り当てる仕掛けですので、このプロセスが終了すると、コンテナ全体が終了となります。これではサーバとして常駐するサービスとして使えません。このため「docker run」で開始するプロセスは以下の役割を担う必要があります。

  • 開始したら他の常駐プロセス(httpdなど)を起動し、シグナル(docker killコマンドで送信)を受信するまで終了待機する。
  • シグナルを受信したら、常駐プロセスを終了し、自身も終了する。

方法はいろいろあるのですが、一番簡単だと思うのは以下のようなシェルスクリプトです。

#! /bin/bash
service rsyslog start
service sshd    start
service mysqld  start
service httpd   start

term() {
     service httpd   stop
     service mysqld  stop
     service sshd    stop
     service rsyslog stop 
}

trap "term; exit" SIGHUP SIGINT SIGTERM

while true; do
     sleep 1
done 

このスクリプトを/root/start.shなどのパスに保存し、次回からdocker runするときはこのスクリプトを実行するようにします。

6.イメージを保存して、docker run

まずセットアップ作業が終わったコンテナを終了します

bash-4.1# exit  <-- コンテナを終了
exit

この段階でコンテナは、「イメージ+変更差分」の形で保存されています。

# docker ps -l <-- コンテナのIDを確認
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES 
ad8596fad31e        centos:centos6      "/bin/bash"         51 minutes ago      Exited (1) 3 seconds ago

docker runするためにはイメージにする必要がありますので、「イメージ+変更差分」を一本のイメージにします。

# docker commit ad85 server01 <-- イメージを作成

いよいよ起動です。このときコンテナホスト(dockerを実行しているマシン)の80番ポートを、コンテナの80番ポートに接続します。(この設定により、外部からコンテナにHTTPリクエスを送信できるようになります。)

# docker run –d –p 80:80 mybasket01 /root/start.sh
5cf98b694ceb5d62f7fa01d4ff5fc7130eb98ab4ea5c04a3df37c090c7b4595f

この状態でコンテナホストの80番ポートにアクセスすると、コンテナサーバからのレスポンスが返るはずです。

7. コンテナ終了は docker kill

コンテナを終了するときは、シグナルを送信して起動スクリプトの終了処理を実行します。ここではTERMシグナルを送信しています。

# docker kill -s="SIGTERM" 5cf9

いくつかのハマりポイント

Dockerコンテナでサーバをつくろうとした時にいくつかハマったポイントがあったので、ご紹介します。

1. CentOS 7 コンテナが使えない

Cent OS 7では常駐プロセス制御にsystemdが使用されていますが、Dockerコンテナ内ではsystemdが動きません。またApacheのインストールも失敗します。残念ですがリビジョンアップで改善されることを期待です。

2. SSHサーバにログインできない

SSHサーバの初期処理が実行されていない可能性がありますので、コンテナ内でSSHサーバを一旦起動して初期処理を実行します。

bash-4.1# service sshd start

また、既定のPAM(Praggable Authentication Module、Linuxの認証拡張モジュール)設定がDockerとぶつかる場合もあります。/etc/ssh/sshd_configを編集し、「UsePAM no」に設定します。

3. ファイル共有が使えない

NFSサーバはカーネル機能ですので、Dockerでは使えません。更に、Sambaも何故か動作しませんでした(調査中です…)。ファイル共有については、現在WebDAV + davfsでやっています。

まとめ

Dockerはまだ新しい技術で、心配な部分が多いというのが率直な印象です。しかしコンテナ仮想化のリソース効率の高さはまちがいなく、ポータビリティの恩恵も大きいと感じています。主要企業は一斉にサポートを表明しており、今後広まっていくのではないでしょうか。

コメント

コメントを投稿

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上での
Webアプリケーション開発
エンジニア、マネージャーを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、セールスフォースパートナーです。
また、heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。

2021年3月

  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
ブログ powered by TypePad