Vulcanを使ったHeroku向けバイナリのビルド
はじめに
BounscaleというオートスケールするHeroku Addonを作っています。
Bounscaleではバックエンドにオープンソースの監視ツールであるZabbixを使っています。今のところサーバ監視しかしていないのですが、今後の拡張で、Heroku上でエージェント監視も見据えていて、実現可能か調査しています。
その中で得た情報をまとめていきます。今回はVulcanです。
Vulcanとは?
VulcanはHeroku自身が公開しているネイティブコードのビルドの仕組みです。
Herokuでネイティブのライブラリを利用したい場合に、確実にHeroku上で動くバイナリをコンパイルして生成することができます。
背景
Herokuで使われているOSとかライブラリとかのバージョンを完全に合わせたビルド環境をローカルに作るのは面倒です。(そもそも詳細は公式にはアナウンスされてないと思います)
バージョン合わないとヘッダファイルがどうたらこうたらとかエラーが出ます。
Vulcanは、それなら最初からHerokuそのものでビルドしてしまえばいいじゃない、という感じで作られたものだと理解しています。
アーキテクチャ
VulcanはHeroku上に通常のHerokuアプリとして、自分用のビルドサーバを自動生成して、クライアントからソースをサーバに渡して、結果としてバイナリを入手します。
流れ
- Vulcanクライアントはrubyのgem経由でインストールされます
- Vulcanクライアントは普通のrubyスクリプトです
- VulcanクライアントにはVulcanサーバのソースが同梱されています
- VulcanクライアントはHerokuに専用のビルド環境(Vulcanサーバ)をデプロイします
- Vulcanサーバはnode.jsでできています
- VulcanクライアントからソースをアップロードするとVulcanサーバがビルドして結果のファイルをダウンロードできます
必要な環境
- Herokuにログインして普通にpushできる環境
- 本記事では詳細は取り扱いません
- カード情報が登録されているHerokuアカウント
- 内部的にCloudantアドオン(無料版なので安心してください)を使っているためだそうです
手順
監視のオープンソースプロダクトZabbixのエージェントをビルドしてみます。
Zabbixのソースコードを取得します
wget http://downloads.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/2.0.3/zabbix-2.0.3.tar.gz
Vulcanのgemをインストールします
gem install vulcan
ビルド環境をHeroku上に作ります
herokuの認証を受けていない場合はここで認証します。
このタイミングで自動的にheroku createとgit pushが行われて、VulcanサーバがHeroku上にデプロイされます。
vulcan create bounscale-buildpack
なお認証情報やビルドのアプリの名前等は ~/.vulcan に記録されています。
ビルドを実施します
Linuxでの通常のビルドのコマンド(configure / make / make install)をVulcanサーバに送信します。
vulcan build -v -s . -c 'CFLAGS="-O3 -Wall -march=native" CXXFLAGS="-O3 -march=native" ./configure --prefix=/app/vendor/zabbix --enable-agent --enable-ipv6 && make -j5 && make install'
ファイルを入手します
ビルドのログがざーっと出た後、こんな感じのメッセージが出て、ファイルがローカルに落ちてきています。
WebからダウンロードできるURLも表示されます。
>> Downloading build artifacts to: /tmp/..tgz
(available at http://bounscale-buildpack.herokuapp.com/output/d6bd8a12-7068-4444-89f4-4be48dd0c95e)
ちょっとファイル名が変ですが、今回はあまり気にしない事にします。
(おそらくvulcan buildのオプションを適切に付ければちゃんとするとは思います)
実行してみる
生成されたzabbix_agentdバイナリをHerokuにデプロイしてください。
(アプリケーションルート/vendor/zabbix/etc/zabbix_agentd.confを一緒にデプロイしておいてください)
Herokuのシェルに接続して実行してみます。
heroku run sh
./zabbix_agentd
なぜかdefunctになっていますが、とりあえずプロセスは上がって来ています。
> ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 0.0 0.0 20368 1448 ? S 02:56 0:00 ps-run
u46763 2 0.0 0.0 4160 668 ? S 02:56 0:00 sh
u46763 15 0.0 0.0 0 0 ? Zs 03:03 0:00 [zabbix_agentd] <defunct>
u46763 16 0.0 0.0 0 0 ? Z 03:03 0:00 [zabbix_agentd] <defunct>
u46763 18 0.0 0.0 15320 1208 ? R+ 03:03 0:00 ps aux
とりあえず
VulcanでビルドできてHeroku上で実行できることは分かったのでこの記事は終わります。
これでちゃんとzabbix_agentdとして動作しているのか、またDynoがrestartしても永続的にプロセスが起動させる方法等はまた別の機会に確かめてまとめます。
また、うまく動くようであれば、buildpackにして公開したいと思っています。
ハマった事
大きいファイルがアップロードできない
Zabbixのソースはそのままだと12MB位あるのですが、大きすぎるのかアップロードが止まってしまうことがありました。
PHPのソースが入っているfrontendディレクトリを丸ごと削除したらアップロードできるようになりました。
Proxy環境に対応していない
VulcanクライアントはProxy環境に対応していません。
http_proxy環境変数を参照するように修正したソースをGithubで公開していますので、必要な方はお使いください。