このエントリーは、2015/11/04に開催のRed Hat Forum 2015の「Red Hat Enterprise Linux OpenStack Platform環境でのDocker活用テクニック」というセッションで説明する内容のメモ書きです。この内容をもっと詳しく(分かりやすく)聞きたいという方は、こちらのセッションにお越しください。登録時の招待コードは「300」です。
事前準備
取り急ぎのメモ書き・・・。CentOS7でも本質的には同じです。CentOS7の場合は、subscription-managerコマンドは無視してください。
はじめに、RHEL7のクラウドイメージをCustomer Portalからダウンロードして、Glanceに登録しておきます。
Dockerのイメージ保存領域を追加のエフェメラルディスクに配置するので、追加のエフェメラルディスク(とついでにSwap領域)を持ったフレーバー m1.docker を定義しておきます。
# nova flavor-show m1.docker
+----------------------------+--------------------------------------+
| Property | Value |
+----------------------------+--------------------------------------+
| OS-FLV-DISABLED:disabled | False |
| OS-FLV-EXT-DATA:ephemeral | 20 <---ココが重要 |
| disk | 10 |
| extra_specs | {} |
| id | a385b85b-8efd-4149-a914-4d870f09af9b |
| name | m1.docker |
| os-flavor-access:is_public | True |
| ram | 1024 |
| rxtx_factor | 1.0 |
| swap | 2048 <---ココが重要 |
| vcpus | 1 |
+----------------------------+--------------------------------------+RHEL7のイメージからVMインスタンスを起動してログインしたら、下記のコマンドでDockerを導入します。
# subscription-manager register # subscription-manager attach --pool=<pool id> # subscription-manager repos --disable=* # subscription-manager repos --enable=rhel-7-server-rpms --enable=rhel-7-server-extras-rpms # yum -y update # yum -y install docker lvm2
この状態でインスタンスを停止(削除ではないですよ!)して、スナップショットを作成しておきます。(スナップショットを作成する前のゴミ掃除は適当にお願いします。)
# glance image-list +--------------------------------------+------------------+-------------+------------------+------------+--------+ | ID | Name | Disk Format | Container Format | Size | Status | +--------------------------------------+------------------+-------------+------------------+------------+--------+ | d6bd60e9-be04-4610-8cad-c3644182fa69 | RHEL7.1 | qcow2 | bare | 425956864 | active | | cdcc6a27-c88f-4032-87a9-1370ea89d0ff | RHEL7_Docker | qcow2 | bare | 1449000960 | active | +--------------------------------------+------------------+-------------+------------------+------------+--------+
VMインスタンスの起動
先ほど保存したスナップショットからインスタンスを起動して、UserDataで、下記のスクリプトを流します。フレーバーは事前に用意したm1.dockerを使用してください。/etc/sysconfig/dockerと/etc/hostsの設定は、プライベートレジストリー(192.168.1.101)を参照するためのものです。
#!/bin/bash -x cat <<'EOF' >>/etc/sysconfig/docker INSECURE_REGISTRY='--insecure-registry registry01:5000' EOF cat <<'EOF' >>/etc/hosts 192.168.1.101 registry01 EOF umount /mnt sed -i 's/^\/dev\/vdb/#\/dev\/vdb/' /etc/fstab cat <<'EOF' >/etc/sysconfig/docker-storage-setup VG=vg_pool DATA_SIZE=18G EOF systemctl stop --no-block docker.service rm -rf /var/lib/docker/* pvcreate -f /dev/vdb vgcreate vg_pool /dev/vdb docker-storage-setup systemctl start --no-block docker.service
この後、インスタンスにログインすれば、普通にdockerコマンドが使えます。
# docker info Containers: 0 Images: 0 Storage Driver: devicemapper Pool Name: vg_pool-docker--pool Pool Blocksize: 524.3 kB Backing Filesystem: xfs Data file: Metadata file: Data Space Used: 20.45 MB Data Space Total: 19.33 GB Data Space Available: 19.31 GB Metadata Space Used: 49.15 kB Metadata Space Total: 25.17 MB Metadata Space Available: 25.12 MB Udev Sync Supported: true Deferred Removal Enabled: true Library Version: 1.02.93-RHEL7 (2015-01-28) Execution Driver: native-0.2 Logging Driver: json-file Kernel Version: 3.10.0-229.14.1.el7.x86_64 Operating System: Employee SKU CPUs: 1 Total Memory: 993.3 MiB Name: docker02.novalocal ID: LT2Y:LJKF:JZRM:C3RH:U4BK:K6IK:3AMS:BESA:DAFO:NMDJ:FCED:HI6Z
UserDataからコンテナを起動する方法
これには、実は少しトリックが必要です・・・・。
UserDataを実行するcloud-init.serviceは、systemdのサービスとして実行しているため、この中で発行した "systemctl start --no-block docker.service" は、UserDataの実行が完了するまで実際の実行が行われません。つまり、UserDataの中で、docker.serviceの起動完了を待って、"docker run"を実行するという処理ができないのです。
ここでは、「docker.serviceの起動完了を待って、"docker run"を実行する」というスクリプトをその場で作って、バックグラウンドで実行しておくという作戦を取ります。具体的には、次のようなUserDataになります。
#!/bin/bash -x # Settings for the private registry cat <<'EOF' >>/etc/sysconfig/docker INSECURE_REGISTRY='--insecure-registry registry01:5000' EOF cat <<'EOF' >>/etc/hosts 192.168.1.101 registry01 EOF # Setting up the local storage umount /mnt sed -i 's/^\/dev\/vdb/#\/dev\/vdb/' /etc/fstab cat <<'EOF' >/etc/sysconfig/docker-storage-setup VG=vg_pool DATA_SIZE=18G EOF rm -rf /var/lib/docker/* pvcreate -f /dev/vdb vgcreate vg_pool /dev/vdb docker-storage-setup # Starting the docker service and a container systemctl --no-block start docker.service cat <<'EOF' >/tmp/run_container$$.sh #!/bin/bash while [[ true ]]; do sleep 5 systemctl is-active docker.service && break done docker run -itd -p 8000:80 --name dengonban01 registry01:5000/enakai00/rails:ver1.0 EOF chmod u+x /tmp/run_container$$.sh /tmp/run_container$$.sh 2>&1 | logger -t run_container$$ &
うーん。もうちょっとすっきりできないですかね。
と思いつつ次の手順へ。
単一コンテナのアプリを起動する

