tkm9

自分向け技術メモ(?)

Vagrant + Chef + VirtualBox で 開発環境チャレンジ(1)

社内のあるrailsアプリを今後チームでやっていこうという話になりまして、いい機会なので Vagrant/Chef で環境を作って、これをメンバーにばらまきたいと思いました。
ということで、その事前調査のメモです。

バージョン

最終目標

こんなことがやりたいです。

  • Vagrant、Chef、VirtualBox をあらかじめメンバー環境にインストールしてもらう
  • 社内gitリポジトリVagrant/Chef の設定ファイルを作成しておく
  • メンバーはリポジトリからcloneし、コマンド1発叩くと仮想環境が自動で出来上がる
  • アプリに必要なミドルウェアを追加した際などはその設定をpush、メンバーはpull&コマンド実行

この記事の目標

最終目標はrailsの環境構築ですが、Vagrant + Chef でひとまず動くようにする。

調べ始めて思ったこと

Chef流行りはじめのころの情報は多いのですが、現状から見ると記述が違ってたりほかのやり方がありそうだったりで、その辺の見極めがちょっと大変かもと思いました。

今回参考にしたページです。

VirtualBoxインストール

これはインストール済なので省略。インストール自体は Downloads – Oracle VM VirtualBox ここからインストーラを落としてすぐできるはずです。

Vagrantインストール

Download Vagrant - Vagrant
こちらから 1.7.2 Mac OSX 用をダウンロード。インストーラ実行。

$ which vagrant
/usr/bin/vagrant
$ vagrant --version
Vagrant 1.7.2

Chef

以前は gem でインストールするのが主流だったようですが、現在は ChefDK(Chef Development Kit という全部入りのキット)が提供されているようですので、こちらを利用します。
Chef Development Kit | Chef Downloads | Chef

キットは以下を含むとのこと。

  • Chef
  • Berkshelf
  • Test Kitchen
  • Foodcritic
  • その他Chefツール
    • Chef Client
    • Knife
    • Ohai
    • Chef Zero

僕の場合、この中で使うのは Chef、Berkshelf、Chef Zero、Knife あたりになるかな?
インストールすると chef コマンドが使えるようになります。

$ which chef
/opt/chefdk/bin/chef
$ chef -v
Chef Development Kit Version: 0.4.0

rubyについて

インストール自体はこちらもインストーラ実行するだけで簡単です。

なお、先ほど、"以前は gem でインストールするのが主流で..." と書きましたが、Chef自体は今も変わらず gem で提供されています。
ですが、Chef 含め必要な gem は、この ChefDK に ruby がバンドルされていて、そちらにインストールされます。
なので、システムで利用しているrubyには影響ないのですね。

例えば gem の操作をしたいときは、

chef gem 〜

のように、chef コマンドを経由することで ChefDK の ruby に対して操作できます。

もしくは、eval "$(chef shell-init bash)" を実行することで、ruby をシステムのものからChefDKのものに切り替えることもできます。
※上記は bash となっていますが各個のシェル名(bash zsh sh powershell posh)とする必要があります
eval "$(chef shell-init bash)"実行の場合、ログインしなおすと元に戻るので bash_profile とかに追記しておくと良いかもしれません

今回は eval "$(chef shell-init bash)" しておきます。
でも今回の作業内容的に不要な気がします。が、一応実行。

実行前 ruby

ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14]

実行後 ruby

ruby 2.1.4p265 (2014-10-27 revision 48166) [x86_64-darwin12.0]

Vagrantプラグイン インストール

$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-chef-zero
$ vagrant plugin install vagrant-omnibus

インストールしたプラグインのバージョン確認

$ vagrant plugin list
vagrant-chef-zero (0.7.1)
vagrant-omnibus (1.4.1)
vagrant-share (1.1.3, system)
vagrant-vbguest (0.10.0)

vagrant-share は多分 Vagrant Cloud に Vagrant環境を公開するためのプラグインでデフォで入ってるやつだと思います。

vagrant設定ファイル作成

chefとの連携はいったん置いておいて、vagrant のみで CentOS7 の環境を作ってみます。

vagrantのゲストOSのイメージについては、boxというファイルが利用されます。
この box はネット上でいろいろなOSのものがアップロードされており、利用することができます。
box については、Discover Vagrant Boxes | Atlas by HashiCorp こちらから選べます。

今回は pmmresende/CentOS7 にしようと思います。

$ mkdir vagrant
$ cd vagrant
$ vagrant init CentOS7 pmmresende/CentOS7
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'CentOS7' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'pmmresende/CentOS7'
    default: URL: https://atlas.hashicorp.com/pmmresende/CentOS7
