OpenStack の DBaaS(Trove)導入 - イメージ作成編

カバー

[!] この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

OSS として仮想マシンや仮想ネットワークなどのクラウド環境を提供する OpenStack ですが、ここに Trove というサービスを加えることにより、データベースを簡単に構築、管理し、仮想マシンから利用できるようになります。

Trove が提供する各種データベースのサーバーは、該当の起動イメージをもとに作成される、仮想マシンインスタンス上で動作します。 この記事では、Trove の紹介から始め、OpenStack(Queens 版)環境に Trove を導入する際の要の作業となる、起動イメージの作成と、無事動作できるためのポイントまでを複数回にわたって説明します。

導入入門編では、Troveについて紹介し、導入作業の流れ、および登場する Trove のプロセスについて説明しました。

今回のイメージ作成編では、Trove のデータベースサーバー起動イメージ作成について説明します。データストアとしては MySQL を使用します。Trove のイメージは Diskimage-builder により作成しますので、まずその説明から始めます。

Diskimage-builder (DIB) について

概要

Diskimage-builder (以下 DIB) は、クラウドやその他環境用のディスクイメージを作成するための python ツールです。DIB では、elements と呼ばれるイメージ作成・変更用の部品をいくつか組み合わせて使用し、目的の仕様に合うイメージを構築します。たとえば、OS は Ubuntu で、ディスクパーティションを持ち、MySQL サーバーが導入済みで、Trove guest agent が動作するディスクイメージ、などが目的の仕様になります。

OpenStack (Queens 版) リリース時期近辺の DIB のバージョンが、以下のコマンドでダウンロードできます。

$ git clone https://git.openstack.org/openstack/diskimage-builder -b 2.33.0

elements

DIB の elements は、ディスクイメージに変更を加えていくためのものであり、実体は DIB により chroot 環境で実行される bash スクリプト群です。DIB が標準で提供している elements は、DIB をダウンロードしたディレクトリ配下の diskimage_builder/elements/ に格納されています。

[centos@dib diskimage-builder]$ ls -F diskimage_builder/elements/
apt-conf/                     install-static/
apt-preferences/              install-types/
apt-sources/                  ironic-agent/
...
fedora/                       uboot/
fedora-minimal/               ubuntu/
gentoo/                       ubuntu-common/
growroot/                     ubuntu-minimal/
grub2/                        ubuntu-signed/
hpdsa/                        ubuntu-systemd-container/
hwburnin/                     vm/
...

elements のディレクトリがたくさん見えますが、このうちいくつかの elements の使用効果について紹介します。

  • ubuntu : OS のイメージとして Ubuntu を使用します

  • fedora : OS のイメージとして Fedora を使用します

  • vm : ディスクイメージにパーティションを作成します

elements には、DIB により標準的に提供されるもののほかに、その他のプロジェクト等により独自に提供されているものもあります。Trove からも、Trove の機能を追加するための専用 elements が提供されています。これは、以下のコマンドにてダウンロードできます。

$ git clone https://opendev.org/openstack/trove.git -b stable/queens

ダウンロードされたディレクトリ配下の integration/scripts/files/elements/ に、Trove 用の elements が格納されています。このうちいくつかの elements の使用効果についても紹介します。

  • ubuntu-xenial-mysql : Ubuntu (xenialバージョン) 上に、Trove で機能提供するための、MySQL データベースサーバーを導入します

  • ubuntu-xenial-guest : Ubuntu (xenialバージョン) 上に、Trove guest agent を導入します
    ※この element では、Trove 仮想マシンインスタンス起動時に、OpenStack のコントローラーノードから Trove guest agent ファイルを取得してくる動作となるため、あらかじめコンロトーラーノード上に Trove guest agent ファイルを用意しておく必要があります。ファイルの配置場所は任意ですが、別途配置場所を指定する必要があります。詳細については、のちほど 「Trove のイメージ作成」にて示します。Trove guest agent ファイルは、先ほど Trove 専用 elements のダウンロードで取得したのと同一のもので、そのトップディレクトリ (trove/) からの全ファイルになります。