「Docker実践入門」の「2.2.2 Dockerfileとシェルスクリプトの連携」で紹介されている伝言板アプリのコンテナを起動してみます。ここでは、書籍の手順で作成したイメージをプライベートレジストリーに「registry01:5000/enakai00/dengonban:ver1.0」として保存してあるものとします。(プライベートレジストリーのセットアップ方法などは、書籍を参照してくださいね!)
まず、UserDataで使用する次のスクリプトを用意します。
dengonban.txt
#!/bin/bash -x # Settings for the private registry cat <<'EOF' >>/etc/sysconfig/docker INSECURE_REGISTRY='--insecure-registry registry01:5000' EOF cat <<'EOF' >>/etc/hosts 192.168.1.101 registry01 EOF # Setting up the local storage umount /mnt sed -i 's/^\/dev\/vdb/#\/dev\/vdb/' /etc/fstab cat <<'EOF' >/etc/sysconfig/docker-storage-setup VG=vg_pool DATA_SIZE=18G EOF rm -rf /var/lib/docker/* pvcreate -f /dev/vdb vgcreate vg_pool /dev/vdb docker-storage-setup # Starting the docker service and a container systemctl --no-block start docker.service cat <<'EOF' >/tmp/run_container$$.sh #!/bin/bash while [[ true ]]; do sleep 5 systemctl is-active docker.service && break done docker run -itd -p 8000:80 --name dengonban01 registry01:5000/enakai00/rails:ver1.0 EOF chmod u+x /tmp/run_container$$.sh /tmp/run_container$$.sh 2>&1 | logger -t run_container$$ &
次のコマンドでVMインスタンスを起動します。(オプションは環境に応じて、適当に変えてください。)
# nova boot --flavor m1.docker --image RHEL7_Docker --key-name mykey \ --security-groups default --nic net-id=4edf131f-eb31-4121-b754-3b15769bf468 \ --user-data dengonban.txt dengonban01 # nova add-floating-ip dengonban01 192.168.1.102
インスタンスが起動すると、プライベートレジストリーからイメージを取得して、自動的にコンテナが起動します。ブラウザから「http://192.168.1.102:8000」にアクセスすると伝言板が利用できます。(セキュリティグループは、8000番ポートの接続を許可しておいてください。)
複数コンテナの連携アプリを起動する