The box you're adding has a name different from the name you
requested. For boxes with metadata, you cannot override the name.
If you're adding a box using `vagrant box add`, don't specify
the `--name` parameter. If the box is being added via a Vagrantfile,
change the `config.vm.box` value to match the name below.

Requested name: CentOS7
Actual name: pmmresende/CentOS7

あれ、エラーになっちゃった。

box を A list of base boxes for Vagrant - Vagrantbox.es から選んできて再度実行。
こっちの場合はURLになる。

$ vagrant init CentOS7 https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box

こんどは大丈夫でした。

$ vagrant ssh

でログインできます。

あと、最初は CentOS6.5 でやったのですが、GuestAdditions関連のエラーが発生しました。
どうやらゲストOSのカーネルが古いのが原因のようだったのでCentOS7としました。
参考になるかもしれませんのでその際みてたページを列挙します。

現時点でのVagrantfileの中身はこんな感じでございます。(コメント部は削りました)

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "CentOS7"
  config.vm.box_url = "https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box"
end

プライベートネットワークの設定

ホストとゲスト間の通信を行えるようにしたいので、Vagrantfile を編集します。(必須じゃないです)

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "CentOS7"
  config.vm.box_url = "https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box"
  # 追記
  config.vm.network :private_network, ip:"192.168.33.11"
end

再起動

$ vagrant reload

これで、ホストからssh vagrant@192.168.33.11 で接続できるようになりました。
vagrantユーザのパスワードは vagrant です

ゲストboxへの Chef のインストール

Vagrantfile に設定を追加することで、boxに自動で Chef をインストールすることができます。

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "CentOS7"
  config.vm.box_url = "https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box"
  config.vm.network :private_network, ip:"192.168.33.11"
  # 追記
  config.omnibus.chef_version = :latest
end

:latestの部分は Chef のバージョン指定です。
chefの最新バージョンのインストールを指定するために:latestとしました。

再起動

$ vagrant reload

で、Chefがゲスト側にもインストールされます。

Chef 設定ファイル作成

新規に Chef 関連のファイルの雛形を生成します。

$ cd vagrant
$ chef generate repo chef-repo

生成後

$ tree
.
├── Vagrantfile
└── chef-repo
    ├── LICENSE
    ├── README.md
    ├── Rakefile
    ├── certificates
    │   └── README.md
    ├── chefignore
    ├── config
    │   └── rake.rb
    ├── cookbooks
    │   └── README.md
    ├── data_bags
    │   └── README.md
    ├── environments
    │   └── README.md
    └── roles
        └── README.md

Berkshelf で cookbook を作成する

Berkshelf は よそ様の作った cookbook を依存関係を解消しつつ管理してくれるツールです。
これを使って cookbook を作ってみます。
とりあえず ntp の cookbook にしてみます。

Berksfile を作成

Berkshelf で cookbook を管理するための、Berksfile というファイルを新規に作成します。

$ cd chef-repo/
$ vi  Berksfile
source "https://supermarket.chef.io"
cookbook 'ntp'
cookbookインストール

インストール先を cookbooks に指定したいので、berks installじゃなくてにしてます。
ていうかberks installでもエラーにはなんなかったけど、どこに入ったのかよくわからんかった...

berks vendor cookbooks

Vagrant / Chef 連携設定

Vagrantfile に設定を追記します。

# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
  config.vm.box = "CentOS7"
  config.vm.box_url = "https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box"
  config.vm.network :private_network, ip:"192.168.33.11"
  config.omnibus.chef_version = :latest
  # 追加
  config.vm.provision "chef_zero" do |chef|
    chef.cookbooks_path = ["chef-repo/cookbooks"]
    chef.add_recipe "ntp"
  end
end

で、確認。

$ vagrant provision
$ vagrant ssh
$ ps aux | grep ntp
ntp       4892  0.0  0.4  29364  2060 ?        Ss   03:45   0:00 /usr/sbin/ntpd -u ntp:ntp -g
vagrant   4924  0.0  0.1 112656   976 pts/0    S+   03:46   0:00 grep --color=auto ntp

お、入ってる!

今後

続きで、rails 環境を作らねば...

しかしなんだか、達成感が皆無です。
いろんな解説ページを見ながらとりあえずやってみただけだから、あんまり理解できてません。もやもや。

少なくとも Chef に関しては全然知識足りてないので、そこをなんとかしてから続きかな。
今のまま環境つくってメンバーに配るくらいなら VirtualBox のイメージをファイルサーバにただ置いておいたほうがよさそうだ。