Docker
boot2docker
fig

Docker1.3版 boot2docker+fig入門

More than 3 years have passed since last update.

Docker1.3がリリースされましたね!

それに合わせて、周辺ツールがアップデートされていて

とても便利になったと感じたので紹介してみます。


Docker/boot2docker

Virtual Box Guest Additionsをサポートしたことにより、

MacOS上のファイルとコンテナ内の同期が簡単になりました。

またDockerがexecコマンドをサポートしたことにより

sshインストールなしでコンテナ内でコマンド実行することが出来ます。

でかい。


fig

figは複数のDockerコンテナをお手軽に管理するためのツールです。

シンプルなyamlファイルを用意するだけでコンテナ操作を行うことが出来ます。

figもDockerのリリースと合わせてアップデートされているようです。



以前と何が変わったのか?

Docker1.2以前ではboot2docker+figを利用しようとすると一手間必要になってしまっていましたが、

1.3からはローカルにfig設定を置くだけで利用することが可能になりました。

つまりローカルMac上からシームレスにコンテナ操作や同期を行うことが出来ます。

実はその辺りを工夫するため、Vagrant+DockerProviderを利用して

ローカル環境とコンテナを同期するための構成を考えていたりしたのですが

このエントリ 参照)

こんな面倒なことをしなくてもとても簡単に同じことを実現できるということです。

※というか、figチュートリアルがほぼこの要件を満たしてた。。今までの苦労は一体。。。



事前準備


boot2dockerを1.3にupdate

既にインストール済みの場合は以下の手順でバージョンアップ+VM更新しておきましょう

boot2docker upgrade

boot2docker delete
boot2docker download
boot2docker init
# 確認
boot2docker version



figのチュートリアルを実行してみる

補足を入れつつ、公式サイト とほぼ同じ手順を踏んでみます。

適当にディレクトリを掘って、以下のファイルを置いてみてください。

(他にもRails/Django/Wordpressのサンプルもあるようです)


pythonアプリ作成

アクセスするとRedisにカウントアップして表示するだけのスクリプトです。


app.py


# -*- coding: utf-8 -*-
from flask import Flask
from redis import Redis
import os
app = Flask(__name__)

# ホスト=redisというのは、figが設定している/etc/hostsを参照しています。後ほど補足
# もちろん、Docker標準の環境変数を利用してもOKです
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
redis.incr('hits')
return 'Hello World! I have been seen %s times.' % redis.get('hits')

if __name__ == "__main__":
# これはflaskの設定Tipsですが、他のコンテナから見えるようにhost="0.0.0.0"を設定する必要があります
app.run(host="0.0.0.0", debug=True)



requirements.txt

flask

redis


Dockerfile作成

python:2.7イメージをダウンロードし、

Mac上のカレントディレクトリ以下をコンテナの/codeに追加し、

pipで必要なpythonモジュールをインストールしています。


Dockerfile

FROM python:2.7

ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt


figファイル作成


fig.yml

web:            # サービス名です。この名前でコンテナにアクセスできます

build: . # ./Dockerfileを用いビルドする
command: python app.py # ビルド後のコンテナで実行するコマンド
ports:
- "5000:5000" # ポートフォワード設定。フォーマットは <ホスト側ポート>:<コンテナ側ポート>
volumes:
- .:/code # ボリューム設定。ローカル「.」を コンテナ「/code」に同期
links:
- redis:redis # リンク設定。フォーマットは <サービス名>:<エイリアス名>
redis:
image: redis # DockerRegistry上のredisイメージを用いコンテナ生成



実行してみる

まずはboot2dockerを起動し、

次にfigでコンテナを起動して

アプリケーションが実行されているか確認してみます。


boot2docker


boot2docker:VM起動

ホストとなるboot2dockerを起動します。これは今までと変わらず。

# VM起動

boot2docker up
# Docker関連の環境変数設定
# コンソールに表示された環境変数をコピペでも良いですが、
# 以下のコマンドでも良いらしい
$(boot2docker shellinit)


fig

figコマンドを実行します。

ほとんどコマンドは「サービス名」を引数に取ることが出来ます。

サービス名を省略した場合は「全サービス」を対象にコマンド実行します。


fig:コンテナ起動

figのカレントディレクトリでfigコマンドを実行します。

(デーモン起動する時は -d オプションを追記)

(既にイメージ作成済みの場合は fig start でOK)

fig up

本当の初回だけはイメージのダウンロードなどが発生しますが、

2回目以後は一瞬でコンテナ起動するようになります。


fig:サンプルアプリケーションにアクセスしてみる

ホストVMのipを確認後、curlでアクセスしてみましょう。


# IP確認。/etc/hostsなどに登録しておくと良いですね
boot2docker ip
# アプリにアクセス
curl 192.168.59.103:5000
(Hello World! I have been seen blah 1 times.)


fig:コンテナ(サービス)の確認

psコマンドで確認できます。サービス名などが付いているので非常に見やすいですね。

-q オプションを指定するとコンテナIDが表示されます。

fig ps 

スクリーンショット 2014-10-19 1.53.05.png


fig:停止

コンテナを停止します。

fig stop


fig:ログ表示

コンテナ内のログもfigから取得できます。

以下はwebサービスのlogを取得します。


# フォーマット
fig logs サービス名
# redisサービスのログ表示
fig logs redis


fig:その他にも

いくつかコマンドがありますので、fig コマンドを叩いて確認してみてください。



figについての補足情報


サービス名を/etc/hostsに反映してくれる

そのままなのですが、サービス名を設定すると/etc/hostsに反映してくれるようです。

軽く確認してみたところ、以下のような感じで反映するようです。

web:

links:
- redis:redis6379
redis:
...


web_etc_hosts

...

x.x.x.x figtest_web_1
x.x.x.x redis6379
x.x.x.x redis_1
x.x.x.x web
x.x.x.x web_1
x.x.x.x figtest_redis_1
...


redis_etc_hosts

...

x.x.x.x figtest_redis_1
x.x.x.x redis
x.x.x.x redis_1
...

「自分のホスト情報」+「linksで設定したホスト情報」が設定されるようですね。

fig run <サービス名> cat /etc/hosts で確認してみましょう。



まとめ

Docker1.3に対応したboot2dockerと、figの機能を紹介してみました。

figを使うとシンプルにコンテナ管理が出来ますし、

なによりコンテナIDではなくサービス名で使えるのがとても便利です。

さらに、ローカル環境の構築でいままで悩んでいたことがだいぶ解消されていて

ライフチェンジングになりそうな感じです。


まだまだ「触ってみた」程度なので、自分の環境でもどしどし使ってみて

開発フローに組み込んで行きたいと思います!!


おまけその1

Macをリスタートした後のDocker起動時間の肌感、

ローカルファイルとコンテナ内ファイルが同期される様子、

などをキャプチャしてみました。

figの起動が一瞬で終わっててコンテナ最高〜♪

record.gif


おまけその2

fig.yml一枚書くだけ(!)でconsulクラスタ構築するデモです。

figコンフィグはこちら。

Mac上から一台のサーバに向けてAPIを実行したかったので

consulserverのみ別ポート(+10000)でポートフォワードしています。


fig.yml

consulserver:

image: progrium/consul
command: -server -bootstrap
ports:
- "18300:8300"
- "18400:8400"
- "18500:8500"
consulclientA:
image: progrium/consul
command: -join consulserver
links:
- consulserver
consulclientB:
image: progrium/consul
command: -join consulserver
links:
- consulserver
consulclientC:
image: progrium/consul
command: -join consulserver
links:
- consulserver

デモはこちら。

record_demo_consul.gif

やばい。