LoginSignup
9
13

More than 5 years have passed since last update.

Dockerを使ってWeb環境を作ってみる

Last updated at Posted at 2017-03-10

はじめに

事の発端は日本語ドメインを使ってみたい、と思ってしまったからというところなんですが、せっかくなのでDockerを使ってWebシステムを作って、知見を貯めていこうということが目的です。

構成

要件

  • 2つのDockerホストがあり、1つはサービスホスト、1つは運用ホストとして利用する。
  • サービス用ホストにはbind, nginxが稼働するコンテナが動作している。
  • 運用ホストではfluentdが動作し、ログを集約し、ローカルのファイルとして保存する。

概要構成図

abstract.jpg

設定

サーバ

初期設定

  • conohaのVPS(512MBのもの)を2台契約し、その上にUbuntu16.04を導入。
  • /etc/hosts, /etc/hostname, /etc/network/interfacesあたりを適当に設定。
  • もちろんapt-getでパッケージの更新とか、

Docker基本方針

インストール

ネットワーク

  • Dockerはコンテナ間のリンクやホスト間でL2接続など色々あるが、特にそういうことは考えずに図にあるIPレベルでの通信を行います。
  • 詳細まで書くと次のようなイメージになると思います。

network.jpg

  • docker0配下のIPはデフォルトで172.17.0.0/24から自動で払い出されますが、NATされ、実IPで通信します。今回の場合はグローバルIPで通信します。
  • グローバルIPで通信するため、ufwを利用して余計な通信は落とすように制御します。

ロギング

  • コンテナ内のアプリケーションから直接fluentdに吐かせてもいいものの、dockerのfluentd driverを利用することで、コンテナが標準入力に出力したデータを指定したfluentdに送ることが出来ます。
  • コンテナ起動時にオプションとして、下記を渡します。
  • tagはNameでもいいのですが、コンテナ再起動時、本来は別のコンテナとして扱うべきだと思うのでIDという扱いにしました。
オプション名 説明
--log-driver fluentd ログドライバーとして、fluentdを指定
--log-opt fluentd-address=XX.XX.XX.YY:24224 fluentdサーバを指定
--log-opt tag=docker.{{.FullID}} ログのtagを指定

タイムゾーン

  • Dockerコンテナは標準でUTCになっているので、JSTに直します。
  • 方法は複数あるみたいですが、ここでは下記オプションをコンテナ起動時に引き渡すことで実現します。
オプション名 説明
-v /etc/localtime:/etc/localtime:ro dockerホストのtimezoneファイルを、コンテナ内にマウントさせます。

fluentd

基本

  • 下記コンテナイメージを使います。
項目名 説明
利用するコンテナイメージ https://github.com/fluent/fluentd-docker-image

fluent.conf

  • confは以下のように記載し保存しておきます。
  • 保存先は$HOME/fluentdとかが良いと思いますが、他のコンテナとまぜこぜになってわかりにくくならなければどこでも良いと思います。
<source>
  type forward
  port 24224
  bind 0.0.0.0
</source>
<match docker.**>
  type file
  path /fluentd/logs/all.log
  time_slice_format %Y%m%d
  time_format %Y%m%dT%H%M%S%z
</match>
  • ちゃんと通信ができているか確認したい場合はファイルに書き出すよりstdoutに書き出すようにして確認したほうがわかりやすいかもしれません。
  • その場合は以下のようなconfを代わりに投入してください。
<source>
  type forward
  port 24224
  bind 0.0.0.0
</source>
<match docker.**>
  type stdout
</match>

そのうえで

$ docker logs fluentd-container-id

コンテナの起動

  • まずはじめにログを蓄えるためのfluentdコンテナを起動するためのパラメータを考えます。
  • 重要なことはログはコンテナ内ではなく、ローカルボリューム側に保存するということです。
オプション名 説明
-p 24224:24224 ホスト側の24224番ポートに対して、コンテナの24224番ポートをマッピングします。
-v $(pwd)/log:/fluentd/logs コンテナ内でログは/fluentd/logsに吐き出されますが、カレントディレクトリ直下のlogディレクトリをマウントする設定とします。※
-v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf カレントディレクトリ直下にあるconfファイルをデフォルトのパスにあるconfファイルにマウントします。
--name fluentd コンテナ名をfluentdとします。
  • 起動コマンド