「Docker実践入門」の「2.3 複数コンテナーの連携活用」で紹介されている短縮URLサービスアプリのコンテナを起動します。これは、バックエンドのMySQLとフロントエンドのnode.jsアプリが連携するシステムです。それぞれ、異なるVMインスタンス上でコンテナを起動して連携させてみます。また、MySQLについては、Cinderボリュームの中にテーブルデータを保存するように構成します。
MySQLとnode.jsアプリのイメージは、書籍の手順で作成して、プライベートレジストリーに「registry01:5000/enakai00/mysql:ver1.0」「registry01:5000/enakai00/shorturl:ver1.0」として保存してあるものとします。
MySQLは、次のUserDataで起動します。
mysql.txt
#!/bin/bash -x
# Settings for the private registry
cat <<'EOF' >>/etc/sysconfig/docker
INSECURE_REGISTRY='--insecure-registry registry01:5000'
EOF
cat <<'EOF' >>/etc/hosts
192.168.1.101 registry01
EOF
# Setting up the local storage
umount /mnt
sed -i 's/^\/dev\/vdb/#\/dev\/vdb/' /etc/fstab
cat <<'EOF' >/etc/sysconfig/docker-storage-setup
VG=vg_pool
DATA_SIZE=18G
EOF
rm -rf /var/lib/docker/*
pvcreate -f /dev/vdb
vgcreate vg_pool /dev/vdb
docker-storage-setup
# Starting the docker service and a container
systemctl --no-block start docker.service
cat <<'EOF' >/tmp/run_container$$.sh
#!/bin/bash
while [[ true ]]; do
sleep 5
systemctl is-active docker.service && break
done
# Wait until the cinder volume becomes available.
while [[ true ]]; do
sleep 5
if lsblk | grep '^vdd'; then
break
fi
done
# Mount the cinder volume on /data.
mkfs.xfs -f /dev/vdd
mkdir /data
mount /dev/vdd /data
mkdir /data/mysql01
chcon -Rt svirt_sandbox_file_t /data
# Start the container and mysqld service.
docker run -itd --name mysql01 -v /data/mysql01:/var/lib/mysql -p 10000:3306 registry01:5000/enakai00/mysql:ver1.0
while [[ true ]]; do
sleep 5
if docker exec mysql01 mysql -u root -e "show databases;"; then
break
fi
done
docker exec mysql01 mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'nodeuser'@'localhost';"
docker exec mysql01 mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'nodeuser'@'%' IDENTIFIED BY 'pas4mysql';"
docker exec mysql01 mysql -u nodeuser -e "CREATE DATABASE shorturl_service;"
docker exec mysql01 mysql shorturl_service -u nodeuser -e " \
CREATE TABLE url_list ( \
hash CHAR(12) PRIMARY KEY, \
url VARCHAR(256) UNIQUE NOT NULL COLLATE utf8_bin \
);"
EOF
chmod u+x /tmp/run_container$$.sh
/tmp/run_container$$.sh 2>&1 | logger -t run_container$$ &コンテナの起動スクリプトでは、Cinderボリュームが/dev/vddとして認識されるのを待って、その後、ボリュームのフォーマット/マウントを行い、これをコンテナ内の/var/lib/mysqlに割り当てています。コンテナ起動後に、MySQLのデータベースの初期化を行っています。エラー処理などは省略していますので、そのあたりは、突っ込まないでください。
次のコマンドで、VMインスタンスの起動とCinderボリュームのアタッチを行います。
# nova boot --flavor m1.docker --image RHEL7_Docker --key-name mykey \ --security-groups default --nic net-id=4edf131f-eb31-4121-b754-3b15769bf468 \ --user-data mysql.txt mysql01 # nova add-floating-ip mysql01 192.168.1.104 # nova volume-attach mysql01 03e12c55-5a0e-4630-a630-2d34283144ed
コンテナが起動すると、外部からは、10000番ポートでMySQLに接続可能になります。(セキュリティグループで、10000番ポートへの接続を許可しておいてください。)
この次は、node.jsアプリのコンテナを起動します。次のUserDataを使用します。
shorturl.txt
#!/bin/bash -x # Settings for the private registry cat <<'EOF' >>/etc/sysconfig/docker INSECURE_REGISTRY='--insecure-registry registry01:5000' EOF cat <<'EOF' >>/etc/hosts 192.168.1.101 registry01 EOF # Setting up the local storage umount /mnt sed -i 's/^\/dev\/vdb/#\/dev\/vdb/' /etc/fstab cat <<'EOF' >/etc/sysconfig/docker-storage-setup VG=vg_pool DATA_SIZE=18G EOF rm -rf /var/lib/docker/* pvcreate -f /dev/vdb vgcreate vg_pool /dev/vdb docker-storage-setup # Starting the docker service and a container systemctl --no-block start docker.service cat <<'EOF' >/tmp/run_container$$.sh #!/bin/bash while [[ true ]]; do sleep 5 systemctl is-active docker.service && break done # Start the container and mysqld service. docker run -itd --name shorturl01 -p 8000:80 \ -e DB_PORT_3306_TCP_ADDR=192.168.1.104 \ -e DB_PORT_3306_TCP_PORT=10000 \ registry01:5000/enakai00/shorturl:ver1.0 EOF chmod u+x /tmp/run_container$$.sh /tmp/run_container$$.sh 2>&1 | logger -t run_container$$ &
次のコマンドでVMインスタンスを起動します。
# nova boot --flavor m1.docker --image RHEL7_Docker --key-name mykey \ --security-groups default --nic net-id=4edf131f-eb31-4121-b754-3b15769bf468 \ --user-data shorturl.txt shorturl01 # nova add-floating-ip shorturl01 192.168.1.105
コンテナが起動したら、WebブラウザでURL「http://192.168.1.105:8000」にアクセスすると、短縮URLサービスが利用できます。