Rook Test Framework の実行環境の構築とテストの実施

この投稿は「Rookと仲間たち、クラウドネイティブなストレージの Advent Calendar 2020 - Qiita」の 2 日目の記事です。 レッドハットでコンサルタントをしている金子です。Rook Test Framework を実行する環境の構築とテストの実施について記載します。

Advent Calendar は始まったばかりですが、他の投稿記事は以下から参照できます。ぜひ御覧ください。

qiita.com

Rook Test Framework とは

公式のドキュメントに次の通り記載されていますが、Rook のコンテナイメージを実際にビルドし、エンドツーエンドのテストを実施するためのフレームワークが提供として提供されています。

The Rook Test Framework is used to run end to end and integration tests on Rook. The framework depends on a running instance of Kubernetes. The framework also provides scripts for starting Kubernetes using kubeadm or minikube so users can quickly spin up a Kubernetes cluster.The Test framework is designed to install Rook, run tests, and uninstall Rook.

テストには Kubernetes の環境が必要なため、kubeadmminikube を利用して環境を構築した上で、予めビルドした Rook イメージに対してテストを実施します。今後、Rook を利用した際に見つけた不具合などを修正するなどのコミュニティ活動を行う上で参考にしていただければと思います。

環境概要

テスト要件は次のとおりとなります。実行環境は Ubuntu 18 となります。テスト用のストレージデバイスの準備のしやすさなどから、今回は VirtualBox 上に環境を構築しテストを実行します。

Package Version 備考
Docker 1.2 && < 17.0 docker 以外を利用する場合は、環境変数 DOCKERCMD にコマンドラインツールを指定してください
Ubuntu 18 現在のテストは本バージョンのみで動作確認が行われています。
kernel >= 4.15 -
Kubernetes with kubectl >= 1.15 新しいバージョンの環境でテストを実施したい場合は、環境変数 KUBE_VERSION にバージョンを指定してください。例:KUBE_VERSION=v1.19.0
Rook - 事前にビルドする必要があります。

環境準備

VirtualBox 環境の準備

今回作成した環境では VirtualBoxvagrant を利用します。インストールは予め済ませておいてください。vagrant init で作成するデフォルトの VM ではディスクサイズが小さいためルートボリュームのサイズを少し増やしておきます。 利用した Vagrantfile は次のとおりです。ルートボリュームを拡張するため、事前に vagrant には以下のコマンドでプラグインをインストールしておきます。

$ vagrant plugin install vagrant-disksize

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.provider "virtualbox" do |v|
    v.name = "rook"
  end

  config.vm.box = "ubuntu/bionic64"
  config.disksize.size = '200GB'
end

一度 VM を作成した後、ストレージデバイスをアタッチするため停止します。

$ vagrant init
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu/bionic64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'ubuntu/bionic64' version '20201014.0.0' is up to date...
==> default: A newer version of the box 'ubuntu/bionic64' for provider 'virtualbox' is
==> default: available! You currently have version '20201014.0.0'. The latest is version

...

    default: your host and reload your VM.
    default:
    default: Guest Additions Version: 5.2.42
    default: VirtualBox Version: 6.1
==> default: Mounting shared folders...
    default: /vagrant => /home/cloud-user/virtualbox/rook
$ vagrant halt
==> default: Attempting graceful shutdown of VM...

テスト実行中に利用するデバイスを作成した VM にアタッチします。ディスクサイズは 5GB ほどあれば十分なようですが念の為多めに 20GB 用意します。 ゲストOSからは、デバイスは /dev/sdb として参照できるようになります。 また、CPUやメモリリソースに余裕がある場合は、テスト実行時間を短縮するためリソースを拡張しておきます。

$ vboxmanage createhd --filename extra_disk.vdi --size 200000 --format VDI
$ vboxmanage storageattach rook --storagectl "SCSI" --device 0 --port 2 --type hdd --medium extra_disk.vdi
$ vboxmanage modifyvm rook2 --cpus 4 --memory 8096

デバイスが VM にアタッチできていることを確認します。先程作成したデバイスが SCSI (2,0) としてアタッチされていることが確認できます。

