永遠の中二病です、ごきげんよう。学生時代の趣味はWindowsの再インストールでした。
環境構築って面倒ですよね。単純作業の割には微妙な手順ミスで後からハマったりして、もっと自動化、効率化できないかなと昔から思っていました。Windowsにも自動インストールの仕組みは以前からありましたが、そのための設定がまた大変だったものです。そんなわけで、今回はUNIX界隈に場所を移して、仮想環境を楽に構築してみようというお話です。
環境構築今昔話
さて、UNIX界隈で仮想環境の構築と言われてどんな手順を思い浮かべるでしょうか?
ざっと挙げても沢山ありますね。これを手作業でやっていては大変です。もちろんこうした作業を自動化する仕組みは色々あって、KickstartのようなOSインストールの自動化であったり、Puppetのようなサーバの集中設定管理のようなものは以前から提供されていました。
また最近だと、昨年はVagrantやChefのようなツールが大いに話題になりました。これらは仮想マシンの操作やプロビジョニング(ソフトウェアの整備やシステム環境設定など、稼働するための準備全般)という部分をプログラマブルに行えるようにするためのものです。上記の手順だと4〜5に相当する部分+αですね。
はい、あとは1〜3まで自動化できれば、ワンストップで仮想環境が作れそうです。
ところが、1〜3に相当する仮想マシンイメージの作成に関することは、Vagrant/Chefと比較するとほとんど話題に上がっていません。というのも、予め用意されたイメージファイルが各所で配布されているので、大抵はそれを利用しているからなのですね。個人用途などではそれでも十分かと思いますが、業務利用となると素性の明らかな…つまり意図された手順に沿ってインストールされた仮想マシンを使いたいもの。
そこで今回は、Vagrantから利用することを想定した仮想マシンイメージを実際に作る事例を紹介しようと思います。なお、仮想化ソフトウェアにはVirtualBoxを利用し、ホストはOS X、ゲストはCentOS 6.5を想定しています。他のOSや仮想化ソフトウェアを利用される場合は一部を読み替えていただければと思います。
環境構築の概要
前置きが長くなりましたが、今回の環境構築のゴールは仮想マシンにCentOSをインストールして、Vagrantから利用できるようになることです。これを踏まえ、想定環境は次の通りとしました。各ツールのバージョンは執筆当時の最新版です。
- ホストOS
- OS X 10.9.x (Mavericks)
- ゲストOS
- CentOS 6.5 (64bit)
- その他ツール
- VirtualBox 4.3.6
- Vagrant 1.4.3
- Packer 0.5.1
また今回仮想マシンを作成するにあたっては、Packerというツールを使用します。同じような機能を持つツールとしてVeeweeというものもあるのですが、PackerはVirtualBoxやVMWareに加えてAmazon EC2やDigitalOceanのようなクラウドサービスについても一貫性のあるインタフェースで作成できるため、汎用性を考慮してこちらを選びました。
必要なソフトウェアのインストール
Packerは公式サイトのダウンロードページに各プラットフォーム向けのパッケージがありますので、こちらをダウンロード、インストールします。homebrewのようにパッケージ管理システム上に存在する場合もありますので、そちらからインストールしても構わないでしょう。
また、VirtualBoxとVagrantもインストールが必要になります。これらは公式サイトからパッケージでダウンロード、インストールします。Vagrantはパッケージ管理システム上にも存在しますが、執筆時点ではバージョンが古いのでパッケージからインストールします。
設定ファイルの作成
Packerを設定するにあたって、今回は次の3つのファイルを作成します。
Packer自体の設定ファイル
まずPacker自体の設定ファイルですが、これはJSON形式で記述します。作業ディレクトリは任意ですが、その配下にBoxが作成されることを考慮しておくと良いでしょう。ファイル名も任意ですが、ここでは便宜上「packer.json」とします。
{ "builders": [ { "type": "virtualbox-iso", "guest_os_type": "RedHat_64", "iso_url": "http://ftp.iij.ad.jp/pub/linux/centos/6.5/isos/x86_64/CentOS-6.5-x86_64-minimal.iso", "iso_checksum_type": "md5", "iso_checksum": "0d9dc37b5dd4befa1c440d2174e88a87", "ssh_username": "vagrant", "ssh_password": "vagrant", "ssh_wait_timeout": "3000s", "vm_name": "box", "http_directory": "./", "boot_wait": "10s", "boot_command":[ "", "linux ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks.cfg ", "" ] } ], "provisioners": [ { "type": "shell", "script": "provisioners.sh" } ], "post-processors": [ { "type": "vagrant", "output": "centos-6.5-x86_64.box" } ] }
この中で説明が必要な項目について触れていきます。
- buildersのtypeは過去のバージョンでは「virtualbox」でしたが、最新版では「virtualbox-iso」となります。
- buildersのssh_usernameとssh_passwordは仮想マシンにログインする時に使います。
- buildersのboot_waitは、ブート時に待つ時間で、環境によるかもしれませんが短すぎるとコマンドの入力に失敗します。
- buildersのboot_commandは、ブート時にPakerがOSインストーラを操作するためのコマンド群です。
- provisionersは、OSインストール後のプロビジョニングについて記述します。今回はシェルスクリプトとして「provisioners.sh」を呼び出すようにしていますが、ChefやPuppetも使おうと思えば使えます。
- post-processorsは、インストール終了後の出力情報です。ここではVagrant用に「centos-6.4-x86_64.box」というファイル名で保存します。
OSインストール後のプロビジョニング用シェルスクリプト
次に、provisionersの項目で外に出したプロビジョニング用スクリプトです。こちらも作業ディレクトリディレクトリにprovisionersで指定したファイル(今回はprovisioners.sh)を設置します。
#!/bin/bash sudo sed -i "s/^.*requiretty/#Defaults requiretty/" /etc/sudoers sudo sed -i "s/#UseDNS yes/UseDNS no/" /etc/ssh/sshd_config sudo sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config sudo sh -c 'echo "[epel]" >> /etc/yum.repos.d/epel.repo' sudo sh -c 'echo "name=epel" >> /etc/yum.repos.d/epel.repo' sudo sh -c 'echo "baseurl=http://download.fedoraproject.org/pub/epel/6/\$basearch" >> /etc/yum.repos.d/epel.repo' sudo sh -c 'echo "enabled=0" >> /etc/yum.repos.d/epel.repo' sudo sh -c 'echo "gpgcheck=0" >> /etc/yum.repos.d/epel.repo' sudo yum -y install gcc make automake autoconf libtool gcc-c++ kernel-headers-`uname -r` kernel-devel-`uname -r` zlib-devel openssl-devel readline-devel sqlite-devel perl wget nfs-utils bind-utils sudo yum -y --enablerepo=epel install dkms mkdir -pm 700 /home/vagrant/.ssh wget --no-check-certificate 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub' -O /home/vagrant/.ssh/authorized_keys chmod 0600 /home/vagrant/.ssh/authorized_keys chown -R vagrant /home/vagrant/.ssh cd /tmp sudo mount -o loop /home/vagrant/VBoxGuestAdditions.iso /mnt sudo sh /mnt/VBoxLinuxAdditions.run sudo umount /mnt sudo /etc/init.d/vboxadd setup
ここで行っているのは、主にVirtualBoxのGuestAdditionsをインストールするための設定と、Vagrantを利用してSSHログインするための設定です。ただのシェルスクリプトですので、読めば理解いただけるかと思います。なお、yumでインストールしているパッケージはGuestAdditionsに必要な最低限のものとなっています。
OS自動インストール用の設定ファイル
次に、OS自動インストール用の設定ファイルを用意します。Linuxの場合はKickstartという自動インストールの仕組みがありますので、その設定ファイルを作成します。こちらは作業ディレクトリに「ks.kfg」として設置します。
install cdrom lang en_US.UTF-8 keyboard us network --bootproto=dhcp rootpw --iscrypted $1$bru//p3Y$AIC48J2Me8qwiR5JW/xIs/ firewall --enabled --service=ssh authconfig --enableshadow --passalgo=sha512 selinux --disabled timezone UTC bootloader --location=mbr text skipx zerombr clearpart --all --initlabel autopart auth --useshadow --enablemd5 firstboot --disabled reboot %packages --nobase @core %end %post /usr/bin/yum -y install sudo /usr/sbin/groupadd vagrant /usr/sbin/useradd vagrant -g vagrant -G wheel echo "vagrant"|passwd --stdin vagrant echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant chmod 0440 /etc/sudoers.d/vagrant %end
こちらについては、Vagrantを利用して「vagrant/vagrant」でログインできるように、またパスワード無しでsudoできるようにしています。rootのパスワードもひとまず「vagrant」としていますので、適宜変更してください。
Vagrantの設定ファイル
最後にVagrantの設定ファイルですが、こちらはvagrantコマンドでスケルトンを生成できますので、利用してみましょう。作業ディレクトリ上で次のコマンドを発行してください。
$ vagrant init centos-6.5-x86_64
これで作業ディレクトリ上に「Vagrantfile」というファイルが生成されますので、次の箇所だけ編集します。
# 仮想マシンにマウントするディレクトリを指定 # config.vm.synced_folder "../data", "/vagrant_data" config.vm.synced_folder "./", "/vagrant_data"
# コメントアウトを解除 config.vm.network :public_network
なお、この設定ではネットワークインタフェースが複数ある場合に選択を求められることになりますので、環境に応じて次のように指定しておくと自動選択されます。
#en1: Wi-Fi (AirPort) の部分は選択したいインタフェースを指定 config.vm.network :public_network, :bridge => "en1: Wi-Fi (AirPort)"
イメージ作成
さて、これでイメージ作成の準備は整いました。作業ディレクトリ上で次のコマンドを発行してください。
$ packer build packer.json
設定に問題が無ければ、あとは放置しておくだけで仮想マシンイメージの作成が完了します。完了したら、おもむろに
$ vagrant box add centos-6.5-x86_64 centos-6.5-x86_64.box $ vagrant up
と打ち込んでみましょう。特にエラー無く起動すれば完成です!「vagrant ssh」で接続するなり、壊すなり、お好きなようにご利用ください。
補足:vagrant upでエラーが発生する場合
下記のようなエラーが発生する場合があるようです。
Failed to mount folders in Linux guest. This is usually beacuse the "vboxsf" file system is not available. Please verify that the guest additions are properly installed in the guest and can work properly. The command attempted was: mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` /vagrant /vagrant mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` /vagrant /vagrant
この場合、共有フォルダが正しくマウントされていませんが、仮想環境には入れますので、
$ sudo /etc/init.d/vboxadd setup
とすることで再度正常にGuestAdditionsがインストールされます。その後、ローカルから
$ vagrant halt $ vagrant up
で正常化します。
あとがき
最後が実に呆気なかったのですが、それだけ自動化の威力が大きいということでご勘弁を…。 VagrantとChefでOSインストール後の環境をプログラマブルに制御し、更に前段階の仮想マシンイメージ作成をPackerで自動化することで、再利用性、一貫性のある環境構築をゼロから行えるようになりました。この仕組みを使えば、多人数の業務プロジェクトなどでも標準化された開発環境を容易に実現できるようになります。またPackerを利用すれば、クラウドサーバの構築についても同じインタフェースが利用できますので、本番環境の構築にも手を広げられる可能性が見えてくるのではないでしょうか。今回紹介した内容はPackerの中でもほんの一部ですので、ぜひ思い思いの使い方をしていただければと思います。
インフラ環境もいよいよ本格的に、職人技から自動化の時代になってきた感がありますね。楽をしても良い所は、どんどん楽をしたいものです。