mashuuko

少し前にVagrant Meetupに参加してから、 VagrantPacker での開発自動化に向けてVMイメージ作成などに取り組んでいる。Vagrantやmeetupの詳細は、publickeyさんの記事やオフィシャルサイトをご覧いただきたい。うんちくはいいから、とりあえず仮想マシンの作成を自動化したい人はQiitaまとめをオススメする。

エントリとは関係ないが写真は先月に、北海道をツーリング旅行したときに撮ったもの(摩周湖)。 RHEL 7が、カーネルとGCCツールチェーンのバージョンアップ的な意味で待ち遠しい今日この頃である (Red Hat Enterprise Linux 7の新機能 )。

モチベーション

私は1年ほど前から、Jubatusの開発に係わっているが、公式サイトではRHEL 6系(CentOSやScientific Linux互換)とUbuntu 10.04(LTS)向けバイナリパッケージ提供をしている。

このプロジェクト限らず、ソフトウェアのバイナリパッケージを提供するには、リリース作業にパッケージ作成のための過程が1段か何段か加わるものである。

もちろん、手作業していくのは手間がかかるし自動化したい。特殊な環境に依存したスクリプトを用意したり、メンテしたりするのは嫌だし、作業ノウハウが属人的になってチームで共有されないとか、毎回のリリース作業者が固定化するような事態は避けたいわけだ。これはソフトウェアの製品開発全般でもいえると思う。私が2008年頃に、製品ビルドの自動化をやったとき、上司から「(前職では)製品にビルドマスターが居たものだよ」というニュアンスの発言を聴いた気がする。最近の流行っぽく書くとPackaging Senseiと呼ぶところだろうか。ビルドマスターの存在は否定しないし、居てくれるならありがたいけど、作業引き継ぎや情報共有を考えると小さなチームでは現実的じゃない。アジャイルチームにおいては、タスクの割り当ては流動的で固定化させることなく、チームの開発メンバー全員がリリースも担当できる状態が健全だろう。

パッケージングの作業からは離れて、ソフトウェアのお試し環境を仮想マシンイメージで配布したいこともある。今までも(今でも)、ソフトウェアをインストール済みの仮想マシンイメージを提供(配布)することはあった。 ただし、それには仮想マシンモニタ(いわゆるVMware、VirtualBox、QEMU/KVMだとか)とその環境間での移植性・互換性の維持が難しいことにある。最近は仮想マシンのイメージフォーマットが標準化されたり、OpenStackのようなOSSのIaaSも存在するが、Vagrantほどお手軽にそれら仮想マシンモニタを抽象化して扱うためのツールはなさそうである。もしくは、私の無知か、私が想定しているツールからは離れていると考えられる。もちろん、Vagrant自体が仮想マシンモニタ間の移植性を格段に高めてくれるわけではないのだが、異なる種類の仮想マシンモニタのディスクイメージを共通の操作基盤で手軽に利用可能になる点で価値がある。

長々書いてしまったが、結局は以下の2点に集約される。

  • バイナリパッケージ作成に焦点を置いたが、リリース作業のパッケージング時の自動化とノウハウの属人化や、作業人員の固定化を防ぎたい。その解決手段として、バイナリパッケージの生成に仮想化技術と、それをラップするツールとしてVagrantを使うアプローチがある
  • ソフトウェアのインストール済みのお試し環境として、仮想マシンイメージごとの配布を考える

テンプレートBOX作成の基礎

Vagrant向けにテンプレートとなるイメージ(Vagrant用語でBOXという)を作成するには、おおまかに以下の2点ある。

  • 自分で仮想マシンを作成し、イメージ配布のために仮想マシンのOS環境を整えた後、イメージをtarボールに固める
  • Packer を使って。上記のOS内の環境構築作業を、OSが用意する仕組みや、シェルスクリプトの実行によって自動化する。その後、Packerのpost-processorsという後処理コマンドでvagrantのBOX作成させる。

Packerを中心とした話をしよう。私はRHEL系以外のディストリビューション・OSの機能はよく知らないが、各OSはOSインストールを自動化する仕組みを持っていたりする(その仕組み自体はPackerと独立である)。

LinuxのRHEL, Debian系だと、これらを活用する。インストーラがブートして、セットアップする段階でどこかのHTTPサーバ上のファイルを読み込んで、記述された設定に従ってLinuxのインストールが自動的に進むわけだ。素晴らしい。

あれでも、わざわざHTTPサーバを用意する必要がないかって疑問が出てこないだろうか? Packerはそこも考慮してくれていて、Packer自身がHTTPサーバを内包してくれている。template.json(Packerの設定ファイルのことをconfiguration templateと呼ぶ)のhttp_directoryって項目に共有したいディレクトリを指定すると、仮想マシンのゲストからHTTPでアクセスできるようになる。といっても、現在このhttp_directoryが実装されているのはVirtualBoxとVMwareだけのようだ。

そもそも、特定用途向けにセットアップが完了した仮想マシンのイメージを配布するのが目的だったはずだ。必要なパッケージやソフトウェアをインストール、設定したり、仮想マシンイメージ配布用にネットワークの設定を初期化させるなど、やるべきことは沢山あって忙しい。そんなことは、シェルスクリプトで自動実行させてしまえるのも魅力である。VMware Tools, VirtualBox Additionsのインストールも忘れないでね。

注意すべき点としては、それら自動化スクリプトの記述とテスト、そして作成済みBOXをテストをPackerはケアしてくれないことだろう。また、OSインストール自動化を、Packerがどれくらいの時間でタイムアウトすべきかというのも難しい問題である。リモートのネットワークからパッケージをインストールすることもあるだろうし、CPUやIOのパフォーマンスはPackerを実行する仮想マシンのホストOS環境に大きく影響される。社内や自宅内に、ミラーサーバでも構築したくなってくるのは私だけではないと思う。

最後に、template.jsonと共通のシェルスクリプトで、VirtualBoxとVMwareの両方のBOXがPacker呼び出しの1コマンドで終わるのを見るのは凄い気分が良い。途中での停止もおおよそバッチリである。VMware toolsやVirtualBox Additionsのインストールにあたっては、以下のQiitaにもコメントしたが、大まかに次のようなコードとなる。

OSXでpackerでCentOS6.4のVirtualBox VMを作成する - Qiita

output, packer build

vmware.sh

 # Installing the vmware-tools
if [ ! -e /home/vagrant/vmware_tools.iso ]; then
    exit 0
fi
echo Starting to install VMWware tools
cd /tmp
mount -o loop /home/vagrant/vmware_tools.iso /mnt
tar -xvf /mnt/*.tar.gz
umount /mnt
perl vmware-tools-distrib/vmware-install.pl --default
rm -rf /home/vagrant/vmware_tools.iso
rm -rf /tmp/vmware-tools-distrib

virtualbox.sh

# Installing the virtualbox guest additions
if [ ! -e /home/vagrant/.vbox_version ]; then
    exit 0
fi
echo Starting to install VirtualBox guest additions
VBOX_VERSION=$(cat /home/vagrant/.vbox_version)
cd /tmp
mount -o loop /home/vagrant/VBoxGuestAdditions_$VBOX_VERSION.iso /mnt
sh /mnt/VBoxLinuxAdditions.run
umount /mnt
rm -rf /home/vagrant/VBoxGuestAdditions_*.iso

コミュニティの様子を見る

Packerのgithubを見ていると、QEMU対応のissuePRもあるし、近いうちにVagrantの公式でもKVMがサポートされるんじゃないかと期待している。もちろん、自分からPull Requestを送ったり、議論に参加しても良い。