仮想開発環境をCentOSからCoreOS+Docker+CentOSに移行する(1)

いままでMacOS/UbuntuでVagrantを利用してCentOSを仮想化して開発を行ってきましたが、仮想化されたCentOSは決してコンパクトではなく可搬性がとても低いと感じていました。本番環境と同じOSを利用するためにUbuntu上でCentOSを動かすのも無駄かなと。

そこで最近仮想化で話題のDockerを利用し、コンテナ型仮想環境へ移行することにしました。Dockerがもっと安定してきたら本番環境にも是非適用してみたいと考えています。

Homepage - Docker: the Linux container engine
https://www.docker.io/

この投稿は長くなりそうなので、何回かに分けて投稿していきます。本投稿ではCoreOSを仮想環境上に構築し、Dockerの動作を確認するするところまで説明していきます。

## UbuntuではネイティブでDockerが動くけどMacは？

DockerはもともとLXCを基板としてコンテナ型仮想化を実現していた（現在はLXCに依存しないドライバで動作）のでUbuntuに対応していますが、Macには当然LXC等の仮想化の機能はありません。

Macで一番簡単にDockerを利用した開発環境を構築するには、boot2dockerというTinyCoreLinuxを利用した仮想環境が近道なのですが、ホストマシンのフォルダを共有できないのがネックでした。

Boot2docker by boot2docker
http://boot2docker.io/

そこで、LinuxディストリビューションはCoreOSを使うことにしました。CoreOSはコアとなるOS機能がとても小さく、Dockerでのアプリ提供を前提とした作りになっています。Vagrantからも簡単に利用できるようVagrantfileも提供されています。NFSを利用したフォルダ共有も可能なので、ローカルのSublimeTextで編集したソースのデバッグも可能です。（実際にはデータ永続化のためのコンテナをアプリとは別で作成が必要ですが）

CoreOS is Linux for Massive Server Deployments
https://coreos.com/

## MacでCoreOSの仮想環境を作る

MacでCoreOSの仮想環境を利用するにはVagrantを利用するのが近道です。インストール方法はドキュメントどおりですが、Vagrantfileのconfig.vm.synced_folderの記述がコメントアウトされているのでそのコメントアウトを外すことでフォルダ共有が利用できるようになります。

Vagrant - CoreOS
https://coreos.com/docs/running-coreos/platforms/vagrant/

```rb:Vagrantfile
...
# Uncomment below to enable NFS for sharing the host machine into the coreos-vagrant VM.
config.vm.synced_folder ".", "/home/core/share", id: "core", :nfs => true, :mount_options => ['nolock,vers=3,udp']
...
```

vagrant up を行うと、MacからNFSのマウントを許可するためにログインユーザーのパスワードが求められますので入力する必要があります。

# Macのコマンドラインをインストール

CoreOSが起動すれば、もうDockerは利用できます。MacからDockerを操作するには、vagrant ssh を実行しSSHを経由して仮想環境上で行ってもいいのですが、直接MacからDockerを操作するためのクライアントをインストールします。

インストールするには以下が必要となりますので、入れていない場合は事前にインストールを行います。

* Xcode
    * [MacAppStore](https://itunes.apple.com/jp/app/xcode/id497799835?mt=12)からインストール
* [Homebrew](http://brew.sh/)
    * `ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"`

Dockerは2014年5月9日現在0.11がリリースされていますが、CoreOSに同梱されているDockerが0.10なのでそのまま実行すると「バージョンが違うよ」と言われ実行できません。なので、Homebrewでインストールする前にバージョンを指定してやる必要があります。

```sh:shell
$ brew versions docker
0.11.1   git checkout eefa235 Library/Formula/docker.rb
0.11.0   git checkout f4560d2 Library/Formula/docker.rb
0.10.0   git checkout c26c37d Library/Formula/docker.rb
0.9.1    git checkout 6bd6532 Library/Formula/docker.rb
0.9.0    git checkout a90b40e Library/Formula/docker.rb
0.8.1    git checkout 4ee0389 Library/Formula/docker.rb
0.8.0    git checkout 9880ace Library/Formula/docker.rb
$ cd /usr/local
$ git checkout c26c37d Library/Formula/docker.rb
$ brew install docker
```

これでインストールができましたが、dockerコマンドはディフォルトではローカルにインストールされたdockerを参照しにいってしまいますので、CoreOSのIPアドレスを接続先に指定します。

```sh:shell
$ docker info
2014/05/09 17:50:54 dial unix /var/run/docker.sock: no such file or directory
$ docker -H tcp://172.17.8.101:4243 info
Containers: 0
Images: 0
Storage Driver: btrfs
Execution Driver: native-0.1
Kernel Version: 3.14.1+
```

毎回指定するのも面倒なので、.bash_profile などに以下を追記するのもいいと思います。環境変数DOCKER_HOSTに接続先を指定しておけば都度指定する必要がなくなります。

```sh:shell
export DOCKER_HOST=tcp://172.17.8.101:4243
```

## Dockerが動くか確認

では簡単にDockerが動作するか確認します。利用するコンテナはCentOSでシェルを起動するだけの簡単なものです。

```sh:shell
$ docker run -i -t centos /bin/sh
sh-4.1# cat /etc/redhat-release
CentOS release 6.5 (Final)
```

動いていますね。exitするとコンテナは終了します。一度作成されたコンテナは docker start でコンテナIDを指定することで再度起動することができます。

```sh:shell
sh-4.1# exit
$ docker ps -a
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS                     PORTS                NAMES
454fc16a6edc        centos:centos6            /bin/sh                11 minutes ago      Exited (0) 3 seconds ago                        sad_torvalds
$ docker start -i 454fc16a6edc
sad_torvalds
sh-4.1#
```

## その2に続く

まずは簡単に導入前の準備をいろんな説明を端折って進めましたが、詳しい仕組みなどは公式ドキュメント等を参照しておくといいでしょう。次回はコンテナをビルドするDockerfileを作成するポイントについてまとめていきたいと思います。