FURYU Tech Blog - フリュー株式会社

フリュー株式会社の開発者が技術情報を発信するブログです。

関JavaでJavaでなくChefの話をしてきました

皆さま約一ヶ月ぶりです。
国平です。

先日、関西Javaエンジニアの会でChefの話をしてきました。参加してくださった方々にちょっとでもChefに興味を持っていただけたら大成功なのですが、いかんせん限られた時間での発表なので具体的な使い方やサンプルまでは踏み込めませんでした。なので、その分をこのブログで補足したいと思います。

発表内容

私の関Javaでの発表資料はこれです。

いろいろと書いていますが、要するに

  • プロビジョニングフレームワークの導入で色々はかどる
  • Chefは便利なツール
  • knife-soloでリモート操作が便利になる
  • Berkshelfでcookbookの依存関係も解決出来る

という内容です。

私の前回の記事のChef周りの内容に加えてknife-soloとBerkshelfの紹介を足しています。 今回の記事では特にknife-soloとBerkshelfの利用についてまとめます。

knife-solo

knife-soloはknifeのサブコマンド群です。
この、knife-soloはChef-Serverで行うようなリモートサーバに対するChefの実行をChef-soloで実現してくれるツールです。

前回のブログ記事で、Chefは各サーバに対しインストールが必要で面倒だと書きましたが、このknife-soloを利用することでChefのリモートインストールが可能になり、Chefの利用が一気にはかどります。

インストール

knife-soloはgemでも提供されており、普通にgem installもできるのですが、デフォルトのバージョンが0.2.0となっています。 https://rubygems.org/gems/knife-solo

しかし、バージョン0.3.0で追加されたオプションもあり、なるべく0.3.0の利用をお勧めします。特に、knife-soloは開発が活発なので、なるべくならgemでなくソースからのインストールをお勧めします。

gemでインストールする

gemからインストールする場合は、バージョン指定せずにインストールすると前述の通り0.2.0がインストールされます。 なるべく最新のバージョンをインストールするために、以下のようにバージョンを指定して取得するといいと思います。

最新バージョンについてはここで確認してください。

]# gem install -v 0.3.0.pre4

ソースからインストールする

knife-soloのソースはGitHubで公開されています。 https://github.com/matschaffer/knife-solo

ソースからのインストールには次の3つがインストールされている必要があります。

  • rake
  • bundler
  • git

インストールの実行手順を下記にまとめました。 注意して頂きたいのは、knife-soloのGitリポジトリはsubmoduleに別れているので、サブモジュールの更新を実行する必要がある点です。

# rakeインストール
]# gem install rake

 # bundlerインストール
]# gem install bundler

 # ソースをgitで取得
]# git clone https://github.com/matschaffer/knife-solo.git

]# cd knife-solo

 # submoduleを更新
]# git submodule init
]# git submodule update

 # ソースからインストールする
]# bundle && bundle exec rake install

上記手順で、knife-soloのインストールが完了します。

コマンド

knife-soloには以下の5つのコマンドがあります。

  • init
  • prepare
  • cook
  • bootstrap
  • clean

今回は、関Javaで紹介したcook、prepareに加えてinitについて紹介しますが、残りのコマンドについてもhelpで確認出来ます。

knife-solo自体のヘルプを確認したい場合はknife solo -hで、各コマンドについて確認したい場合は、knife solo -h {command}で確認出来ます。

init

initコマンドを使う事で、新しくknife-soloに最適化されたChefRepository(Kitchen)を作成する事が出来ます。

knife solo init {DIRECTORY}

prepare

prepareコマンドは、リモートマシンに対してChef-soloのインストールを行います。 また、同時に指定したリモートマシンに対してデフォルトで実行される設定を書き込むjsonファイルがnodesフォルダに作成されます。

knife solo prepare {user}@{host}

cook

cookコマンドは、リモートマシンに対してChef-soloの実行を行います。 prepareコマンドでjsonが作成されているハズですので、そのjsonのrun_listに書かれているcookbookが順に実行されます。

knife solo cook {user}@{host}

sample

knife-soloを利用するサンプルとして、gitをリモートサーバにソースからインストールしてみます。

今回は、opsocodeが公開しているcookbookをgitから取得して実行します。 なお、今回は既にローカルマシンにはgitがインストール済みの前提で進めます。 もし、まだローカルマシンにgitをインストールしていない場合は、gitをインストールする、もしくはgit cloneを行っている箇所を、zipのダウンロードに読み替えてください.

まずはリポジトリを作成しましょう。

# リポジトリ作成
]# knife solo init knife-solo-repo

リポジトリの作成が出来たら、リモートサーバにChefをインストールします。

]# cd knife-solo-repo

 # リモートサーバへのChef-soloインストール
]# knife solo prepare {user}@{host}

次に必要なcookbooksをダウンロードします。

]# cd site-cookbooks

 # git cookbookのダウンロード
]# git clone https://github.com/opscode-cookbooks/git.git

