ujunのブログ

lava-dockerのPostgreSQLを捨てて Amazon Aurora Serverless を使えるように改造する

IoT的なネタと見せかけてただの魔改造を。。

目次

LAVAとは

Introduction to LAVA — LAVA 2020.04 documentation

LAVAはいろんな物理ボードとかQEMUとかでカーネルをブートしてテストするためのツール。LinuxカーネルAndroidカーネルのパフォーマンス測定とか電力消費のモニタリング用途とかで使われることもあるそう。

なお、LAVA自身はテストスイートでもビルドファームでもなくて、どこかでビルドしたカーネルをダウンロードしてターゲットボードにデプロイしてテストを流すことができるくん なので、カーネルのビルドは自分でどこかでやっておく必要がある。例えばJenkinsと組み合わせてCIパイプラインを構築するための構成要素というのが実践的な使い方になる。

LAVAのアーキテクチャ

ざっくり以下の公式の図みたいな感じで、Master/Workerから構成されていて、Workerをスケールさせれば大量のターゲットボードに対して実行することができるようになる。

_images/arch-overview.svg

図をみると、LAVAのデータストア(PostgreSQLです)はMasterノードからのみアクセスされ、しかもMasterノードのローカルにある。公式のインストール手順でもlava-dockerプロジェクト(https://github.com/kernelci/lava-docker)でも、Masterと同ノードあるいは同コンテナにPostgreSQLがインストールされることになる。また、ガイド(https://docs.lavasoftware.org/lava/first-installation.html) によれば以下のように書かれており、やっぱりMasterノードとPostgreSQLは抱き合わせ前提のようだ。

Database - This uses PostgreSQL locally on the master, with no external access.

基本的には可用性とか拡張性がそこまで強く求められるシステムでもないと思うので、これはこれでライトに使えるという点でいいのかもしれないけど、こういうのは外部データストアの可能性も考えたくなるものなので。。

ワークロード的に常時稼働でないこういうDev系のシステムには、Aurora Serverlessが選択肢としてあり得る、と思うけど実際どうなんだろう。とりあえずそこにDBの役割をオフロードすることを考える。PostgreSQL互換もサポートされていることだし。もちろん自前のPostgreSQLサーバとかprovisionedタイプのRDSとか、実際はなんでもイイ。

lava-dockerのインストール

VPC内にEC2インスタンスを立てる。
lava-dockerで導入するのがシンプルなので、手順(https://github.com/kernelci/lava-docker#quickstart)に従って、以下を実行する。

$ git clone https://github.com/kernelci/lava-docker.git
$ cd lava-docker
$ ./lavalab-gen.py

lavalab-gen.py を実行すると、output/local というディレクトリが生成されて、配下にdocker-compose用のファイルがいくつか生成されている。
例えばmasterのほうは以下のようなファイル構成となる。

master1
    ├── Dockerfile
    ├── apache2
    ├── backup
    ├── default
    ├── device-types
    ├── device-types-patch
    ├── devices
    ├── entrypoint.d
    │   └── 01_setup.sh
    ├── env
    ├── groups
    ├── health-checks
    ├── lava-patch
    ├── lava_http_fqdn
    ├── settings.conf
    ├── tokens
    │   └── admin-0
    ├── users
    │   └── admin
    └── zmq_auth

公式手順だとこのまま docker-compose build; docker-compose up -d すれば起動する。
でmasterコンテナ内のPostgreSQLがデータストアとなる。このままコンテナを作り直せばデータは揮発しちゃう。 ので、永続化させたければデータボリュームをコンテナのデータ領域にマウントするなど方法がある。今回はマネージドのDBサービスを使う。

AWS Aurora Serverless の準備

これは省略。

改造する

この方法は2020年5月時点で非公式の方法であり、なんらかのコードパスで不具合が生じる可能性があるけども、一応ちゃんと動いてくれているように見えてはいるので自分の環境はこれにしている。

とても簡単な改造の3ステップが以下のような流れ。

  1. instance.confを作成する
    masterは /etc/lava-server/instance.conf という設定ファイルを参照して接続先DBを認識するようなので、以下のような instance.conf を、てきとうなパスに作成する。で、masterのDockerfileの中に COPY /path/to/instance.conf /etc/lava-server/instance.conf を追加しておく。
    ※ もちろんAurora側にRoleやDBは作成済みであるとする

    LAVA_DB_PASSWORD="lavaserver"

    LAVA_SYS_USER="lavaserver"

    LAVA_DB_NAME="lavaserver"

    LAVA_INSTANCE="lavaserver"

    LAVA_DB_USER="lavaserver"

    LAVA_DB_PORT="5432"

    LAVA_DB_SERVER="endpoint of Aurora"

  2. master1/entrypoint.d/01_setup.shを修正する
    これはmasterイメージをbuildするさいのentrypointとなるスクリプトで、実はこの中で、ローカルのPostgreSQLに対して lavaserver ユーザのパスワードをランダムに変更するという力技を行っている。そして、instance.confLAVA_DB_PASSWORD も書き換えている。そのためここは以下の行をコメントアウトなり削除しておいて instance.conf への置換を無効化する。。。

      < sed -i "s,^LAVA_DB_PASSWORD=.*,LAVA_DB_PASSWORD='$(cat /root/pg_lava_password)'," /etc/lava-server/instance.conf || exit $?
      ---    
      > # sed -i "s,^LAVA_DB_PASSWORD=.*,LAVA_DB_PASSWORD='$(cat /root/pg_lava_password)'," /etc/lava-server/instance.conf || exit $?
    
  3. ビルドして起動する
    あとは、 docker-compose build; docker-compose up -d するだけ。

大変雑な改造なのだが、もっとちゃんとやるのであればそもそもmasterコンテナでPostgreSQLあげないようにしたほうがベターだろうと思う。

一昔前には、サーバハードニングという文脈において不要なサービスは停止することというのが当たり前のように叫ばれていたような気がする。OSインストールからハコモノを大事に育てるような素朴な構築をなかなかしなくなってしまった昨今でも大事というか普通にチェックすべしなポイントではあるけども。

なにはともあれできた。

使えている

とりあえずサンプルのジョブを流してちゃんと使えていることが確認できた。

Submitting your first job — LAVA 2020.04 documentation

コンテナ再作成しても過去のレポートやらテストのログが残るのはうれしい。RDS自体のもろもろの恩恵にもあずかれる。

今後

EC2インスタンス上でdocker-composeをしたのだけど、ここまできたらmasterとworkerもマネージドなコンテナオーケストレーションサービスを使いたいと思うのが自然なので、そうしたい。

データ自体はAuroraに保持することによってポータビリティがめっさあがったと思い、Fargateとかにマイグレーションするときもきっとすんなりいってくれるはずと思っているけどそんなことはないんだろうなあ。

参考