今日から始めるDocker
2014/10/31
弊社で定期的にやっている社内ワークショップで、Dockerを試してみるというテーマを扱いました。筆者自身、このワークショップの為にDockerを使ってみたのが正直なところなのですが、思ったほど敷居は高くないという印象です。
本番環境でWebサーバやアプリケーションサーバとして運用する場合は事情は異なると思いますが、ちょっとした開発環境を構築するなどの用途であれば、気軽に使うこともできそうです。
今回は、Dockerの詳細には深入りせず、ワークショップでやった内容をそのまま紹介しようと思います。
目次
Dockerについて
Dockerはコンテナ型の仮想環境構築を実現するツールです。KVMなど仮想マシンによるハイパーバイザ型の仮想化と比較し、以下のような利点があると言われています。
- 仮想化によるオーバーヘッドが小さい
- イメージのサイズは小さく軽量
コンテナ型仮想化のメリットとして一般に強調されるのは、仮想化によるオーバーヘッドが小さいという点です。仮想マシンによる仮想化では、ホストOS上でゲストOSを実行する必要があるため、そのためのオーバーヘッドが生じます。一方、DockerやLXCなどコンテナによる仮想化の場合、こうしたオーバーヘッドはほとんど生じません。
また開発環境・検証環境として使用する観点では、イメージサイズの小ささもメリットとなります。筆者もよくVagrant(VirtualBox)で仮想環境を構築するのですが、boxのサイズが大きく、いつの間にかイメージでディスクの容量を逼迫していたといったこともありました。こうしたユースケースでも、コンテナ型の仮想化は有利だと言えるでしょう。
Dockerを使ってみる
以下では、CoreOSを使ったDockerの使い方について簡単に紹介していきます。
VagrantでのCoreOSの起動
今回は、Vagrant上のCoreOSを使ってDockerを使用しますので、まずはVagrantで仮想マシンを立ち上げます。
1 2 3 4 5 6 7 |
CoreOSのVagrantfileをclone $ git clone https://github.com/coreos/coreos-vagrant.git VagrantでCoreOSを立ち上げ $ cd coreos-vagrant $ vagrant up $ vagrant ssh |
CoreOSにログインしたら、Dockerが入っていることを確認します。
1 2 3 4 5 6 7 8 9 10 |
$ docker version Client version: 1.3.0 Client API version: 1.15 Go version (client): go1.3.2 Git commit (client): c78088f OS/Arch (client): linux/amd64 Server version: 1.3.0 Server API version: 1.15 Go version (server): go1.3.2 Git commit (server): c78088f |
以下のようにバージョン情報が表示されればDockerが利用できます。
イメージの取得とコンテナの起動
弊社では主にCentOSを使っているので、今回はCentOSを利用する方法を述べていきます。まずはCentOSのイメージを取得しましょう。docker pullというコマンドを実行すると、後述するDocker Hub上からDockerのイメージをダウンロードできます。
1 |
$ docker pull centos:latest |
イメージをpullした後でdocker imagesを実行してみます。docker imagesはローカルにあるDockerのイメージを一覧で確認できます。先ほどダウンロードしたCentOSのイメージが確認できるはずです。
1 2 3 |
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos latest 87e5b6b3ccc1 2 weeks ago 224 MB |
さて、ダウンロードしたイメージ上で何かしらコマンドを実行したい、ということがあると思います。ここでは試しにCentOS上で yum version を実行してみましょう。
1 2 3 4 5 |
$ docker run centos yum version Loaded plugins: fastestmirror Installed: 7/x86_64 133:4c70309dc8105033a94ef1f8abf39eec758a7008 Group-Installed: yum 14:d92850d928d628772a0a1d95c98e078545b0eea0 version |
下記のようにバージョンが表示されるので、確かにCentOS上でコマンドを実行できていることが確認できます。
コンテナからのイメージ保存
Dockerで生成したコンテナ上でコマンドが実行できたとはいえ、それだけではあまり役に立ちませんよね。
次はイメージから生成したコンテナに変更を加え、そのコンテナを保存してみましょう。下記のコマンドを実行すると、CentOS上のbashに入れます。
1 |
$ docker run -t -i centos /bin/bash |
立ち上げたコンテナのシェル上で、適当にコマンドを実行してみましょう。今回はPHPをインストールしてみます。
1 |
# yum install -y php |
インストールが完了したら、コンテナ上のシェルから出ます。コンテナ上で実行したコマンドが終了したことが確認できます。
docker ps -l で最新のコンテナに関する情報が確認できます。コンテナのIDを使い、コミットしてイメージ作成します。
1 2 3 |
$ docker ps -l CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8173f6edbe58 centos:latest "/usr/bin/bash" 3 minutes ago Exited (130) 45 seconds ago pensive_albattani |
docker commit でコンテナをコミットします。
1 |
$ docker commit 8173f6edbe58 yshnb/centos-test |
再び docker images によりイメージの一覧を確認すると、先ほどのコミットで新しいイメージができていることが確認できると思います。
1 2 3 4 |
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE yshnb/centos-test latest bd6fc140f3d8 5 seconds ago 293.7 MB centos latest 87e5b6b3ccc1 2 weeks ago 224 MB |
イメージが生成できていることを確認できたら、いったんコンテナは削除してしまいましょう。docker ps -a -q で存在するコンテナのIDのみをすべて出力することができます。
1 |
$ docker ps -a -q | xargs -n 1 docker rm |
改めてイメージからコンテナを立ち上げると、先ほどインストールしたPHPが入っていることを確認できます。
1 2 3 4 5 |
$ docker run -t -i yshnb/centos-test # php -v PHP 5.4.16 (cli) (built: Sep 30 2014 09:44:39) Copyright (c) 1997-2013 The PHP Group Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies |
このようにコンテナをコミットすることで、新しいイメージとして保存することが可能です。
イメージの取得からコンテナ作成までの流れ
ここまでの流れを簡単にまとめると、以下のようになります。
最初にイメージを取得したうえで、イメージからコンテナを立ち上げるには、 docker run を実行します。逆にコンテナからイメージを生成する場合は docker commit を使うという感覚です。
Dockerfileを使ったイメージの作成
前章では変更したコンテナの内容を docker commit することでイメージを作成しました。
先の方法でもイメージを作成することはできますが、完成されたイメージが共有できるのみで、そもそもそのイメージがどのような手順を経て構築されたのか?を知ることができません。
そこでこのイメージ生成のための手順を記述したものが、 Dockerfileです。Dockerfileでもベースとなるイメージを使用するのですが、ベースとなるイメージから、各種コマンドを実行したりポートを変更したうえで、新しいイメージを作成できます。
今回はDockerfileの例として、なんちゃってLAMP環境を作成してみましょう。
Apacheのインストール
1 2 3 |
$ mkdir -p lamp $ cd lamp $ touch Dockerfile |
Dockerfileへは以下の内容を記述します。
1 2 3 4 |
FROM centos:centos6 RUN yum install -y httpd EXPOSE 80 CMD apachectl -DFOREGROUND |
Dockerfileが記述できたら、ビルドしてイメージを生成してみましょう。
1 |
$ docker -t build yshnb/lamp-test . |
問題がなければ、Successfully … と表示されます。問題がなければ、立ち上げてみましょう。
1 |
$ docker run -d -p 80:80 yshnb/lamp-test |
docker run は立ち上げのコマンドです。-d はデタッチモードでの立ち上げ、また -p ではコンテナとDockerを実行しているOSの間でポートのマッピングを行うことができるオプションです。
正常に立ち上がっていれば、下記のURLでApacheが立ち上がっていることが確認できるはずです。
http://172.17.8.101/
PHPの実行環境構築
次はPHPをインストールしてみましょう。Dockerfileを下記のように変更します。
1 2 3 4 5 6 |
FROM centos:centos6 RUN yum install -y httpd RUN yum install -y php php-devel php-cli php-mysql php-mbstring ADD index.php /var/www/html/ EXPOSE 80 CMD apachectl -DFOREGROUND |
phpの動作確認ができるように、index.phpというファイルを作っておきます。
1 |
$ echo "<?php phpinfo();" > index.php |
先ほどと同じようにビルドし、実行してみましょう。既に実行中のコンテナがポートを使用していると、80番へのマッピングができずエラーになるので、実行前に既存のコンテナは停止させておきます。
1 2 3 |
$ docker -t build yshnb/lamp-test . $ docker stop $(docker ps) $ docker run -d -p 80:80 yshnb/lamp-test |
先ほどと同じURLへアクセスすると、phpinfo()によって出力されるPHPの情報が表示されるはずです。
MySQLのインストール
続いてLAMPのMである、MySQLをインストールしてみましょう。
先ほどのDockerfileは以下のように変更します。
1 2 3 4 5 6 7 8 9 10 |
FROM centos:centos6 RUN yum install -y httpd RUN yum install -y php php-devel php-cli php-mysql php-mbstring php-xml php-dom ADD index.php /var/www/html/ RUN yum install -y mysql-server RUN service mysqld start; RUN yum install -y wget RUN cd /var/www/html; wget -O index.php http://softlayer-sng.dl.sourceforge.net/project/adminer/Adminer/Adminer%204.1.0/adminer-4.1.0.php EXPOSE 80 CMD mysqld_safe & apachectl -DFOREGROUND |
先ほどと同じように、ビルドと実行をおこないます。
1 2 3 |
$ docker -t build yshnb/lamp-test . $ docker stop $(docker ps) $ docker run -d -p 80:80 yshnb/lamp-test |
再び先ほどのURLへアクセスすると、PhpMyAdminライクなGUIの管理画面であるAdminerのログイン画面が表示されるはずです。MySQLはセーフモードで立ち上げているので、 root というユーザ名さえ入力すればログインすることができます。
この例でもわかるように、docker runにより実行する際にはプロセスをフォアグラウンドで起動しておく必要があります。今回はApacheやMySQLを直接起動しましたが、実際にDockerを活用する場合、実行時に複数のプロセスを実行しておくことが必須になるはずです。プロセスをデーモン化するsupervisordなどをフォアグラウンドで起動することで、複数のプロセスを立ち上げることになると思います。
Docker Hubでのイメージ共有
Dockerには、Docker HubというDockerのイメージを共有できるプラットフォームがあります。全世界のDockerユーザーが公開しているイメージを探して使用することができるので、ちょっとした実行環境がほしいというときには、ここから目的のイメージを探して共有することができます。
前章までで使用したCentOSのイメージも、Docker Hubから取得してきたものです。
またイメージは利用するのみならず、アカウントを取得すれば、誰でも自由にイメージを公開することができます。ここでは簡単なイメージの利用方法を紹介します。
Docker Hubから共有されているイメージを探す
Docker Hub内にあるこちらのページからイメージを探すことができます。
探してきたイメージは、以下のコマンドでに利用できます。
1 |
$ docker pull <イメージ名> |
Docker Hubへイメージを公開する
Dockerのイメージ公開にはDocker Hubのアカウントが必要です。アカウントの作成はこちらから可能なので、興味のある方は作成してみてください。
作成後、Dockerの入っているマシンに戻り、以下のコマンドを入力します。
1 2 3 4 5 |
$ docker login Username: <ユーザ名> Password: <パスワード> Email: <メールアドレス> Login Succeeded |
ログインすると、以下のコマンドでDocker Hubにイメージを共有することができます。
1 |
$ docker push <ユーザ名>/<イメージ> |
GitHub/BitBucketと連携したイメージの自動ビルド
Dockerfileを管理するGithubやBitBucketのリポジトリと連携し、Dockerfileの更新にあわせてイメージをビルドすることができます。
これを利用すると、Dockerfileを編集するだけで編集後のイメージ配布ができるので、継続的に変更を加えていくようなイメージの配布にも便利です。
前章で作成したDockerfileも、Automated Buildを利用してこちらからダウンロードできるようにしています。
まとめ
Dockerは、少し利用するだけならたいして難しいものではありません。検証環境を作っては壊し…といったことをしたいケースなどでは、Vagrantで構築をし直すよりも、Dockerで構築するのが便利です。
また本番環境での具体的な運用事例が出てくれば、今後幅広い領域で使われる可能性をもった技術だと思います。2014年10月現在のところ、Dockerを本格的に使用した事例はまだ少ないと思いますが、まずは簡単なケースで使用してみるといいのではないでしょうか。