git cookbookが直接依存するcookbookはhttp://community.opscode.com/cookbooks/gitのCookbooksの項にまとまっていますが、最終的にgit cookbookは次の6つのcookbookに依存します。 これは、git cookbookが依存するcookbookが更に依存するcookbookを持つためです。

これらのcookbookもダウンロードします。

]# git clone https://github.com/opscode-cookbooks/runit.git
]# git clone https://github.com/opscode-cookbooks/build-essential.git
]# git clone https://github.com/opscode-cookbooks/dmg.git
]# git clone https://github.com/opscode-cookbooks/yum.git
]# git clone https://github.com/opscode-cookbooks/chef_handler.git
]# git clone https://github.com/opscode-cookbooks/windows.git

必要なcookbooksがそろったら、実行するrun_listを設定します。

]# cd ../nodes
]# vi {host}.json

 # 以下 {host}.json
{
  "run_list":[
    "recipe[git::Source]"
  ],
  "git":{
    "prefix":"/usr/local/git"
  }
}

このjsonの設定で、knife-soloを実行するとリモートサーバの/usr/local/gitにgitがソースからビルドされます。 実行するには、knife solo cookコマンドを実行します。

]# cd ..

 # cookbookの実行
knife solo cook {user}@{host}

これで、gitのインストールが実行出来るはずです。

Berkself

先ほどのknife-soloのサンプルでは、cookbookの依存関係を手動で解決しました。 しかし、gitだけで6つものcookbookに依存しているのに、さらに他のcookbookを実行するとなると、依存関係の解決は気の遠くなる作業になります。 そんな、cookbookの依存関係を自動的に解決してくれるツールがBerkselfです。

本家サイトでは、Chefを活用するためのbundler的なツールだと説明されていますが、関Javaな人にはMavenをイメージしてもらうのがわかりやすいと思います。 前述のknife-soloを利用したサンプルとしてgitをリモートサーバにインストールしましたが、その際にgitのcookbook以外にもbuild-essentialなどのcookbookをgitから取得しました。 これは、gitのcookbookがそれらのcookbookに依存しているためです。 Chefではrecipe中にinclude_recipe "..."と記述する事で、Chefのpath中にあるcookbooksに依存した処理を記述する事が出来ます。 これにより、誰かが公開しているcookbooksを別のcookbooksから利用しやすくなっているのですが、同時に必要なcookbookの数が増えてしまい、人力での管理が難しくなってしまいます。 こういった問題については、rubyであればbundler、JavaならMavenScalaならsbtを利用している方々はよくわかるんじゃないかと思います。

インストール

インストールは簡単でgem経由でインストールするだけです。

]# gem install berkshelf

Berksfile

Berkshelfの設定については、基本的にはリポジトリ直下にあるBerksfileを編集します。 そんなに難しい英語を使っているわけでも無いので公式サイトを一読して頂ければだいたいどんな事が出来るのかわかると思います。

コマンド  

Berksfileの編集が完了していれば、berks installコマンドで依存関係を解決する事が出来ます。

]# berks install

ただし、これだけ実行するとberkshelfの初期設定に従って、~/.berkshelf以下に依存するcookbookがインストールされます。 シンプルにChef-soloを利用するだけであれば、ローカルマシンのChefのパスは通っているのでこれで問題ないのですが、Chef-soloを利用してリモートサーバに対してインストールを実行しようとするとこれでは問題があります。

基本的にChef-soloはリポジトリ内のファイルをrsyncでリモートサーバに対して同期するだけなので、基本的にリポジトリ外の依存ファイルを同期する事が出来ません。 そのため、リポジトリ内にcookbookをダウンロードしてくる必要があります。

指定したpathにcookbookをダウンロードするには–pathオプションを利用します。

]# knife solo init {repo}

]# cd {repo}

]# berks install --path ./site-cookbooks

サンプル

knife-soloのサンプルとしてgitのcookbookを利用したサンプルを挙げましたが、次は、同じgitをBerkshelfを利用して実行してみます。 knife-sloの時は依存関係のあるcookbookを自力で全て取得していましたが、今回はBerkshelfの力を存分に発揮してもらいます。

まずは、リポジトリを作成します。今回は、berkrepoというリポジトリを作成します。

]# knife solo init berkrepo
]# cd berkrepo

]# knife solo prepare {user}@{host}

リポジトリが出来たらBerksfileを編集します。knife-soloのinitコマンドを利用して、リポジトリを作成すればデフォルトでBerksfileは作成されるので、以下のように編集します。

Berksfile

site :opscode

cookbooks "git"

nodes/{host}.json

{
  "run_list":[
    "recipe[git::source]"
  ],
  "git":{
    "prefix":"/usr/local/git-berk"
  }
}
]# berks install --path ./site-cookbooks
]# knife solo cook {user}@{host}

まとめ

knife-soloとBerkshelfについて、関Javaでの発表を補足しつつ紹介してみました。 ほんとうに、この組み合わせは鼻血が出るほど素敵なので、ご興味のある方は是非お試しください。