Docker は LXC (Linux Container) という Linux のコンテナ技術を基礎とした仮想化フレームワークです。
VMware や Virtualbox などの、ハードウェアまで仮想化する完全仮想化技術より必要とする CPU 処理能力やディスク容量が少ないため、
OS環境を保存しておくのに要するリソースや他のサーバーへ移動して稼働するのに要する時間が少なくて済みます。
Docker を使って、サーバー環境の移動を試してみます。
今回は実ハードウェアを複数用意する代わりに以下の環境を使用して作業を行いました。
VM を作成し、CentOS 6.5 (64bit) をインストールDVDからインストールします。
VM の設定
プロセッサコア 1
メモリ 1024M
ネットワークアダプタ ブリッジ自動検出
ハードディスク 20G
CentOS のインストーラーでほぼ全て default の Workstation 向けパッケージをインストール。
用意出来た VM上の CentOS にログインし、Docker をインストールします。
Docker 公式 web ページの
Red Hat Enterprise Linux へのインストール手順
http://docs.docker.io/installation/rhel/
に従います。
Extra Packages for Enterprise Linux (EPEL) リポジトリの追加
$ sudo yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
docker-io パッケージのインストール
$ sudo yum install docker-io --- 中略 --- Installed: docker-io.x86_64 0:0.11.1-4.el6 Dependency Installed: libcgroup.x86_64 0:0.40.rc1-5.el6_5.1 lxc.x86_64 0:0.9.0-2.el6 lxc-libs.x86_64 0:0.9.0-2.el6 Complete!
docker のベースになっている lxc 関連ファイルが依存関係を満たすため同時にインストールされます。
Docker デーモンの起動
$ sudo service docker start
マシン起動時の Docker デーモン自動起動設定
$ sudo chkconfig docker on
インストールが完了したら docker の情報を確認します。
$ sudo docker info [sudo] password for beat: Containers: 0 Images: 0 Storage Driver: devicemapper Pool Name: docker-253:0-797918-pool Data file: /var/lib/docker/devicemapper/devicemapper/data Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata Data Space Used: 2195.8 Mb Data Space Total: 102400.0 Mb Metadata Space Used: 0.7 Mb Metadata Space Total: 2048.0 Mb Execution Driver: lxc-0.9.0 Kernel Version: 2.6.32-431.17.1.el6.x86_64
まだインストール直後なのでコンテナもイメージも 0、
関連ファイルは /var/lib/docker/ の下に入ります。
docker pull コマンドで Django を動作させるサーバーの元になる CentOS のイメージを Docker 公式リポジトリから取得します。
$ sudo docker pull centos
取得した CentOS ベースイメージを確認します。
$ sudo docker images [sudo] password for beat: REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos centos6 0b443ba03958 5 weeks ago 297.6 MB centos latest 0b443ba03958 5 weeks ago 297.6 MB centos 6.4 539c0211cd76 14 months ago 300.6 MB
二つのイメージがダウンロードされました。
最新版には centos6 と latest 二つのタグが付けられているためリストには三つ見えていますが、実体は二つです。
最新版の方のイメージを、シェルが立ち上がり作業できる設定で起動します。
この時 Django の default 使用ポート 8000 をフォワードしておきます。
$ sudo docker run -i -t -p :8000 centos:centos6 bash bash-4.1#
docker image の公式リポジトリは海外のサーバーにあるため、ネットワークの状況や取得するイメージによっては
取得に時間のかかることがあります。
コンテナの shell でインストールを行います。
まず setuptools をインストール
bash-4.1# yum install python-setuptools
easey_install で pip をインストール
bash-4.1# easy_install pip
pip で Django をインストールします。
bash-4.1# pip install django
コンテナのインタフェースのIPアドレスを確認します。
以下の例ではコンテナ内で確認していますが、docker ps でコンテナIDを確認し
docker inspect コンテナID の出力の IPAddress で確認することもできます。
bash-4.1# /sbin/ifconfig eth0 Link encap:Ethernet HWaddr 92:C4:5C:74:DC:F3 inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::90c4:5cff:fe74:dcf3/64 Scope:Link UP BROADCAST RUNNING MTU:1500 Metric:1 RX packets:3 errors:0 dropped:0 overruns:0 frame:0 TX packets:4 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:238 (238.0 b) TX bytes:328 (328.0 b) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
Django の最も簡単な動作確認を行います。
bash-4.1# cd /home/ bash-4.1# django-admin.py startproject mysite bash-4.1# cd mysite bash-4.1# python manage.py runserver 172.17.0.2:8000 Validating models... 0 errors found May 26, 2014 - 11:30:12 Django version 1.6.5, using settings 'mysite.settings' Starting development server at http://172.17.0.2:8000/ Quit the server with CONTROL-C.
正常に起動したら VM の CentOS 上のwebブラウザで上記URLにアクセスします。
Django のデフォルトページが表示されたらOKです。
3 から 5 までの手順を行ったコンテナは bash を抜けると終了してしまい、同じイメージから再度起動しても加えた変更残っていません。
そこでベースイメージに加えた変更を再利用できるよう、コンテナからイメージを作成します。
docker ps コマンドで以前に使用したコンテナのリストを表示します。
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d17bf0933bfb centos:centos6 bash About 10 minits ago Exited (0) 10 seconds ago agitated_hypatia 95aaa7e741df centos:centos6 bash 5 hours ago Exited (1) 5 hours ago romantic_ptolemy 47ee760a5dca centos:centos6 bash 5 hours ago Exited (0) 5 hours ago cranky_sinoussi 4711136aef8a centos:centos6 bash 5 hours ago Exited (1) 5 hours ago kickass_albattani 5de34b44f509 centos:centos6 bash 5 hours ago Exited (0) 5 hours ago sick_darwin 7b8865d3587b centos:centos6 bash 5 hours ago Exited (0) 5 hours ago dreamy_einstein
上記のような形式で、それまでに起動させたコンテナが表示されます。
今終了させたばかりのコンテナを確認し、docker commit コマンドで名前を付けてコンテナからイメージを作成します。
$ sudo docker commit d17bf0933bfb django-test
イメージが正常に作成されたか確認します。
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE django-test latest f7961339d47b About 2 seconds ago 374.4 MB centos centos6 0b443ba03958 5 weeks ago 297.6 MB centos latest 0b443ba03958 5 weeks ago 297.6 MB centos 6.4 539c0211cd76 14 months ago 300.6 MB
作成したイメージを起動し、先ほど shell 上で加えた変更が利用可能のままになっていることを確認します。
$ sudo docker run -i -t -p :8000 django-test:latest bash bash-4.1# cd /home/mysite bash-4.1# python manage.py runserver 172.17.0.2:8000 Validating models... 0 errors found May 26, 2014 - 11:30:12 Django version 1.6.5, using settings 'mysite.settings' Starting development server at http://172.17.0.2:8000/ Quit the server with CONTROL-C.
内部に変更が保存されており、ブラウザで Django にアクセス出来ることも確認できたら shell を抜けてコンテナを終了します。
このコンテナイメージを他の環境に移動できるよう export します。
$ sudo docker ps -a [sudo] password for beat: CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 94cbb5bca398 django-test:latest bash 4 minutes ago Exited (0) 12 seconds ago backstabbing_goldstine d17bf0933bfb centos:centos6 bash About an hour ago Exited (0) About an hour ago agitated_hypatia 95aaa7e741df centos:centos6 bash 5 hours ago Exited (1) 5 hours ago romantic_ptolemy 47ee760a5dca centos:centos6 bash 5 hours ago Exited (0) 5 hours ago cranky_sinoussi 4711136aef8a centos:centos6 bash 5 hours ago Exited (1) 5 hours ago kickass_albattani 5de34b44f509 centos:centos6 bash 5 hours ago Exited (0) 5 hours ago sick_darwin 7b8865d3587b centos:centos6 bash 5 hours ago Exited (0) 5 hours ago dreamy_einstein
最後に起動したコンテナを export します。export 対象はコンテナIDか自動で付けられる識別名で指定します。
$ sudo docker export 94cbb5bca398 > django-test-export.tar $ ls -alh django-test-export.tar -rw-rw-r--. 1 beat beat 362M 5月 26 21:07 2014 django-test-export.tar
export したイメージのサイズは django images で確認した django-test の VRTUAL SIZE より少し小さくなり、
362M になりました。
コンテナイメージを移動して動作させる先の環境として、1 と同じ構成の VM を再度作成します。
docker によって動作するコンテナイメージの移動が可能であることを確認するための環境なので、
1 の VM をそのままコピーして利用することはせず、同じ手順で再度作成します。
2 の手順と同じ手順を行います。
6 の手順で export して作成したアーカイブファイルを scp などで新たな VM 上にコピーし、
docker の import コマンドで import します。
$ sudo -s # cat django-test-export.tar | docker import - beat:django-test 0698f1626b7a1e3946de1ec3a3abc38cba6ba91726676341208062e49216bac7
正しく import されたか確認します。
$ sudoo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE beat django-test 5df9c99c50ff 7 minutes ago 364 MB
import したイメージを起動します。
$ sudo docker run -i -t -p 8000 beat:django-test bash bash-4.1# bash-4.1# cd /home/mysite bash-4.1# python manage.py runserver 172.17.0.2:8000 Validating models... 0 errors found May 26, 2014 - 13:11:59 Django version 1.6.5, using settings 'mysite.settings' Starting development server at http://172.17.0.2:8000/ Quit the server with CONTROL-C.
VM 上の web ブラウザから 172.17.0.2:8000 へアクセスして Django ページの表示が確認できれば
移動は成功です。
今回の試行では、
で同じサーバー環境を別途一から作るのよりわずかに効率化できた程度ですが、
実際のサービスに使用するようなサーバー環境を作成する場合には
3〜5 の仮想環境作成とサーバーアプリケーションのセットアップに今回の試行例より時間を要するはずです。
その部分を一度だけ行ってイメージ化すれば、7〜10 は今回の試行例と変わらない短時間で行えるため
サーバー環境設定の効率化に大きな効果が期待できます。
イメージとコンテナを別々に操作する概念と、コンテナ内へネットワークからアクセスする方法が
最初は分かりにくい感じがあるのですが、一旦把握できれば
仮想化したイメージの扱いは楽で作業時間も非常に短く済み、
有用に感じました。
今回の試行例では 3〜5 の作業を shell から直接コマンドを入力して行っていますが、
Dockerfile という定義ファイルを作成してイメージを作成する方法もあります。
作業内容の記録と自動化のため Dockerfile を記述してイメージ作成を行う方が一般的です。
Dockerfile を作成したら docker build コマンドを実行するだけで
などを一括して行うことができます。
docker サービスを起動すると、コンテナ内との接続用にブリッジ docker0 が作られます。
$ /sbin/ifconfig docker0 docker0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::389f:86ff:feca:5735/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:54 errors:0 dropped:0 overruns:0 frame:0 TX packets:38 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:9164 (8.9 KiB) TX bytes:3427 (3.3 KiB)
このブリッジは iptables による IPマスカレードで外部ネットワークと接続します。
(ですから docker 起動中は iptables を停止してはいけません。)
コンテナを起動すると、veth**(OpenVZ由来の Virtual Ethernet Tunnel)も作られ、
コンテナ内部の eth0 と仮想的な組を作って接続されます。
vethKT14kb Link encap:Ethernet HWaddr FE:92:46:C6:45:B1 inet6 addr: fe80::fc92:46ff:fec6:45b1/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:3 errors:0 dropped:0 overruns:0 frame:0 TX packets:3 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:238 (238.0 b) TX bytes:238 (238.0 b)
コンテナ内部からはこの veth**--docker0 経由で外部のネットワークへ出て行くことが出来ますが、
コンテナのネットワークへはホストLinux 上からしかアクセスできません。
ホストLinux の外部ネットワークからコンテナ上のサーバーへアクセス出来るようにするためには、
Redirect Ports
http://docs.docker.io/use/port_redirection/
に解説されているように、 docker run 時に行う port のリダイレクトに IPアドレスの設定も加え
外部から到達可能な IPアドレスへリダイレクトを行うか、
コンテナに追加の veth を加えてホストOSのネットワークインタフェースへの bridge を行う
Pipework: Software-Defined Networking for Linux Containers
https://github.com/jpetazzo/pipework
という shellscript のツールを使用します。
イメージの起動時に
$ sudo docker run -i -t -p 8000 beat:django-test bash
の代わりに
$ sudo docker run -i -t -p 192.168.0.161:80:8000 beat:django-test bash
とコンテナ内部の 8000 ポートをホストOS eth0 の IPアドレス 80番へリダイレクトして起動すれば、
コンテナ内部で起動した django (python manage.py runserver 172.17.0.2:8000)へは
192.168.0.161:80 へアクセスすることで同じネットワークに属している他のマシンからも
アクセス可能になります。
2014/05/28 export イメージサイズ、Port のリダイレクトに関し追記
2014/05/27 初稿公開