Dockerにおけるデータ専用コンテナ、KVM仮想化環境からの移行
Dockerでは、OSのベースイメージ以外にも、データ専用のコンテナ(一般的にデータコンテナと呼ばれます)を作成することができます。データ専用のコンテナを作成しておけば、アプリケーションが参照するデータを別コンテナに分離し、次々と生成されるコンテナで、データコンテナに保管したユーザーデータの再利用ができるようになり、データの可搬性が向上します。
データ専用コンテナ
データ専用コンテナには、OSイメージではなく、busyboxとよばれるイメージを利用します。busyboxは、基本的なLinuxコマンド群を単一のbusyboxコマンドにまとめたものであり、必要最小限のLinuxシェル環境を提供する場合によく利用されています。以下では、/data0001ディレクトリを提供するデータ専用のコンテナd0001を作成する手順を示します。まず、busyboxのイメージをdocker pullにより入手します。
# docker pull busybox:latest
/data0001ディレクトリを提供するコンテナd0001を生成します。
# docker run -i -t -v /data0001 --name d0001 busybox /bin/sh / #
生成されたコンテナd0001のコマンドライン上で、空の/data0001ディレクトリが自動的に作成されていることを確認し、テスト用のファイルdatafile01.txtを作成します。
/ # ls /data0001/ / # / # echo "Hello data container" > /data0001/datafile01.txt
データ専用コンテナd0001のコマンドラインをexitコマンドで離脱し、別のコンテナc0001からコンテナd0001の/data0001ディレクトリを利用します。
/ # exit # docker run -i -t --volumes-from d0001 --name c0001 centos:centos7.1.1503 /bin/bash [root@11d62810bd4a data0001]# cat /data0001/datafile01.txt Hello data containerHello data container [root@11d62810bd4a data0001]#
データ専用コンテナを使ったボリュームのバックアップ
busyboxとtarコマンドを組み合わせることで、データ専用コンテナに保管されているデータをホストOS上にバックアップ、またはコンテナへリストアすることが可能です。以下では、データ専用コンテナd0002が提供する/datadirをホストOS上の/hostdirにバックアップする例を示します。まず、バックアップ対象のデータを含むコンテナを生成します。/datadirディレクトリをボリュームとして提供するデータ専用コンテナd0002を生成します。
# docker run -i -t -v /datadir --name d0002 busybox /bin/sh / #
データ専用コンテナd0002上の/datadirにバックアップ対象となるファイルを保管します。
/ # echo "Hello data container" > /datadir/datafile.txt
別の端末で、ホストOS上のコマンドラインから、データ専用コンテナd0002のボリューム/datadir以下全てをホストOS上の/hostdirディレクトリ配下に、backup.tarとしてバックアップします。
# docker run --rm --volumes-from d0002 -v /hostdir:/ctdir busybox:latest tar cvf /ctdir/backup.tar /datadir tar: removing leading '/' from member names datadir/ datadir/datafile.txt
ホストOS上の/hostdirディレクトリにバックアップアーカイブのbackup.tarが保存されているかを確認します。
# ls -l /hostdir/ 合計 4 -rw-r--r--. 1 root root 2560 5月 24 12:53 backup.tar # tar tvf /hostdir/backup.tar drwxr-xr-x root/root 0 2015-05-24 12:52 datadir/ -rw-r--r-- root/root 21 2015-05-24 12:52 datadir/datafile.txt
[補足]
上記のtarコマンドは、busyboxが提供するコンテナ上で実行され、そのコンテナ内の/ctdirディレクトリ上にファイルが保管され、コンテナの/ctdirディレクトリがホストOSの/hostdirディレクトリに紐づいているため、結果的にホストOS上の/hostdirにバックアップが保管されています。tarコマンドは、busyboxが提供しているものですので、通常のLinux OSに搭載されているGNU tarに比べ、機能が制限されている点に注意する必要があります。
ホストOSにバックアップしたデータを別のコンテナにリストア
次に、ホストOSの/hostdirディレクトリ上にバックアップしたデータbackup.tarを別のコンテナにリストアしてみましょう。リストア先となるコンテナc0003を生成、起動します。コンテナc0003は、ホストOSに対して、/datadirディレクトリを提供し、このディレクトリ配下にリストアするため、コンテナ起動時に「-v /datadir」の付与が必要です。
# docker run -i -t -v /datadir --name c0003 centos:centos7.1.1503 /bin/bash [root@c7e14aaea18e /]# ls -l /datadir/ total 0 [root@c7e14aaea18e /]#
次に、別の端末のホストOSのコマンドラインから、ホストOS上の/hostdirディレクトリに保管されたバックアップデータbackup.tarを、コンテナc0003にリストアします。
# docker run --rm --volumes-from c0003 -v /hostdir:/ctdir busybox:latest tar xvf /ctdir/backup.tar -C / datadir/ datadir/datafile.txt #
再び、コンテナc0003が稼働している端末に戻り、ホストOSに保管されているバックアップデータbackup.tarがコンテナc0003の/datadir配下にリストアされているかを確認します。
[root@c7e14aaea18e /]# # cat /datadir/datafile.txt Hello data container [root@c7e14aaea18e /]#
Dockerにおけるコンテナのインポートとエクスポート
既存の仮想化環境で構築された様々なアプリケーション資産が有効に機能しており、安定的に利用できている場合は、そのまま仮想化基盤を利用することが考えられます。しかし、イミュータブル・インフラなどのDevOps環境の新規導入を検討している場合は、それらの既存の仮想化基盤のソフトウェア資産をDocker環境に移行することが考えられます。このような仮想化からDockerへの移行要件に応えるため、Dockerでは、仮想化基盤で利用されているゲストOSのイメージファイルなどの非Docker環境のイメージ(厳密にはアーカイブファイルです)を、Docker環境に移行する手段が用意されています。具体的には、既存のKVM仮想化環境のゲストOSのqcow2形式のイメージファイルをtarアーカイブに変換し、Docker環境にインポートすることで、Dockerイメージに変換し、Docker上でコンテナとして利用するといった移植方法になります。以下では、既存のKVM仮想化基盤のゲストOSイメージをDocker環境に移植する例を示します。
まず、移植対象のKVMゲストOSをシャットダウンします。ここでは、KVMゲストOSの名前をc66svr01とし、KVMゲストOSは、CentOS 6.6を想定します。
# virsh shutdown c66svr01
Dockerが稼働するCentOS 7.xのシステムにKVMゲストOSのqcow2イメージをコピーします。標準では、KVMゲストOSのイメージファイルは、/var/lib/libvirt/imagesディレクトリに保管されています。コピー先のCentOS 7.xのディレクトリのパスは任意ですが、ここでは、/dataディレクトリにコピーすことにします。以下は、Dockerが稼働するホストで作業します。
# mkdir /data # scp KVMホストマシンのIPアドレス:/var/lib/libvirt/images/c66svr01.qcow2 /data/ # cd /data/ # ls -lh c66svr01.qcow2 -rw-------. 1 qemu qemu 17G 5月 26 00:00 c66svr01.qcow2
Dockerが稼働するCentOS 7.xがインストールされたサーバーに、qcow2イメージファイルをtarアーカイブに変換するvirt-tar-outコマンドをインストールします。virt-tar-outコマンドは、libguestfs-toolsパッケージに含まれています。
# yum install -y libguestfs-tools
virt-tar-outコマンドを使って、KVMゲストOSのqcow2イメージを、圧縮されたtarアーカイブに変換します。
# virt-tar-out -a c66svr01.qcow2 / - | gzip > c66svr01.tgz # ls -lh c66svr01.tgz -rw-r--r--. 1 root root 361M 5月 28 14:01 c66svr01.tgz
c66svr01.tgzをDocker環境にインポートします。
# cat c66svr01.tgz |docker import - centos:c66svr01 95770ed984259fd699e569545855f27e236152d6a0cac1828dac8943467916a2
[補足]
以下のように、環境変数を設定すれば、virt-tar-outコマンドとdockerコマンドをパイプで連結させることも可能です。
# export LIBGUESTFS_BACKEND=direct # virt-tar-out -a /data/c66svr01.qcow2 / - | docker import - centos:c66svr01 # docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE centos c66svr01 95770ed98425 About a minute ago 960.6 MB #
[注意]
ここで、devicemapperが提供するファイルに空き容量が無い旨のエラーメッセージが出力される場合は、/etc/sysconfig/docker-storageで設定したパラメータが小さい可能性があります。そのため、大きい値に変更する必要があります。ただし、/etc/sysconfig/docker-storageのパラメータ変更を有効にするには、dockerサービスを停止後、/var/lib/dockerディレクトリ配下を一旦全て削除しなければならないため、既存のDockerイメージは、全て破棄する必要がありますので、注意が必要です。
インポートしたDockerイメージを起動させてみましょう。
# docker run -i -t --name c66svr01 --hostname c66svr01 centos:c66svr01 /bin/bash [root@c66svr01 /]# ifconfig eth0 |grep "inet addr" inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 [root@c66svr01 /]# service httpd start ...
既存のKVMゲストOS環境をDocker環境に移植できていることがわかります。ただし、IPアドレスの固定割り当て、ホスト名、OS起動時の各種スクリプト等の設定は、Docker環境で別途追加設定を行う必要があります。
systemdに対応したコンテナの利用
CentOS 7.xでは、サービスの起動の仕組みにsystemdが採用されています。systemdが採用されているOSをコンテナとして稼働させる場合は、systemdをインストールしたDockerイメージを作成しなければなりません。また、docker runによるコンテナの起動時に、--privilegedオプションを付与し、コンテナ自体は、/sbin/initで起動します。また、コンテナのプロセスは、-dオプションを付与し、バックグラウンドで稼働させます。これにより、systemdが利用可能となり、CentOS 7.xやUbuntu 15.04などのコンテナ内で、systemdによる各種サービスの起動を行うことができます。
以下は、CentOS 7.1のDockerイメージを使って起動したDockerコンテナにsystemdをインストールし、systemdをインストールしたDockerイメージcentos:test01を新たに作成し、そのイメージからApache Webサービスをsystemd経由で起動させる例です。
# docker run -i -t --name test01 --hostname test01 centos:centos7.1.1503 /bin/bash [root@test01 /]# vi /etc/yum.conf ... proxy=http://プロキシーサーバーのURL:8080 ... [root@test01 /]# yum clean all && yum swap -y fakesystemd systemd [root@test01 /]# exit # docker commit test01 centos:test01 # docker rm -f test01 # docker run -d --privileged --name test01 --hostname test01 centos:test01 /sbin/init
稼働中のコンテナには、docker execコマンドで入ることができます。
# docker exec -i -t test01 /bin/bash [root@test01 /]# yum install -y httpd [root@test01 /]# systemctl start httpd [root@test01 /]# systemctl status httpd [root@test01 /]# systemctl enable httpd [root@test01 /]# ip a |grep "inet " inet 127.0.0.1/8 scope host lo inet 172.17.0.8/16 scope global eth0 [root@test01 /]# exit # curl http://172.17.0.8
まとめ
第5回~第8回では、Dockerの基本的な操作をご紹介しました。Dockerは、単なるハイパーバイザー型の仮想化ソフトウェアに取って代わるサーバー集約の手段というだけでなく、クラウド基盤のサービス提供やDevOps環境で必要とされる非常に重要な基盤技術として非常に注目を浴びていますが、アプリケーションの稼働だけでなく、データ専用コンテナや、バックアップ専用のためにコンテナを利用するなど、応用範囲が広いことが理解できたかと思います。