読者です 読者をやめる 読者になる 読者になる

アプリケーションの仮想化『Docker』を試してみた

Docker

f:id:sunrise683:20150103215532j:plain

photo credit: Ulf Bodin via photopin cc 

せっかくのお正月休みを利用して、インフラ系技術をhomeworkとしてやっておきたいという気持ちが強くなり、『Docker』を実装してみました。docker(ドッカー)を実装するにあたり、はじめにdockerとは何かを調べました。
Docker」とは、アプリケーションを実行するための仮想環境を管理するソフトウェアツールの一種。仮想環境にOSを含まない「コンテナーアーキテクチャを採用している。アプリケーション実行環境の展開や複製、作り直しが素早くできる他、構成管理を自動化しやすいといった特長がある。
どうやらdockerというやつは、従来からあるVMware等の仮想化技術と異なり、ミドルウェア以上のアプリケーションを仮想化、管理するソフトウェアのようです。そして、この管理単位に「Container」という単位を使うらしい。この記事をもう少し読み進めていきます。

仮想化したOS上でコンテナー内のユーザーアプリケーション(ライブラリやミドルウェアを含む)を実行するので、OSレベルの仮想化とも呼ばれる。

仮想マシンと違い、OSは含んでいないのだが、アプリケーションから見ると全く異なったOSで稼働しているように見えるので、OSの仮想化ということになるらしい。ところでdockerについて調べていると、「Boot2Dcocker」という補助ツールがあるらしい。これはdockerはLinuxカーネルに依存することから、Linux OSにしかインストールできない。しかし、この補助ツールとVirtual Boxを使うことでWindows環境でもdockerを使うことができるというツールらしい。これがもう少し軽量になり、Virtual Boxも不要になったらWindows環境にLinux環境を共存させることが出来、とても便利ですね。。
 
実際にdockerをVirtual Box上のCentOS6.6 64bit(以下、"rishiridake"というホスト名)にインストールしてみます。yumによるインストール手順が最も簡単だと思いますが、できればインターネットとつながっていない環境でも実装できるよう、まずはbinaryからインストールする方法を試して見たいと思います。ここからは公式のマニュアル(Binaries - Docker Documentation)を参考にしていきます。
[root@rishiridake ~]#  chmod +x docker
あとはdockerをデーモンとしてスタートするようです。
[root@rishiridake ~]#  ./docker -d &
[1] 3102
[root@rishiridake ~]# INFO[0000] +job serveapi(unix:///var/run/docker.sock)
INFO[0000] WARNING: You are running linux kernel version 2.6.32-504.3.3.el6.x86_64, which might be unstable running docker. Please upgrade your kernel to 3.8.0.
INFO[0000] Listening for HTTP on unix (/var/run/docker.sock)
INFO[0003] +job init_networkdriver()
INFO[0003] -job init_networkdriver() = OK (0)
INFO[0003] WARNING: mountpoint for memory not found

INFO[0003] Loading containers: start.

INFO[0003] Loading containers: done.
INFO[0003] docker daemon: 1.4.1 5bc2ff8; execdriver: native-0.2; graphdriver: devicemapper
INFO[0003] +job acceptconnections()
INFO[0003] -job acceptconnections() = OK (0)
INFOレベルの出力が出ていますが、上手く動いているようです。バージョンの確認をしておこうと思います。
# ./docker version
Client version: 1.4.1
Client API version: 1.16
Go version (client): go1.3.3
Git commit (client): 5bc2ff8
OS/Arch (client): linux/amd64
INFO[0358] GET /v1.16/version
INFO[0358] +job version()
INFO[0358] -job version() = OK (0)
Server version: 1.4.1
Server API version: 1.16
Go version (server): go1.3.3
Git commit (server): 5bc2ff8
次にcentos環境をdockerを使ってダウンロードしてみます。
# ./docker pull centos
INFO[9231] POST /v1.16/images/create?fromImage=centos%3Alatest
INFO[9231] +job pull(centos, latest)
INFO[9231] +job trust_update_base()
INFO[9231] -job trust_update_base() = OK (0)
INFO[9232] +job trust_key_check(/library/centos)
INFO[9232] -job trust_key_check(/library/centos) = OK (0)
centos:latest: The image you are pulling has been verified
511136ea3c5a: Pull complete
5b12ef8fd570: Pull complete
34943839435d: Pull complete
INFO[9512] +job log(pull, centos:latest, )
INFO[9512] -job log(pull, centos:latest, ) = OK (0)
Status: Downloaded newer image for centos:latest
INFO[9512] -job pull(centos, latest) = OK (0)
確認してみると、確かにcentosというrepositoryが追加されている模様。
# ./docker images
INFO[10005] GET /v1.16/images/json
INFO[10005] +job images()
INFO[10005] -job images() = OK (0)
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              latest              34943839435d        4 weeks ago         224 MB
このcentosイメージをrunしてみようとしたところ、なんだか様子が変ですね。
#  ./docker run centos /bin/echo /etc/redhat-release
ERRO[10267] Warning: error unmounting device ......
 ....しばらく頑張ってみましたが上手くいかず、方法を変更してEPEL Repository(yum)を使うことにしました。まずはEPELを有効化。
