ページ ツリー

比較バージョン

キー

  • この行は追加されました。
  • この行は削除されました。
  • 書式設定が変更されました。

ハンズオン環境の構築

必要なソフトウェア

開発環境の構築には以下のソフトウェアが必要です。
それぞれダウンロード、インストールしてください。

VirtualBox

https://www.virtualbox.org/wiki/Downloads

Vagrant

Connpass

...

※ Vagrant の box やプラグインは環境変数 VAGRANT_HOME のパスに配置されます。

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 の管理下に置きます。

 

コード ブロック
$ vagrant box add <box の名前> <box のファイルパス>

 

  • box の名前:   sl65-x64-chefs_meeting01

  • box のファイルパス: /path/to/sl65-x64-chefs_meeting01.box

※ 登録された box ファイルは $VAGRANT_HOME/boxes に配置されます。

開発環境の立ち上げ

Vagrantfile の存在するディレクトリでコマンドを実行してください。

 

コード ブロック
$ cd chefs_meeting01/
$ vagrant up

 

  • ユーザー: vagrant

  • パスワード: vagrant

...

 

Cookbook のひな形をつくる

chef コマンドで Cookbook のひな形を生成します。

コード ブロック
$ cd workspace
$ chef generate cookbook <Cookbook 名>
  • Cookbook 名: jenkins

 

コマンドを実行すると、以下のファイルが作成されます。

.kitchen.yml

Kitchen の設定ファイル
テスト用のインスタンスや実行するプロビジョニングの設定を記述

Berksfile

Berksfile の設定ファイル
Kitchen でプロビジョニングを行うときの依存する Cookbook を記述

README.md

Cookbook の説明書

chefignore

ChefClient に転送しないファイルを定義

metadata.rb

Cookbook の基本情報を記述

recipes/default.rb

Cookbook がデフォルトで実行する Redipe

 

Eclipse プロジェクトに変換

スクリプトを実行し .project を生成します。

コード ブロック
$ cd <Cookbook 名>
$ gen-eclipse

...

  • プロジェクトをインポート

File -> Import… -> General -> Existing Projects into Workspace

コード ブロック
/home/vagrant/workspace/<Cookbook 名>

 

  • 隠しファイルを表示するように設定する

Package Explorer の ▽ を選択 -> Filters…
「.*resources」のチェックを外す

 

Recipe の書き方

Chef では、インスタンスのあるべき状態を Recipe(ソースコード)として記述します。

Recipe は「ファイルのダウンロード」や「コマンドの実行」など、さまざまな機能をもつ Resource で構成されています。

たとえば、 以下の Recipe は 「bash により “/tmp” ディレクトリで “tar zxf archive.tar.gz” というスクリプトを実行する “extract tar file” という名前の Resource」 を定義したものです。

 

コード ブロック
 

 

 

...

bash “extract tar file” do

 cwd “/tmp”

 code “tar zxf archive.tar.gz”

 action :run

end

 

ここでは Chef 標準の “bash” という Resource の :run という Action を呼び出すように定義していて、“cwd” や ”code” という Attribute によりそのときのパラメータを指定しています。