実行フェーズ

DIB により、フェーズごとに以下の順で elements のコードが実行されます。

  • root.d
  • extra-data.d
  • pre-install.d
  • install.d
  • post-install.d
  • block-device.d
  • finalise.d
  • cleanup.d

また、

  • environment.d

を使って環境変数を設定する elements もあります。

たとえば、DIB 標準提供の ubuntu element のディレクトリ配下には、以下のファイルが含まれているため、

environment.d/99-cloud-init-datasources.bash
install.d/99-autoremove
pre-install.d/00-remove-apt-xapian-index
pre-install.d/00-remove-grub
pre-install.d/01-set-ubuntu-mirror
root.d/10-cache-ubuntu-tarball

これらのコードは、他の同時に指定される elements や依存関係にある elements のコードとともに、以下の順番で実行されていくことになります。

  • root.d フェーズ
    (1) environment.d/99-cloud-init-datasources.bash
    (2) root.d/10-cache-ubuntu-tarball
  • pre-install.d フェーズ
    (1) environment.d/99-cloud-init-datasources.bash
    (2) pre-install.d/00-remove-apt-xapian-index
    (3) pre-install.d/00-remove-grub
    (4) pre-install.d/01-set-ubuntu-mirror
  • install.d フェーズ
    (1) environment.d/99-cloud-init-datasources.bash
    (2) install.d/99-autoremove

DIB によるイメージのビルドがうまくいかなかったときは、この実行順を念頭に調査することになります。

elements の使用する環境変数

DIB では elements を組み合わせて目的のディスクイメージを作成しますが、単純に使用したい elements を指定するだけでは細かい条件が合っていないことがあります。たとえば、DIB 標準提供 element である ubuntu は OS として Ubuntu を導入するものですが、デフォルトでは意図しないバージョンの Ubuntu を使用しようとするかもしれません。そこで、DIB では環境変数を使って、条件に合うように、elements に細かな指定を与えることになります。

elements ごとの環境変数の使い方については、各 elements ディレクトリ中の README ファイルで説明されていることもありますが、README ファイルが無い場合もあり、また、実際に使うには情報が不十分なこともあるため、elements のコードを直接確認したほうが確実です。

ubuntu element のコード ubuntu/root.d/10-cache-ubuntu-tarball を見ると、