警告: /var/tmp/rpm-tmp.hzYFEo: ヘッダ V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
準備中...                ########################################### [100%]
   1:epel-release           ########################################### [100%]
続いて、docker-ioのインストール。yumだとパッケージ管理してくれるので依存しているパッケージもインストールしてくれるのがいいところです。
[root@rishiridake bin]# yum install docker-io
(途中、省略)
インストール:
  docker-io.x86_64 0:1.3.2-2.el6
依存性関連をインストールしました:
  libcgroup.x86_64 0:0.40.rc1-15.el6_6         lua-alt-getopt.noarch 0:0.7.0-1.el6
  lua-filesystem.x86_64 0:1.4.2-1.el6          lua-lxc.x86_64 0:1.0.7-1.el6
  lxc.x86_64 0:1.0.7-1.el6                     lxc-libs.x86_64 0:1.0.7-1.el6
依存パッケージ、結構ありますね。。これだけあると、先ほどのエラーが起こったのもパッケージが不足していたからでしょうか。サービス起動行い、先ほどダウンロードしたcentos環境を確認してみたいと思います。
[root@rishiridake bin]# service docker start
Starting cgconfig service:                                 [  OK  ]
Starting docker:                                           [  OK  ]
[root@rishiridake bin]# chkconfig docker on
[root@rishiridake bin]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos              latest              34943839435d        4 weeks ago         224 MB
では、centos環境をrunしてみたいと思います。

[root@rishiridake bin]# docker run -i -t centos /bin/bash
[root@06eb9c307e9f /]# echo "test"
test

うまくいきました。
[root@06eb9c307e9f opt]# exit
exit
[root@rishiridake bin]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@rishiridake bin]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                     PORTS               NAMES
06eb9c307e9f        centos:latest       "/bin/bash"            4 minutes ago       Exited (0) 2 minutes ago                       berserk_thompson
9c97364c0e49        centos:latest       "/bin/echo /etc/redh   22 minutes ago                                                     goofy_bardeen
dc05202ae310        centos:latest       "/bin/echo /etc/redh   23 minutes ago                                                     thirsty_kirch
5f4653bdb01a        centos:latest       "/bin/bash"            29 minutes ago                                                     elegant_thompson

 Containerは一度exitしても、起動後attachすればまた同じように使える。なるほど~、こういうのバージョン管理に使えますね。。

[root@rishiridake bin]# docker attach 06eb9c307e9f
2015/01/01 21:24:15 You cannot attach to a stopped container, start it first
[root@rishiridake bin]# docker start 06eb9c307e9f
06eb9c307e9f
[root@rishiridake bin]# docker attach 06eb9c307e9f
[root@06eb9c307e9f /]# echo test
test
この後しばらくこのdocker内のcentosを触って見ました。最小限のイメージのようで、多くのLinuxコマンドはインストールされておらず、新たにインストールする必要がありそうです。ネットワークはNAT構成のようです。全く新しいOSを使っているかのようです。これがContainerなのですね。。少し感動しました。また、一度触ったContainerはバージョン管理されており以下のコマンドで状態を管理することが出来ます。
[root@rishiridake bin]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                      PORTS               NAMES
06eb9c307e9f        centos:latest       "/bin/bash"            28 minutes ago      Exited (0) 24 seconds agoberserk_thompson
9c97364c0e49        centos:latest       "/bin/echo /etc/redh   47 minutes ago                                                      goofy_bardeen
dc05202ae310        centos:latest       "/bin/echo /etc/redh   48 minutes ago                                                      thirsty_kirch
5f4653bdb01a        centos:latest       "/bin/bash"            54 minutes ago                                                      elegant_thompson
直近で"EXIT"しているのがわかりますね。また、NAMESはデフォルトで適宜付けられているようですが、下記のようにテンプレートを作る際に必要です。そして、Containerを新たなテンプレートとして保存するには以下のコマンドを入力します。
[root@rishiridake bin]# docker commit berserk_thompson tori/hoge_inst
e29407e967a504d0b3c7bac8df54e35d3bdcf85220f67211c5f1d5df00e
[root@rishiridake bin]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
tori/hoge_inst    latest              e29407e967a5        21 seconds ago      358.6 MB
centos              latest              34943839435d        4 weeks ago         224 MB
一度imageを作成すれば、そのimageから複数のContainerを呼び出すことが可能のようです。

[root@rishiridake bin]# docker ps -a
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS                      PORTS               NAMES
1a76358a3982        tori/hoge_inst:latest   "/bin/bash"            19 seconds ago      Exited (0) 14 seconds ago                       boring_jones77ecc6b02699        tori/hoge_inst:latest   "/bin/bash"            32 seconds ago      Exited (0) 24 seconds ago                       backstabbing_kirch

バックグラウンドで走らせるには、deattachedモードでrunさせれば良いようです。
# docker run -i -t -d IMAGE /bin/bash
dockerいいですね。私は好きになりました。これからちょくちょく使っていく予感がします。
 
dockerで使用可能なコマンド一覧は下記のサイトがわかりやすいです。
 
docker全般の解説は下記が最も基礎的で良いと思います。