こんにちは、Necoチームの鈴木です。
Necoチームでは仮想データセンター構築ツールPlacematを使って、データセンターを丸ごと仮想化し、その上でサーバーのプロビジョニングやKubernetesクラスタ構築、Kubernetes上で動作するアプリケーションのTest Suitesを実行しています。Placematはプロジェクト初期に開発されたツールで、古いツールに依存していたり、実装方式や設計が洗練されていないなどの課題があっため、4ヶ月前からv2を開発開始し、先日リリースしました。本記事ではその機能と使い方、今後のCI改善 Placemat on Kubernetesについて紹介します。
Placematはシングルバイナリで構成されています。使い方もシンプルで、インストールしたバイナリにYAMLの設定ファイルを渡して起動すると、設定に従ってネットワークを構成してVMを起動、終了時にはそれらをクリーンアップします。CIで自動テストを実行するための環境作りがとても楽になります。aptで依存ライブラリをインストール、debパッケージでPlacematをインストールして起動すれば完了です。
下記のリソースをYAMLファイルに定義して組み合わせることで、様々な構成の仮想データセンターを構築することができます。
1:Networkリソースを定義することで、Bridgeネットワークを作成します。VMやスイッチを相互に接続できます。
kind: Networkname: my-nettype: externaluse-nat:trueaddress: 10.0.0.0/22
2:NetworkNamespaceリソースを定義することで、独立したネットワーク領域を作成します。Network Namespace内でbirdなどのアプリケーションを実行することでスイッチの機能をエミュレーションすることができます。
kind: NetworkNamespacename: my-netnsinit-scripts: - /path/to/scriptinterfaces: - network: net0 addresses: - 10.0.0.1/24apps: - name: bird command: - /usr/local/bird/sbin/bird - -f - -c - /etc/bird/bird_core.conf
3:Nodeリソースを定義することでQEMUでVMを起動することができます。後述しますが多彩な設定が可能になっています。
kind: Nodename: my-nodeinterfaces: - net0volumes: - kind: image name: root image: image-name copy-on-write: true - kind: localds name: seed user-data: user-data.yml network-config: network.yml - kind: raw name: data size: 10G - kind: hostPath name: host-data path: /var/lib/foo writable: falseignition: my-node.igncpu: 2memory: 4Gsmbios: manufacturer: cybozu product: mk2 serial: 1234abcduefi: falsetpm: true
4:Imageリソースでサーバーの起動ディスクイメージを定義できます。URLを指定してPlacematにダウンロードさせることもできますし、ローカルに保存済みのイメージファイルのパスを指定することもできます。
kind: Imagename: ubuntu-cloud-imageurl: https://cloud-images.ubuntu.com/releases/16.04/release/ubuntu-16.04-server-cloudimg-amd64-disk1.img
Necoチームでは以下の構成の仮想データセンターを構築して自動テストに使っています。

Nodeリソースは以下のような多彩なVMの設定が可能で、様々なユースケースに対応可能です。
hostPathvolumeを指定することで、virtio-9p-deviceを使ったホスト/ゲスト間のファイル共有が可能です。cloud-initやignitionでvolumeをmountすれば、テストに必要なファイルをホストから渡すこともできます。こちらのExampleを使ってPlacematを実際に動かす方法を紹介します。動作環境はUbuntu 18.04/20.04になります。VMで動かす場合にはNested Virtualizationを有効にする必要があります。
ここでは以下のようなBootサーバー1台、Workerサーバー2台のClusterを構築していきます。