...
DIB_RELEASE=${DIB_RELEASE:-trusty}
DIB_CLOUD_IMAGES=${DIB_CLOUD_IMAGES:-http://cloud-images.ubuntu.com/$DIB_RELEASE/current}
if [ $DIB_RELEASE != "trusty" ] && [ $DIB_RELEASE != "xenial" ]; then
    BASE_IMAGE_FILE=${BASE_IMAGE_FILE:-$DIB_RELEASE-server-cloudimg-$ARCH.squashfs}
else
    BASE_IMAGE_FILE=${BASE_IMAGE_FILE:-$DIB_RELEASE-server-cloudimg-$ARCH-root.tar.gz}
fi
...
function get_ubuntu_tarball() {
...
        echo "Fetching Base Image"
        $TMP_HOOKS_PATH/bin/cache-url $SHA256SUMS $CACHED_SUMS
        $TMP_HOOKS_PATH/bin/cache-url \
            $DIB_CLOUD_IMAGES/$BASE_IMAGE_FILE $CACHED_FILE
...
    # Extract the base image (use --numeric-owner to avoid UID/GID mismatch between
    # image tarball and host OS e.g. when building Ubuntu image on an openSUSE host)
    if [ $DIB_RELEASE != "trusty" ] && [ $DIB_RELEASE != "xenial" ]; then
        sudo unsquashfs -f -d $TARGET_ROOT $DIB_IMAGE_CACHE/$BASE_IMAGE_FILE
    else
        sudo tar -C $TARGET_ROOT --numeric-owner -xzf $DIB_IMAGE_CACHE/$BASE_IMAGE_FILE
    fi
}
...

というコードになっており、また、ubuntu element が依存している ubuntu-common element のコード ubuntu-common/environment.d/10-ubuntu-distro-name.bash は、

export DISTRO_NAME=${DISTRO_NAME:-ubuntu}
export DIB_RELEASE=${DIB_RELEASE:-bionic}
export DIB_DEBIAN_COMPONENTS=${DIB_DEBIAN_COMPONENTS:-main,universe}

# There are two default distro mirrors depending on architecture
ARCH=${ARCH:-}
if [[ "arm64 armhf powerpc ppc64el s390x" =~ "$ARCH" ]]; then
    default_ubuntu_mirror=http://ports.ubuntu.com/ubuntu-ports
else
    default_ubuntu_mirror=http://archive.ubuntu.com/ubuntu
fi

export DIB_DISTRIBUTION_MIRROR=${DIB_DISTRIBUTION_MIRROR:-$default_ubuntu_mirror}

となっているため、デフォルトでは導入する Ubuntu バージョンは
DIB_RELEASE=bionic
が選ばれ、また取得ファイルが
DIB_CLOUD_IMAGES=http://cloud-images.ubuntu.com/bionic/current
にある
BASE_IMAGE_FILE=bionic-server-cloudimg-amd64.squashfs
となることがわかります。

しかし、今回 Trove イメージを作成するために、Ubuntu (xenial バージョン) を使用する必要があるため、バージョンが合わないことになります。 そこで、こういったバージョンのような細かい指定をするために、上記の決められた環境変数を定義することになります。

――― では、どのように設定すればよいでしょうか。

まず、Ubuntu のバージョンを合わせるために、export DIB_RELEASE=xenial をあらかじめ自分で定義しておくこととします。すると、ファイルの取得先は
DIB_CLOUD_IMAGES=http://cloud-images.ubuntu.com/xenial/current

BASE_IMAGE_FILE=xenial-server-cloudimg-amd64-root.tar.gz
となります。

しかし、この URL の示すファイルはあまり都合がよくありません。xenial バージョンのファイルのうち、current ファイルを指しているため、最新のビルドファイルに置き換えられていきます。 ここでは安全のため、固定のビルドバージョンのファイルを指定するように定義を変更します。

たとえば http://cloud-images.ubuntu.com/releases/xenial/release-20200129 にあるファイルが、以下のように xenial 中の固定ビルドバージョンのファイルとなっているようです。

Icon  Name                                                   Last modified      Size  Description
[DIR] Parent Directory                                                            -   
[   ] MD5SUMS                                                29-Jan-2020 17:43  4.1K  
[   ] MD5SUMS.gpg                                            29-Jan-2020 17:43  836   
[   ] SHA1SUMS                                               29-Jan-2020 17:43  4.5K  
[   ] SHA1SUMS.gpg                                           29-Jan-2020 17:43  836   
[   ] SHA256SUMS                                             29-Jan-2020 17:43  5.8K  
[   ] SHA256SUMS.gpg                                         29-Jan-2020 17:43  836   
[TXT] ubuntu-16.04-server-cloudimg-amd64-azure.vhd.manifest  29-Jan-2020 08:51   16K  Ubuntu Server 16.04 LTS (Xenial Xerus) released builds
...
[   ] ubuntu-16.04-server-cloudimg-amd64-root.tar.gz         29-Jan-2020 08:53  196M  Cloud image for 64-bit computers (compressed tar file of /)
...
[   ] ubuntu-16.04-server-cloudimg-amd64.squashfs            29-Jan-2020 08:53  159M  Ubuntu Server 16.04 LTS (Xenial Xerus) released builds
...

先ほどの URL のファイル名と比べ、接頭語が、

xenial-server-cloudimg-amd64 ~

ubuntu-16.04-server-cloudimg-amd64 ~

と変化していることに注意し、環境変数を

export DIB_RELEASE=ubuntu-16.04
export DIB_CLOUD_IMAGES=http://cloud-images.ubuntu.com/releases/xenial/release-20200129

と定義しなおせば、ファイル名も
BASE_IMAGE_FILE=ubuntu-16.04-server-cloudimg-amd64.squashfs
となり、目的のファイルをダウンロードできるようになります。

このようにして、環境変数を利用して、elements の動作を細かく変える必要がある場合があります。

Trove のイメージ作成

DIB を使用して、Trove のイメージを作成します。

elements は、以下のものを使用します。

  • ubuntu [DIB 標準提供] : OS のイメージとして Ubuntu を使用
  • vm [DIB 標準提供] : ディスクイメージにパーティションを作成
  • cloud-init-datasources [DIB 標準提供] : 起動高速化のため、特定のデータソースのみを参照するよう cloud-init を設定
  • ubuntu-xenial-guest [Trove] : Ubuntu (xenialバージョン) 上に、Trove guest agent を導入
  • ubuntu-xenial-mysql [Trove] : Ubuntu (xenialバージョン) 上に、Trove で機能提供するための、MySQL データベースサーバーを導入

環境変数の設定と DIB コマンドの実行をまとめた、以下のような内容のシェルスクリプトを用意して、実行します。

export CONTROLLER_IP=XX.XX.XX.XX
export HOST_SCP_USERNAME=troveimage
export PATH_TROVE=/home/troveimage/queens/trove
export ESCAPED_PATH_TROVE=`echo $PATH_TROVE | sed 's|/|\\\/|g'`

export RELEASE=xenial
export DIB_RELEASE=ubuntu-16.04
export DIB_CLOUD_IMAGES=http://cloud-images.ubuntu.com/releases/xenial/release-20200129

export HOST_USERNAME=root
export TROVESTACK_SCRIPTS=/XXXXXXXXXXXX/integration/scripts
export SSH_DIR=$TROVESTACK_SCRIPTS/files/keys

export DIB_CLOUD_INIT_DATASOURCES="ConfigDrive"
export GUEST_USERNAME=XXXXXXXX
export ELEMENTS_PATH=$TROVESTACK_SCRIPTS/files/elements
export ELEMENTS_PATH+=:/XXXXXXXXXXXX/diskimage_builder/elements/

export DEST=/XXXXXXXXX/UC
export GUEST_LOGDIR=/var/log/trove
export ESCAPED_GUEST_LOGDIR=`echo $GUEST_LOGDIR | sed 's|/|\\\/|g'`
export DIB_CLOUD_INIT_ETC_HOSTS=true

disk-image-create -a amd64 -o ImageName ubuntu vm \
  cloud-init-datasources ubuntu-xenial-guest ubuntu-xenial-mysql
  • CONTROLLER_IP は、Trove インスタンスから Trove guest agent ファイルなどを取得しに行くコントローラーノードの IP アドレスを指定します。必要があれば、経路上のファイアーウォールなどの設定も修正しておきます。

  • HOST_SCP_USERNAME は、Trove インスタンスから Trove guest agent ファイルなどを取得しに行くコントローラーノードのアカウントを設定します。

  • ESCAPED_PATH_TROVE は、コントローラーノード上の Trove guest agent ファイル格納ディレクトリを設定します。

  • TROVESTACK_SCRIPTS は、イメージビルド用サーバー上にダウンロードしてきた Trove elements ファイル中の、integration/scripts ディレクトリを指すようにします。

  • GUEST_USERNAME は、Trove インスタンスに作成されるユーザー名を指定します。

  • ELEMENTS_PATH には、イメージビルド用サーバー上の、必要な elements の格納されているディレクトリを指定しています。

  • DEST は、Trove guest agent コードに必要なその他の python パッケージのバージョンを OpenStack 本体側と合わせるため、各パッケージのバージョンを指定した requirements/upper-constraints.txt ファイルを格納した、イメージビルド用サーバー上のディレクトリを指定しています。※バージョンが合っていないと動作に不具合が生じます。

upper-constraints.txt ファイルは、Trove を導入したコントローラーノードにて以下のコマンドで作成できます。pip が無い場合はあらかじめ導入しましょう。

$ pip freeze > upper-constraints.txt

スクリプトを実行し、イメージのビルドを開始すると、実行時のログが画面に大量に表示されていきます。ビルドに問題があった場合の解析に利用するため、ログを取っておいた方がよいでしょう。

2020-12-16 04:10:18.008 | diskimage-builder version 2.33.0                      
2020-12-16 04:10:18.009 | Building elements: base ubuntu vm cloud-init-datasources ubuntu-xenial-guest ubuntu-xenial-mysql block-device-mbr                     
...
(中略)
...
2020-12-16 04:29:01.083 | Converting image using qemu-img convert               
2020-12-16 04:30:47.708 | Image file trove-ubuntu-xenial-mysql-tmp.qcow2 created...                                                                             
2020-12-16 04:30:48.174 | Build completed successfully                          

環境にもよりますが、初回ビルド時には数十分程度の時間が掛かります。1 回ビルドすると、~/.cache/ にキャッシュされるファイルができて、少し早くなるようです。ビルドが成功すると、上記のように Build completed successfully の出力で終わります。

ビルドできたイメージは、Trove 導入入門編の「Trove 導入から利用までの流れ - 初期導入の例 - ・管理者作業 - 3. データストアと起動イメージを Trove に登録」などで使用します。

また、以下のようにビルドが失敗した場合は、出力されたログを見て解析します。

...
2020-12-16 04:09:22.271 | Fetched 54.3 MB in 2min 39s (340 kB/s)                
2020-12-16 04:09:22.271 | E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/s/snapd/snapd_2.48_amd64.deb  502  cannotconnect                        
2020-12-16 04:09:22.271 |                                                       
2020-12-16 04:09:22.271 | E: Unable to fetch some archives, maybe run apt-get up
date or try with --fix-missing?                                                 
2020-12-16 04:09:22.293 | Unmount /tmp/dib_build.EDr0UEHM/mnt/var/cache/apt/archives                                                                            
2020-12-16 04:09:22.312 | Unmount /tmp/dib_build.EDr0UEHM/mnt/tmp/in_target.d   
2020-12-16 04:09:22.330 | Unmount /tmp/dib_build.EDr0UEHM/mnt/sys               
2020-12-16 04:09:22.346 | Unmount /tmp/dib_build.EDr0UEHM/mnt/proc              
2020-12-16 04:09:22.360 | Unmount /tmp/dib_build.EDr0UEHM/mnt/dev/pts           
2020-12-16 04:09:22.376 | Unmount /tmp/dib_build.EDr0UEHM/mnt/dev               
2020-12-16 04:09:22.723 | INFO diskimage_builder.block_device.blockdevice [-] State already cleaned - no way to do anything here                                

ビルドエラーの中には、いくつか分かっている簡単な解決方法をもつものもあります。

  • Ubuntu のリポジトリサーバーなどの遅延でファイル取得に失敗している場合、何回かビルドし直すと成功する場合があるようです。どうしてもだめなら、取得先のサーバーを差し替えるための apt-sources elements などを使用する方法もあります。

  • sudo コマンドがタイムアウトしているログが出た場合は、該当 element コード中の sudo ~sudo -h localhost ~ と置き換えると、改善されるようです。

次回予告

次回は、Trove のイメージ作成・登録後に問題が発生した場合の解析について説明します。


TOP
アルファロゴ 株式会社アルファシステムズは、ITサービス事業を展開しています。このブログでは、技術的な取り組みを紹介しています。X(旧Twitter)で更新通知をしています。