ハンズオン環境の構築
必要なソフトウェア
開発環境の構築には以下のソフトウェアが必要です。
それぞれダウンロード、インストールしてください。
VirtualBox
https://www.virtualbox.org/wiki/Downloads
Vagrant
http://www.vagrantup.com/downloads.html
※ Vagrant の box やプラグインは環境変数 VAGRANT_HOME のパスに配置されます。
Vagrant プラグイン
開発環境の構築には以下の Vagrant プラグインが必要です。
それぞれインストールしてください。
vagrant-omnibus
ゲストマシンに Chef をインストールしてくれるプラグインです。
コード ブロック |
---|
$ vagrant plugin install vagrant-omnibus |
vagrant-vbguest
VirtualBox の Guest Additions をホストの VIrtualBox に合わせて更新してくれます。
...
コード ブロック |
---|
$ vagrant plugin install vagrant-vbguest |
必要なファイルをコピー
USB メモリの chefs_meeting01 ディレクトリをコピーしてください。
※ コピー先のパスに特殊文字などが含まれてはいけません。
box の登録
ベース box を Vagrant の管理下に置きます。
...
※ 登録された box ファイルは $VAGRANT_HOME/boxes に配置されます。
開発環境の立ち上げ
Vagrantfile の存在するディレクトリでコマンドを実行してください。
...
※ 起動した VM は VirtualBox のデフォルトの仮想マシンフォルダに配置されます。
Cookbook のひな形をつくる
chef コマンドで Cookbook のひな形を生成します。
...
コマンドを実行すると、以下のファイルが作成されます。
.kitchen.yml
Kitchen の設定ファイル
テスト用のインスタンスや実行するプロビジョニングの設定を記述
Berksfile
Berksfile の設定ファイル
Kitchen でプロビジョニングを行うときの依存する Cookbook を記述
README.md
Cookbook の説明書
chefignore
ChefClient に転送しないファイルを定義
metadata.rb
Cookbook の基本情報を記述
recipes/default.rb
Cookbook がデフォルトで実行する Redipe
Eclipse プロジェクトに変換
スクリプトを実行し .project を生成します。
...
Eclipse で .project をインポートします。
プロジェクトをインポート
File -> Import… -> General -> Existing Projects into Workspace
コード ブロック |
---|
/home/vagrant/workspace/<Cookbook 名> |
隠しファイルを表示する
Package Explorer の ▽ を選択 -> Filters…
「.*resources」のチェックを外す
Recipe の書き方
Chef では、インスタンスのあるべき状態を Recipe(ソースコード)として記述します。
Recipe は「ファイルのダウンロード」や「コマンドの実行」など、さまざまな機能をもつ Resource で構成されています。
...
コード ブロック |
---|
remote_file “/tmp/archive.tar.gz” do source “http://path/to/archive.tar.gz” action :create end bash “extract tar file” do cwd “/tmp” code “tar zxf archive.tar.gz” action :run end |
Recipe を書く手順
Recipe を書くにはまず、「具体的に何をしたいのか」を明らかにし、それに対し「どの Resource を使用するか」を決めなければなりません。そうしてからようやく具体的なソースコードを記述できます。
たとえば、あるアプリケーションのコマンドにパスを通すために、/etc/profile.d/application.sh に 「export PATH=$PATH:/opt/application/bin」 という内容のファイルを配置したいとします。
これはどの Resource を使えば実現できるでしょうか。
...
具体的に何をしたいのかを明らかにする
使えそうな Resource を探し、仕様を確認する
Recipe を記述する
という手順を繰り返していきます。
Jenkins をインストールする Recipe をつくる
まずは、手動で Jenkins をインストールする場合の手順を確認します。
...
デフォルトの Recipe なので、chef generate cookbook で生成された recipes/default.rb を編集します。
ヒント
コマンドを実行する
execute Resource [ http://docs.opscode.com/resource_execute.html ]
ファイルをダウンロードする
remote_file Resource [ http://docs.opscode.com/resource_remote_file.html ]
※ ダウンロードしたファイルなどは /tmp ではなく Chef::Config[:file_cache_path] に保存する
パッケージをインストールする
package Resource [ http://docs.opscode.com/resource_package.html ]
テキストファイルの内容を置換する
ruby_block Resource [ http://docs.opscode.com/resource_ruby_block.html ]
...
※ file Resource + lazy でもできるかな?
ファイルやディレクトリのオーナーを変更する
ruby_block Resource [ http://docs.opscode.com/resource_ruby_block.html ]
...
※ execute Resource で chown コマンドを実行してもよい
サービスを起動する / 自動的に起動するように登録する
service Resource [ http://docs.opscode.com/resource_service.html ]
.kitchen.yml の編集
作成した Recipe が期待したとおりに動いているか確認してみましょう。
確認には Kitchen を利用すると便利です。
...
コード ブロック |
---|
driver: name: docker provisioner: name: chef_solo platforms: - name: centos-6.4 driver_config: image: centos forward: 8080 suites: - name: default run_list: - recipe[tar::default] - recipe[java::default] - recipe[jenkins::default] attributes: java: install_flavor: oracle jdk_version: 7 java_home: /usr/java/default oracle: accept_oracle_download_terms: true |
ポイント
driver
軽量・高速な docker を使用します。
Kitchen から docker を利用するには kitchen-docker のインストールが必要です。
コード ブロック |
---|
$ chef gem install kitchen-docker |
※ 今回の環境には既にインストールされています。
driver_config
centos をベース image とします。
利用できる image 名は Dockerfile の FROM 句で指定できるものと同じです。
詳細は Dockerfile のリファレンスを参照してください。
[ https://docs.docker.com/reference/builder/#from ]
forward ではホストマシンにフォワーディングするポート番号を指定します。
今回は jenkins が使用する 8080 ポートに http://localhost:8080 でアクセスできるように指定しています。
詳細は kitchen-docker のドキュメントを参照してください。
[ https://github.com/portertech/kitchen-docker ]
run_list
プロビジョニング時に実行する Recipe を指定します。
Jenkins の動作には Java が必要なので、今回は Opscode Community の java Cookbook を使うことにします。
また、java Cookbook の動作には tar が必要なので、これも Opscode Community の tar Cookbook を使います。
自作した jenkins Cookbook も忘れずに指定しましょう。
※ プロビジョニングに外部の Cookbook が必要な場合は後述する Berksfile の編集が必要です。
attributes
プロビジョニング時に Recipe にわたす Attribute を指定します。
Attribute とは Recipe に対するパラメータのようなものです。
今回は Opscode コミュニティの java Cookbook の Attribute を指定しています。
詳細は java Cookbook の README.md を参照してください。
[ http://community.opscode.com/cookbooks/java ]
Berksfile の編集
プロビジョニング時に必要な外部の Cookbook は、このファイルをもとに berkshelf によって解決されます。Opscode Community の Cookbook であれば、次のように名前を指定するだけでOKです。
...
Git リポジトリ
git: ‘https://path/to/cookbook.git’ローカルファイルシステム
path: ‘/path/to/cookbook’
Kitchen インスタンスの起動とプロビジョニング
では、作成した Cookbook を Kitchen のインスタンスへプロビジョニングしてみましょう。
...
コード ブロック |
---|
# インスタンスの生成 kitchen create # Chef-Solo のインストールと初回のプロビジョニング kitchen setup # プロビジョニング kitchen converge # Serverspec の実行 kitchen verify # ssh ログイン kitchen login # インスタンスの破棄 kitchen destroy |
Web ブラウザで Jenkins にアクセス
docker コマンドでコンテナのポートを確認します。
...
コンテナの 8080 ポートがホストの 49154 にフォワーディングされていることが確認できます。
Firefox などの Web ブラウザで http://localhost:49154/ にアクセスしてみてください。
Jenkins の画面が表示されていれば成功です。
Attribute に対応させる
Attribute とは
Recipe にパラメータを与える仕組みです。
プロビジョニング時に Attribute を指定することで、Recipe の動作などを変化させることができるようになります。
Attribute を指定するには
Attribute は Key - Value 形式のデータで、指定する方法はプロビジョニングツールにより異なります。
...
Knife の場合
knife node edit で Json ファイルを編集コード ブロック "normal": { “application”: { “version”: {} } }
※ 実際の運用では knife を使っていないので、間違っているかもしれません。
Attribute の値を Recipe で 使う
Recipe から Attribute の値を参照するには、node オブジェクトを利用します。
...
コード ブロック |
---|
application_version = node[‘application’][‘version’] |
Attribute にデフォルト値をセットする
Attribute にはプロビジョニングツールで値が指定されなかった場合のデフォルト値を指定しておくことができます。
...
コード ブロック |
---|
default[‘application’][‘version’] = ‘1.0.0’ |
jenkins Cookbook を Attribute に対応させる
何を Attribute にするか
Cookbook の設計次第で何を Attribute にするかは変わります。
今回は次の項目を Attribute にしてみましょう。
Jenkins のバージョン
特定のバージョンの Jenkins をインストールしたくなるかもしれないJenkins の rpm ファイルの URL
将来的に、rpm ファイルの URL が変更されるかもしれないJenkins の実行ユーザー
特定のユーザーで Jenkins を実行したくなるかもしれない
ヒント
Attribute の名前
一般的には、「node[<Cookbook の名前>][<任意の Attribute 名>]」とすることが多いようです。
Recipe の中で自身の Cookbook 名を取得するには cookbook_name Method [ http://docs.opscode.com/dsl_recipe_method_cookbook_name.html ] を利用できます。
※ ./attribute/defualt.rb では利用できません。
Kitchen で確認
対応が完了したら、.kitchen.yml に作成した Attribute を追記して、Kitchen インスタンスでプロビジョニングを行い確認してみましょう。
コード ブロック |
---|
$ kitchen destroy $ kitchen setup $ kitchen login kitchen@localhost’s password: kitchen |
Cookbook のテスト
Foodcritic [ http://acrmp.github.io/foodcritic/ ]
Chef 専用の静的テストツールで、ChefDK に含まれています。
Cookbook のルートディレクトリでコマンドを実行すると、Chef のお作法に違反したコードなどが検出されます。
...
警告のメッセージには Foodcritic のルール番号が含まれています。
Foodcritic の公式サイトには各ルールの詳細な情報と修正例が記載されていますので、参考にしてください。
Ruby の静的テストツールを利用する
Recipe は Ruby で記述されているので、Ruby の汎用的な静的テストツールを利用することもできます。
Reek [ https://github.com/troessner/reek ]
複雑なコードを検出する静的テストツール
コード ブロック |
---|
$ reek ./ |
Flay [ http://ruby.sadi.st/Flay.html ]
重複コードを検出する静的テストツール
コード ブロック |
---|
$ flay ./ |
これらのツールは gem でインストールできるものです。
ChefDK の gem にインストールするには、以下のようにコマンドを実行します。
コード ブロック |
---|
chef gem install <gem パッケージ名> |
※ 今回の環境では reek、flay は既にインストールされています。
ChefSpec [ https://github.com/sethvargo/chefspec ]
Chef 専用の動的テストツールで、ChefDK に含まれています。
主に Recipe が期待通りにコンパイルされているかを確認します。
単純な Recipe の場合は Recipe と ChefSpec のテストコードがほとんどイコールになってしまい、ただ同じことを2度書いているだけになってしまいます。
いま運用している規模では ChefSpec を利用するメリットが見いだせないので利用していません。
Serverspec [ http://serverspec.org/ ]
サーバーの状態をテストする動的テストツールです。Chef 専用のものではありませんが、Kitchen が標準で対応しています。今回は Kitchen から利用することを前提にすすめます。
Serverspec のテストコードの配置
Kitchen で Serverspec を実行するには、専用のパスにテストコードを置く必要があります。
...
※ 「*」の部分はなんでもいいようですが、Recipe の名前と同じにするのをよく見かけます。
Serverspec のテストコードの記述
たとえば、あるパスにファイルが存在することを確認するには、以下のように記述します。
...
Serverspec では簡単な記述でサーバーの状態をテストできるように、様々な Resource が用意されています。
詳細は Serverspec のドキュメント [ http://serverspec.org/resource_types.html ] を参照してください。
Kitchen で Serverspec を実行
Kitchen インスタンスで Serverspec のテストを実行するには次のコマンドを使用します。
...
※ 「kitchen verify」以外に、「kitchen test」というコマンドもあります。
Vagrant で Cookbook をつかう
Vagrantfile の書き方
Vagrantfile は主に次の 3 つのブロックに分かれます。
Vagrant の基本的な設定
ベース box やネットワーク、共有ディレクトリなどの設定を記述します。
コード ブロック |
---|
config.vm.box = ‘sl65-x64-chefs_meeting01’ |
Provider の設定
VirtualBox の VM の CPU コア数やメモリサイズなどの設定を記述します。
...
設定項目などは VirtualBox のドキュメント [ https://www.virtualbox.org/manual/ch08.html#vboxmanage-modifyvm ] を参照してください。
Provisioner の設定
Chef で実行する Recipe や Attribute などの設定を記述します。
コード ブロック |
---|
config.vm.provision :chef_solo do |chef| # cookbook のあるディレクトリの相対パスを指定 chef.cookbooks_path = [‘cookbooks’, ‘site-cookbooks’] # 実行する Recipe を指定 chef.run_list = [ ‘java’, ‘eclipse’ ] # Attribute を指定 chef.json = { java: {}, eclipse: {} } |
cookbook のディレクトリについて
一般的に、./cookbooks ディレクトリに Community Cookbook や Git リポジトリから取得した Cookbook を配置し、
./site-cookbooks ディレクトリにこの Vagrantfile で起動する VM 専用の Cookbook を配置します。
jenkins Cookbook を Vagrant で
jenkins Cookbook を配置
まずは、作成した jenkins Cookbook を site-cookbnooks ディレクトリに配置しましょう。
Vagrantfile を編集
作成した jenkins Cookbook を現在の開発環境に対して実行できるように Vagrantfile を編集してみてください。
プロビジョニングを実施
編集が完了したら、vagrant のコマンドで、現在の開発環境に対してプロビジョニングを行います。
...