こんなことをやってみたい
- CentOSに最新のrubyをインストールしたい。
- vagrantを利用したい
- ruby入りのboxを使うのではなく、素のCentOSを使って手順を自分で試したい
- OS起動後に自分でsshでログインしてからrubyのセットアップをするのではなく、自動でインストールが進んで欲しい
- ひとまずrubyが入ったら、自分のイメージとしてboxを作りたい。
- rubyのリモートでバッグをしたい。(ゆくゆく)
※プロビジョニングにはChefを使えそうではあるけれど、Chefはそもそも対象ノードにrubyを入れるのが前提です。
Chefを使わずに簡単にプロビジョニング
Vagrantを使ってVMを起動したあとは、Chef (Chef-solo)を使ってプロビジョニングができます。
でも、そこまでしなくても、設定ファイルなどは調整せず、単純にyumでパッケージをインストールするくらいなら、shellを使って実施ができます。
注意点
Vagrantで config.vm.provision :shell をつかうとshellが実行できるのですが、基本はvagrantアカウントでsudoを使って操作になります。
でも、Vagrantの元になっているBoxによっては sudoした際のPATHが決まっていて、/usr/local/bin にインストールされたものが使えなかったりするので、ご注意を。
以下は、CentOSの場合のvisudoでの確認。
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
CentOS6.5に、Vagrantのプロビジョニング段階でrubyをインストールしてみる
rubyをインストールする手順を用意する
参考にしたのは、実は、index.docker.io にあったCentOS6.5 + ruby2.1入りのイメージです。
『Vagrantをすっ飛ばして、Dockerですか?』とお叱りを受けそうですが、Dockerのイメージは、docker history とすると、そのイメージが どんなコミットの積み重ねで生成されたかが分かります。
また、docker.io の対象のイメージのページには、そのイメージを作るもとになったのDockerfileも掲載されています。
ということで、インストールの手順が大変参考になります。
Vagrantのboxは、参考にしたDockerのイメージと同じく、CentOS。ただし、CentOS6.5を利用しました。
参考にしたVagrantfileは、こんな感じ
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# 利用するboxと、host名を設定
config.vm.box = "cent65"
config.vm.hostname = "test"
# Virtualboxのネットワークで、固定IPを割り当て
config.vm.network :private_network, ip: "192.168.33.11"
# boxは基本はメモリが512MBなので、2GBにしておく
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
vb.customize ["modifyvm", :id, "--cpus", "1"]
end
# ここから、Chefを使わない簡単プロビジョニング
config.vm.provision :shell, :inline => <<-EOT
yum install -y gcc
yum install -y zlib-devel openssl-devel
cd /usr/local; curl -OL http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.0.tar.gz
cd /usr/local; tar xfz ruby-2.1.0.tar.gz
cd /usr/local/ruby-2.1.0; ./configure --prefix=/usr/local; make; make install
# 実はここ、絶対パスでなく gem install … だったら失敗しました。
/usr/local/bin/gem install bundler --no-ri --no-rdoc
EOT
end
Server specでチェック
vagrant upでイメージの起動からプロビジョニングまで済んだら、ちゃんとVagrantfileの通りになっているか、server specで確認してみます。
単純に、ホスト名やOS, rubyが指定のパスにインストールできたか、というチェックです。
specファイルの例
require 'spec_helper'
# OS チェック
describe file('/etc/redhat-release') do
it { should contain 'CentOS' }
end
# ホスト名チェック
describe file('/etc/sysconfig/network') do
it { should contain 'test' }
end
# SELinux 無効の確認
describe selinux do
it { should be_disabled }
end
# ruby
describe file('/usr/local/bin/ruby') do
it { should be_executable }
end
describe command('/usr/local/bin/ruby -v') do
it { should return_stdout /^ruby 2\.1\.0/ }
end
rake specで確認
実行してみます。うまくテストが通った模様。
% rake spec
/Users/xxx/.rbenv/versions/2.0.0-p247/bin/ruby -S rspec spec/default/default_spec.rb
....
Finished in 2.11 seconds
5 examples, 0 failures
うまくいったのでSnapshotを取っておこう!
Vagrantでは、saharaというシンプルなSnapshotを取るプラグイン以外にも、snapshotというプラグインがあります。こちらの方が、コマンドラインから名前付きスナップショットが取得できるので、便利。
% vagrant snapshot take ruby2.1-installed
Taking snapshot ruby2.1-installed
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
% vagrant snapshot list
Listing snapshots for 'default':
Name: ruby2.1-installed (UUID: 9e25d049-0445-46db-9b05-3432d819d3c1) *
以上、VagrantでベースのCentOSを起動後、chefではなくconfig.vm.provision :shellを使ってruby2.1を入れる手順を検証してみました。
リモートデバッグに関しては、ruby2.1向けはまだ上手くできませんでしたが、上手く出来たら次回に書こうと思います。
追記:出来上がったCentOSにChefを入れておく
http://www.vagrantbox.es で、そもそもChef-soloインストール済みのBoxが提供されていますが、今回は自前でChef-soloを入れます。
また、rubyをインストールするプロビジョンの段階で、Chef-soloのインストールステップを追加することもできますが、ここでは、Vagrantのホスト側から、knife solo prepareで追加することにします。
なお config.vm.provision は、実行されるタイミングに制限があります。
- 初回のvagrant init
- vagrant provision を明示した際
- vagrant reload --provision を明示した場合
- 参考:http://docs.vagrantup.com/v2/provisioning/basic_usage.html
最初にvagrant upでOS起動とプロビジョニングを実施し、その後にconfig.vm.provisionに追加操作をさせたい場合は 上記のいずれかで明示的に指定しないと反映されません。
(あ、このコマンドもyumで入れとけば良かった、と後から気がついた時とか)
SSHのキーを登録する
では、Chef-soloを入れる作業に移ります。
- 前提:
- Vagrantを管理する側にも、Chef-soloが入っていて、Chefのリポジトリもそこで管理している。
出来上がったCentOSのホスト名は、config.vm.hostname = "test" と設定したので、ssh test でログインできるように、vagrant ssh-config にオプションを付けて、鍵を登録します。
(※ --host を指定しないと、Host default という名前になって登録されます)
% vagrant ssh-config --host test >> ~/.ssh/config
knife solo prepare で、ホスト側からChef-soloをインストールする
knife solo prepare ".ssh/configで登録したホスト" で、ホスト側からのChef-soloのインストールができますので、ruby2.1でも問題ないか確認します。
% knife solo prepare test
Bootstrapping Chef...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 14101 100 14101 0 0 2244 0 0:00:06 0:00:06 --:--:-- 20555
Downloading Chef 11.8.0 for el...
downloading https://www.opscode.com/chef/metadata?v=11.8.0&prerelease=false&p=el&pv=6&m=x86_64
to file /tmp/install.sh.12727/metadata.txt
trying curl...
url https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.8.0-1.el6.x86_64.rpm
md5 8f72d94dffd75c3f79dc0fcd457e7f11
sha256 1a1e3df541240dcf5da1d128b1a4341224db5a2e1dee83b3f0f5d41e0aadb2a3
downloaded metadata file looks valid...
downloading https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-11.8.0-1.el6.x86_64.rpm
to file /tmp/install.sh.12727/chef-11.8.0.x86_64.rpm
trying curl...
Checksum compare with sha256sum succeeded.
Installing Chef 11.8.0
installing with rpm...
warning: /tmp/install.sh.12727/chef-11.8.0.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY
Preparing... ########################################### [100%]
1:chef ########################################### [100%]
Thank you for installing Chef!
Generating node config 'nodes/test.json'...
入ったようです。
Server specで再度チェック
Host test にChefが入ったか、これもserver specで確認してみます。上記のspecファイルに追加してチェック。
# Chef-soloが入ったかチェック
# knife solo prepareであとから入れた場合のテスト
describe file('/usr/bin/chef-solo') do
it { should be_executable }
end