使用する設定ファイルは以下になります。
kind: Networkname: net0type: externaluse-nat:trueaddress: 172.16.0.1/24---kind: Networkname: bmctype: bmcuse-nat:falseaddress: 172.16.1.1/24---kind: Imagename: ubuntu-imageurl: https://cloud-images.ubuntu.com/releases/20.04/release/ubuntu-20.04-server-cloudimg-amd64.img---kind: Nodename: bootinterfaces:-net0volumes:-kind: imagename: rootimage: ubuntu-image-kind: localdsname: seeduser-data: user-data.example.ymlnetwork-config: network-config.example.ymlcpu:1memory: 2G---kind: Nodename: worker-1interfaces:-net0volumes:-kind: rawname: datasize: 10Gcpu:1memory: 2Gsmbios:serial: 1234abcduefi:false---kind: Nodename: worker-2interfaces:-net0volumes:-kind: rawname: datasize: 10Gcpu:1memory: 2Gsmbios:serial: 5678efghuefi:false
以下のコマンドを実行して依存packageとPlacematをインストールします。
# 依存packageをインストール$ sudo apt-get update$ sudo apt-get -y install --no-install-recommends qemu qemu-kvm socat picocom cloud-utils freeipmi-tools# Placematをインストール$ curl -O -sfL https://github.com/cybozu-go/placemat/releases/download/v2.0.4/placemat2_2.0.4_amd64.deb$ sudo dpkg -i ./placemat2_2.0.4_amd64.deb
以下のコマンドを実行してplacematリポジトリをcloneし、exampleのclusterを構築します。
$ git clone https://github.com/cybozu-go/placemat.git$ cd placemat/examples$ sudo placemat2 --data-dir ./data --cache-dir ./cache ./cluster.example.yml
以下のログが表示されていれば起動成功です。
placemat2 info: "Start Placemat API server" address="127.0.0.1:10808"
Placematを起動したコンソールとは別のコンソールを開き、以下のコマンドでnode(VM)の一覧を確認します。
$ pmctl2 node listbootworker-1worker-2
続いてbootサーバーにログインします。
$ sudo pmctl2 node enter boot# ユーザー: ubuntu, パスワード: ubuntu でログインできます。# ターミナルを終了する時は、Ctrl-qとCtrl-xを続けて押してください。
worker-1にもログインしてみます。bootサーバーからOSイメージをダウンロードしてセットアップを終えるとログインできるようになります。環境によっては時間がかかる場合があります。
# worker-1にログイン$ sudo pmctl2 node enter worker-1# ターミナルを終了する時は、Ctrl-qとCtrl-xを続けて押してください。
次にBMCサーバーを起動して、IPMI、Redfishを使ってVMを再起動してみます。ここではworker-1のBMCを起動して再起動してみたいと思います。
$ sudo pmctl2 node enter worker-1$ echo 172.16.1.2 | sudo dd of=/dev/virtio-ports/placemat# ターミナルを終了する時は、Ctrl-qとCtrl-xを続けて押してください。
PlacematはVMの/dev/virtio-ports/placematにcharデバイスを設定して、BMCアドレスが通知されるのを待機しています。アドレスが通知されると以下のようなログを出力してBMCサーバーを起動します。
placemat2 info: "creating BMC port" bmc_address="172.16.1.2" serial="1234abcd"placemat2 info: "BMC USer: Add user" user="cybozu"
ipmipowerコマンドを使ってworker-1の電源状態を取得してみます。
$ ipmipower --stat -u cybozu -p cybozu -h 172.16.1.2 -D LAN_2_0172.16.1.2: on
続いてRedfishを使って電源状態を取得します。
$ curl -sku cybozu:cybozu https://172.16.1.2/redfish/v1/Systems/System.Embedded.1 | jq .PowerState"On"
ipmipowerコマンドでworker-1を再起動します。
$ ipmipower --reset -u cybozu -p cybozu -h 172.16.1.2 -D LAN_2_0172.16.1.2: ok
worker-1のコンソールに入ると再起動してネットワークブートしている様子が確認できます。
$ sudo pmctl2 node enter worker-1# ターミナルを終了する時は、Ctrl-qとCtrl-xを続けて押してください。
Redfishを使う場合はこちらのコマンドで再起動できます。
$ curl -X POST -H "Content-Type: application/json" -d '{"ResetType":"ForceRestart"}' -sku cybozu:cybozu https://172.16.1.2/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.ResetPlacematを起動したコンソールでCtrl-cを押します。作成したBridgeやNetwork Namespaceなどをクリーンアップして終了します。
最近ではRook/CephやMySQL Operator MOCOなど重量級のアプリケーションが稼働を始めたことなどもあって、CIの不安定さや遅さが問題になることが増えてきました。
これらの課題を解決するために、PlacematをKubernetes上で動かしてCIを回すことを計画しています。

Self-hosted runnerをKubernetes Clusterで管理するためのOperatorを絶賛開発中です。こちらのOperatorが完成したら、KubernetesのPod内に構築された仮想データセンターでワークフローを実行するように、CI環境の移行を進めていく予定です。事前のPoCではCIの高速化が期待できる結果が出ているため、大幅なCI改善を見込んでいます。
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。