$ vboxmanage showvminfo rook | grep SCSI
Storage Controller Name (1):            SCSI
SCSI (0, 0): /home/cloud-user/VirtualBox VMs/rook/ubuntu-bionic-18.04-cloudimg.vdi (UUID: 864cc634-ac60-48e6-9d1e-22dec83ef55e)
SCSI (1, 0): /home/cloud-user/VirtualBox VMs/rook/ubuntu-bionic-18.04-cloudimg-configdrive.vmdk (UUID: 5ea3cce8-1695-4074-9859-98b8485fff8a)
SCSI (2, 0): /home/cloud-user/virtualbox/rook/extra_disk.vdi (UUID: e1a7d106-4363-4f59-847e-08f6706e2b0c)

VM  を起動し、VM上で環境構築を継続します。

$ vagrant up
$ vagrant ssh

パッケージのインストール

Rook のイメージのビルド、Kubernetes 上でのテスト実施のために、以下のパッケージをインストールします。

  • docker-ce
  • make
  • go

make のインストール

# apt-get install -y install build-essential

docker, go のインストールについては、ドキュメントを参照してください。

Rook ビルド環境の準備

Rook リポジトリを clone します。GOPATH の関係などから、$HOME/go/src/github.com/rook/に clone します。

# mkdir -p $HOME/go/src/github.com/rook
# export GOPATH=$HOME/go
# cd $HOME/go/src/github.com/rook
# git clone https://github.com/rook/rook.git

ひとまず、テストを実施するのみなので master ブランチで作業を行います。

Rook イメージのビルド

ドキュメント に従い、ビルドを実行します。

# cd $HOME/go/src/github.com/rook/rook
# make -j4

実行が完了すると最後に以下のようなメッセージが出力されることを確認してください。

...
Congratulations!
Your Rook CSV 9999.9999.9999 manifest for k8s is ready at: cluster/olm/ceph/deploy/olm-catalog/k8s/9999.9999.9999/manifests
Push it to https://github.com/operator-framework/community-operators as well as the CRDs from the same folder and the package file cluster/olm/ceph/assemble/rook-ceph.package.yaml.
Template stored at cluster/olm/ceph/templates/rook-ceph-k8s.vVERSION.clusterserviceversion.yaml.in
=== container build build-a7ad6610/ceph-amd64
sha256:3d0c8ef6a1b96d36259cd98de569a9563612a3907352e9568159a10b7764e690
sha256:5d54aa21ff9fca46acacf22b4b605282be4e5c81cbed8e8799b7f047b4ef1a94
=== saving image build-a7ad6610/edgefs-amd64
=== container build build-a7ad6610/yugabytedb-amd64
sha256:adfc420992ca25c37b667c0f66b664c0c658403749386e4e3a8c3a9a716ee01d
sha256:14c0204aa0f71566ac6a7efc06f0045034e9bc3158c7c90d4104362d37692e5c
sha256:5a593be97f73071649d42175479c432af82ef7d08823dd26a552dd60a7e8bcea
=== saving image build-a7ad6610/nfs-amd64

Rook Test Framework を使ったインテグレーションテストの実行

環境がクリーンであるか確認

準備が整ったため、テストを実施します。実施前に環境がクリーンであるか確認します。確認方法は rook のドキュメント をベースにチェックします。 確認の概要としては、Kubernetes がクリーンな状態であるかどうか、Rook が利用するデバイス(本環境では /dev/sdb) が 0x00 で初期化されていることの確認をします。

Kubernetes 環境はまだ立ち上げていないため、これから準備する環境はクリーンではありますが、ディスクを確認しておきます。次のコマンドを実行し、デバイスが 0x00 で初期化されていることを確認してください。

# xxd -l 128 /dev/sdb
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................

万が一、ディスクが初期化されていない場合は、Rook メンテナーである satoru-takeuchi さんのリポジトリにある ci-fini.sh を参考に、ディスクを初期化します。 デバイスは環境に合わせて変更してください。本記事に従った場合は /dev/sdb が対象のデバイスとなっているはずです。

# export TEST_SCRATCH_DEVICE=/dev/sdb 
# vgremove --yes --force rook-integration-test-vg
# pvremove --yes --force ${TEST_SCRATCH_DEVICE}
# dd if=/dev/zero of=${TEST_SCRATCH_DEVICE} bs=1M count=100 oflag=dsync,direct

kubeadm を利用した環境の準備

エンドツーエンドの実行環境を構築します。

