このエントリーは、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サービスが利用できます。