$ docker run -d -p 24224:24224 -v $(pwd)/log:/fluentd/logs -v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf -v /etc/localtime:/etc/localtime:ro --name fluentd fluent/fluentd
  • 私の環境の場合、ホスト側のlogディレクトリはパーミッションが777でないとコンテナ起動時にエラーが出て正しく動作しませんでした。
  • 正確な原因、解決方法は今のところ不明ですが、もしis not writable的なエラーが出た場合は試してみてください。

ufwの設定

  • internetからフルオープンだと問題があると思うので下記で絞っておきます。
$ ufw allow from XX.XX.XX.XX to any port 24224
  • もちろん先に、SSHを開ける設定など入れてからenableした方がいいと思います。

bindの設定

基本

  • 下記コンテナイメージを使います。
項目名 説明
利用するコンテナイメージ https://github.com/sameersbn/docker-bind

コンテナの起動

  • このコンテナイメージは設定変更用のmuninがついてくるので、特に設定ファイルなどは用意しなくても大丈夫ですが、コンテナ再起動時などに問題が起こらないように設定ファイル類はホスト側のファイルシステムに保存されるようにします。
オプション名 説明
-p 53:53/tcp ホスト側の53番ポートに対して、コンテナの53番ポートをマッピングします。(TCP)
-p 53:53/udp ホスト側の53番ポートに対して、コンテナの53番ポートをマッピングします。(UDP)
-v $(pwd)/bind:/data コンテナ内のデータは/data内に保存されます。その領域にホスト側の./bindをマウントすることで、コンフィグを始めとしたデータ類をホスト内に保存します。
--name bind コンテナ名はbindとします。
  • 起動コマンド
docker run --name bind -d -v /etc/localtime:/etc/localtime:ro -p 53:53/tcp -p 53:53/udp -v /opt/docker/data/bind:/data --log-driver=fluentd --log-opt=fluentd-address=XX.XX.XX.YY:24224 --log-opt=tag=docker.{{.FullID}}   sameersbn/bind:9.9.5-20170129

起動後の設定

  • コンテナ起動後、munin経由で設定変更を行います。
  • muninはデフォルトで10000ポートでlistenしていますが、パスワード認証だけは過去の色々なトラウマからsshトンネリングでアクセスすることとします。
  • まずは、bindコンテナのローカルIPを調べます。
$ docker inspect -f "{{ .NetworkSettings.Networks.bridge.IPAddress}}" bind-container-id
  • 今回の場合172.17.0.x:10000
$ ssh -i 公開鍵のパス username@XX.XX.XX.XX -L 8080:172.17.0.x:10000

nginxの設定

基本

  • 下記コンテナイメージを使います。
項目名 説明
利用するコンテナイメージ https://hub.docker.com/_/nginx/

コンテナの起動

  • 今回は難しいことはせず、とりあえず起動してアクセスできることを確認します。
オプション名 説明
-p 80:80 ホスト側の80番ポートに対して、コンテナの80番ポートをマッピングします。
-v $(pwd)/nginx:/usr/share/nginx/html:ro コンテンツは$(pwd)/nginxに保存し、その領域をコンテナの公開領域にリードオンリーでマウントします。
--name nginx コンテナ名はnginxとします。
  • 起動コマンド
$ docker run --name nginx -v /etc/localtime:/etc/localtime:ro -p 80:80 -v $(pwd)/nginx:/usr/share/nginx/html:ro --log-driver=fluentd --log-opt=fluentd-address=XX.XX.XX.YY:24224 --log-opt=tag=docker.{{.FullID}} -d nginx

まとめ

  • これでWebサーバが最低限動く程度の構成はできたかと思います。
  • ただ、パッと思いつくところでHTTPS対応であったり、性能監視であったりはまだ未着手なので、そのあたりもうまいやり方がないかは近々調査してみようと思います。

  • Dockerってあまりピンときていないところがじつはあったのですが、言ってしまえばアプリケーションをデプロイする、という発想をするとしっくり来るということを先輩に教わりスッキリしました。

  • Docker = VMという発想が強いと中々扱いにくいものに見えますが、アプリケーションという単位で考えると結構扱いやすくなる気がしました。

次の目標

9
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
13