# tests/scripts/kubeadm.sh up
# export KUBECONFIG=~/admin.conf
# tests/scripts/helm.sh up

環境に正常にアクセスできることを確認します。Node の Status が Ready となっていること、Kubernetes のバージョンが取得できていることを確認します。

# kubectl get node
NAME            STATUS   ROLES    AGE    VERSION
ubuntu-bionic   Ready    master   112s   v1.15.12
# kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-11T13:17:17Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.12", GitCommit:"e2a822d9f3c2fdb5c9bfbe64313cf9f657f0a725", GitTreeState:"clean", BuildDate:"2020-05-06T05:09:48Z", GoVersion:"go1.12.17", Compiler:"gc", Platform:"linux/amd64"}

テスト実施に必要な環境変数を設定します。

# export TEST_HELM_PATH=/tmp/rook-tests-scripts-helm/linux-amd64/helm
# export TEST_BASE_DIR=/tmp/rook-integration
# export TEST_SCRATCH_DEVICE=/dev/sdb
# mkdir -p $TEST_BASE_DIR

テストの実行

すべてのテストを最初から実行すると、環境が正しく出来ているかわからないため、一部のテストを実行して確認します。ドキュメントにある TestARookClusterInstallation_SmokeTest を実行します。

# go test -v -timeout 1800s -run CephSmokeSuite github.com/rook/rook/tests/integration -testify.m TestARookClusterInstallation_SmokeTest

以下のように出力されれば準備完了です。

...
2020-11-29 13:53:34.086285 I | installer: verifying clean up of /tmp/rook-integration/rook-test from node ubuntu-bionic. err=<nil>
2020-11-29 13:53:34.088708 I | installer: system namespace "smoke-ns-system" still found...
2020-11-29 13:53:39.092630 I | installer: system namespace "smoke-ns-system" still found...
2020-11-29 13:53:44.096048 I | installer: system namespace "smoke-ns-system" still found...
2020-11-29 13:53:49.395553 I | installer: system namespace "smoke-ns-system" removed
--- PASS: TestCephSmokeSuite (184.87s)
    --- PASS: TestCephSmokeSuite/TestARookClusterInstallation_SmokeTest (5.09s)
PASS
ok      github.com/rook/rook/tests/integration  184.900s

準備が出来ていますので、テストを実行しましょう。

# go test -v -timeout 7200s github.com/rook/rook/tests/integration

まとめ

実行環境は準備できたでしょうか。テスト環境を構築できれば、今後 Rook に対してなにか修正を提供する機会があったときにテストが実行できるためコミュニティ活動がやりやすくなるかと思います。 実際に修正を提供する場合には、コミットメッセージを含めてコミュニティのルールが存在するため、以下のドキュメントを予め参照してから修正するとスムーズかと思います。

github.com

参考ですが、Rook リポジトリへ Pull Request を作成するときにチェックすべきチェックリストは次のとおりです。 事前に以下のドキュメントには目を通しておけば、チェックリストには回答できるかと思います。

Checklist:

- Commit Message Formatting: Commit titles and messages follow guidelines in the developer guide.
- Skip Tests for Docs: Add the flag for skipping the build if this is only a documentation change. See here for the flag.
- Skip Unrelated Tests: Add a flag to run tests for a specific storage provider. See test options.
- Reviewed the developer guide on Submitting a Pull Request
- Documentation has been updated, if necessary.
- Unit tests have been added, if necessary.
- Integration tests have been added, if necessary.
- Pending release notes updated with breaking and/or notable changes, if necessary.
- Upgrade from previous release is tested and upgrade user guide is updated, if necessary.
- Code generation (make codegen) has been run to update object specifications, if necessary.

注意事項

Rook Test Framework はテスト実施後に環境をクリーンにするための処理も実装されていますが、発生した異常によってはクリーンにならないこともあるようです。例えば、テスト実施時に設定したタイムアウト時間を超えてしまった場合は強制的にテストが終了してしまうため、終了処理が実施されません。その場合は、環境構築時に実施したディスクを初期化するコマンドと、Kubernetes を再作成することをおすすめします。

Kubernetes の初期化はコマンドが用意されており、以下を実行するのみとなります。

# tests/scripts/kubeadm.sh clean

再度テストを実施する場合は、tests/scripts/kubeadm.sh up の手順から実施することでクリーンな環境でテストを行うことが出来ます。

参考

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。