指定できる Action や Attribute は Resource ごとに異なるので、Chef のドキュメントを確認してください。bash Resource であれば [ http://docs.opscode.com/resource_bash.html ] です。

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 を使えば実現できるでしょうか。

Chef のドキュメントを調べると、file Resource というのが見つかります。これは、任意の内容のテキストファイルを任意のパスに配置する Resource のようです。使えそうですね。

では、file Resource の詳細を確認しましょう。

Chef のドキュメント [ http://docs.opscode.com/resource_file.html ] を参照すると、次のようなシンタックスになっていることが確認できます。

 

...

file <配置先のファイルパス> do

 content <配置するファイルの内容>

end

 

充分に理解できたら、いよいよ具体的なソースコードを実装します。

 

...

file “/etc/profile.d/application.sh” do

 content “export PATH=$PATH:/opt/application/bin

end

 

書けました。

このように Recipe を書くには、

  1. 具体的に何をしたいのかを明らかにする

  2. 使えそうな Resource を探し、仕様を確認する

  3. Recipe を記述する

という手順を繰り返していきます。

 

Jenkins をインストールする Recipe をつくる

まずは、手動で Jenkins をインストールする場合の手順を確認します。

  1. http://pkg.jenkins-ci.org/redhat/ から rpm をダウンロード

  2. ダウンロードした rpm を yum コマンドでインストール

  3. /etc/sysconfig/jenkins を編集して、実行ユーザーを変更

  4. 利用するディレクトリのオーナーを変更

  5. サービスを登録・起動

これを Recipe にしてみましょう。

デフォルトの 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 ]

Chef::Util::FIleEdit [ http://rubydoc.info/gems/chef/Chef/Util/FileEdit ]

※ execute Resource で sed コマンドを実行してもよい

※ file Resource + lazy でもできるかな?

ファイルやディレクトリのオーナーを変更する

ruby_block Resource [ http://docs.opscode.com/resource_ruby_block.html ]

FileUtils#chown_R [ http://docs.ruby-lang.org/ja/1.9.3/method/FileUtils/m/chown_R.html ]

※ execute Resource で chown コマンドを実行してもよい

サービスを起動する / 自動的に起動するように登録する

service Resource [ http://docs.opscode.com/resource_service.html ]

 

.kitchen.yml の編集

作成した Recipe が期待したとおりに動いているか確認してみましょう。

確認には Kitchen を利用すると便利です。

Kitchen とは、任意の環境をインスタンスとして起動し、プロビジョニングを行い、その結果を検証できるツールです。インスタンスは何度でも簡単に作り直すことができるので、気軽に Chef の Recipe を試すことができます。

まずは Kitchen を使用するために、設定ファイル .kitchen.yml を編集しましょう。

 

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です。

 

source "https://api.berkshelf.com"

cookbook ‘tar'

cookbook 'java'

metadata

 

※ Opscode Community 以外の依存

 

Kitchen インスタンスの起動とプロビジョニング

では、作成した Cookbook を Kitchen のインスタンスへプロビジョニングしてみましょう。

 

...

$ kitchen setup

 

プロビジョニングが成功したら、Kitchen インスタンスにログインしてみてください。

 

[vagrant] $ kitchen login

kitchen@localhost’s password: kitchen

[kitchen] $ sudo service jenkins status

jenkins (pid 17656) を実行中...

[kitchen] $ exit

 

ログインできたら、jenkins サービスが実行されているか確認してみましょう。

/etc/sysconfig/jenkins の内容も確認してみてください。

うまくいっていない場合は、Cookbook を修正し、次のコマンドでプロビジョニングをやり直します。

 

...

$ kitchen converge

 

以前プロビジョニング結果が原因でプロビジョニングがうまくいかない場合は、次のコマンドで Kitchen インスタンスを破棄してから、再度プロビジョニングを実行します。

 

...

$ kitchen destroy

$ kitchen setup

 

※ kitchen の主なサブコマンド

 

...

# インスタンスの生成

kitchen create

 

# Chef-Solo のインストールと初回のプロビジョニング

kitchen setup

 

# プロビジョニング

kitchen converge

 

# Serverspec の実行

kitchen verify

 

# ssh ログイン

kitchen login

 

# インスタンスの破棄

kitchen destroy

 

 

Web ブラウザで Jenkins にアクセス

docker コマンドでコンテナのポートを確認します。

 

...

$ docker ps

CONTAINER ID  PORTS
e35e89ea252a    0.0.0.0:49153->22/tcp, 0.0.0.0:49154->8080/tcp

 

コンテナの 8080 ポートがホストの 49154 にフォワーディングされていることが確認できます。

Firefox などの Web ブラウザで http://localhost:49154/ にアクセスしてみてください。

Jenkins の画面が表示されていれば成功です。

Attribute に対応させる

Attribute とは

Recipe にパラメータを与える仕組みです。

プロビジョニング時に Attribute を指定することで、Recipe の動作などを変化させることができるようになります。

Attribute を指定するには

Attribute は Key - Value 形式のデータで、指定する方法はプロビジョニングツールにより異なります。

  • Kitchen の場合
    .kitchen.yml の attributes に、YAML形式で定義

 

...

attributes:

 application:

   version: ‘2.0.0’

 

  • Vagrant の場合
    Vagrantfile の chef.json に、Hash で定義

 

...

config.vm.provision :chef_solo do |chef|

 chef.json = {

   application: {

     version: ‘2.0.0’

   }

 }

 

  • Knife の場合
    knife node edit で Json ファイルを編集

 

...

"normal": {

 “application”: {

   “version”: {}

 }

}

 

※ 実際の運用では knife を使っていないので、間違っているかもしれません。

 

Attribute の値を Recipe で 使う

Recipe から Attribute の値を参照するには、node オブジェクトを利用します。

Attribute が以下のように設定されている場合、

 

...

attributes: {

 application: {

   version: ‘2.0.0’

 }

}

 

Recipe では以下のように node オブジェクトを経由して、目的の Attribute の値を取得できます。

 

...

application_version = node[‘application’][‘version’]

 

Attribute にデフォルト値をセットする

Attribute にはプロビジョニングツールで値が指定されなかった場合のデフォルト値を指定しておくことができます。

デフォルト値は専用のファイルに記述します。ファイルは chef コマンドで生成できます。

 

...

chef generate attribute ./ default

 

./attributes/default.rb というファイルが生成されますので、以下のようにデフォルト値を定義します。

 

...

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 のルール番号が含まれています。

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 を実行するには、専用のパスにテストコードを置く必要があります。

まずはテストコードを置くディレクトリを作成しましょう。

 

...

$ mkdir -p ./test/integration/default/serverspec/

 

※ “default” の部分は .kitchen.yml で指定した suites の name

テストコードは *_spec.rb というファイル名で配置します。

 

...

$ touch ./test/integration/default/serverspec/default_spec.rb

 

※ 「*」の部分はなんでもいいようですが、Recipe の名前と同じにするのをよく見かけます。

 

Serverspec のテストコードの記述

たとえば、あるパスにファイルが存在することを確認するには、以下のように記述します。

 

require 'serverspec'

include Serverspec::Helper::Exec

include Serverspec::Helper::DetectOS

describe file('/etc/passwd') do
 it { should be_file }
end

 

Serverspec では簡単な記述でサーバーの状態をテストできるように、様々な Resource が用意されています。

詳細は Serverspec のドキュメント [ http://serverspec.org/resource_types.html ] を参照してください。

Kitchen で Serverspec を実行

Kitchen インスタンスで Serverspec のテストを実行するには次のコマンドを使用します。

 

...

$ kitchen verify

 

そうすると、Serverspec のテストが実行され、次のようにテスト結果のログが出力されます。

 

...

Service "jenkins"

   should be running

      

Finished in 0.04041 seconds

1 example, 0 failures

 

※ 「kitchen verify」以外に、「kitchen test」というコマンドもあります。

 

Vagrant で Cookbook をつかう

Vagrantfile の書き方

Vagrantfile は主に次の 3 つのブロックに分かれます。

Vagrant の基本的な設定

ベース box やネットワーク、共有ディレクトリなどの設定を記述します。

 

...

config.vm.box = ‘sl65-x64-chefs_meeting01’

 

Provider の設定

VirtualBox の VM の CPU コア数やメモリサイズなどの設定を記述します。

 

...

config.vm.provider :virtualbox do |vbox|

 vbox.customize [‘modifyvm’, :id, ‘--memory’, '2048']

 vbox.customize [‘modifyvm’, :id, ‘--cpus’, '2']

end

 

設定項目などは 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 のコマンドで、現在の開発環境に対してプロビジョニングを行います。

 

...

$ vagrant provision

 

うまくいけば、現際の開発環境上で Jenkins サービスが起動していて、http://localhost:8080 で Jenkins にアクセスできるようになります。

 

 

 

 

資料

 

コンテンツ

子ページ表示
alltrue