256bitの殺人メニュー

インフラエンジニアだったソリューションアーキテクトなくわののブログ。こちらのBlogは個人の意見となっていて会社とは全く関係ありません。お約束です。[twitter:@kuwa_tw]めんどくさがりが重い腰を上げて何かをアウトプットすることにどれほどの意味があるのかを試してみたいブログでもある。

Cookbookの管理を楽にするBerkshelfの使い方( ー`дー´)キリッ とか。

子供が生まれたり、職場では人事改革が行われたり、@さんがスマートフォンアプリエンジニアになったりと、生活が激変しつつある今日この頃みなさまいかがお過ごしでしょうか。
はい、乙カレー様です。くわのです。


職場ではずっとchef-server 1本で来ていたわけなのですが、ちょっと前からchef solo+Berkshelfを使い始めたりしている私達がいます。
きっとみなさんchef-serverとか強がりやがってやっと素直になりやがったなと思っていることでしょう。
(Chef-serverも使い方で便利ですよ)


ドキュメント読んだらいいのかと思ったりもするんだけどBerkshelfのドキュメントがあんま綺麗じゃなくて困るというw
ちゅーことで、ざっくり使い方を整理しました。あ、Berkshelfのバージョンは3です。

Berkshelf

BerkshelfはCookbookの依存性を管理するためのソフトウェアです。
主な目的としては2つあり、

  • Cookbookの依存性の確保
  • Cookbookのバージョン管理

です。
例えば、Webサーバを構築するための[webserver]という、Cookbookがあったとして、[webserver]は、nginxを使用するために[nginx]のCookbookに依存しているような場合などです。
更にCookbookバージョンが変わることによる冪等性の確保のため、Cookbookのバージョン管理も行えます。

Berkshelfのインストール

割愛、、、bundleとかで。

$ cat Gemfile 
source 'https://rubygems.org'

gem "berkshelf"
$ bundle install

Berkshelf用のCookbookのひな形作成

Berkshelfを実行するためのCookbookのひな形作成

$ berks cookbook berks-cookbook

Berkshelfの設定

まずは基本的なBerkshelfの動作設定についてですが、これはconfig.jsonに設定します。
デフォルトだとワーキングディレクトリ ~/.berkshelf/ 以下の config.json にあります。


なくてもデフォルトで動きますが、Githubに繋ぎたい場合等は設定が入りますので指定してください。


ちなみに、berkshelfのワーキングディレクトリを変更したい場合は環境変数 BERKSHELF_PATH を指定します。

ex.)
export BERKSHELF_PATH=/usr/local/etc/berkshelf/
config.jsonの設定項目

こんなかんじです。

- chef.chef_server_url - Chefサーバの管理画面URL
- chef.node_name - ChefのClientNameの設定、デフォルトはknifeがあればそこから取得
- chef.client_key - clientキーの設定。
- chef.validation_client_name - validateキー(Chefにおけるrootみたいなもの)の設定
- chef.validation_key_path - validateキー(Chefにおけるrootみたいなもの)ファイルの場所
- vagrant.vm.box - Vagrantで使用するBoxの名前の指定(default: Berkshelf-CentOS-6.3-x86_64-minimal)
- vagrant.vm.box_url - VirtualBoxのBoxのあるURLの指定 (default: https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box)
- vagrant.vm.forward_port - host->guestでforwardするportの設定
- vagrant.vm.provision - Chefのprovisionerの指定、chef_solo or chef_client. (default: chef_solo)
- ssl.verify - SSL接続を確認するかどうか。(default: true)
- cookbook.copyright - 新しいCookbookを生成する際に含めるコピーライト表示
- cookbook.email - 新しいcookbookが作成された時にメールを飛ばす先. デフォルトはknifeがあればそこから取得
- cookbook.license - 新しいcookbookで使用するライセンス。 デフォルトはknifeがあればそこから取得
- github - Github credentials 必要なcookbookをダウンロードするときに使うものをHashのArrayで入れる。

Berksfile

次に取得するCookbookを指定するためのBerksfileを設置。
Berksfileに記述するCookbookはコミュニティクックブック、Berks-API、Gitレポジトリ、LocalFilePathなどを指定する事ができます。

Berksfileの設定項目

Berksfileの記述ですが、下に例を貼りました。
コミュニティCookbook等のBerks-API経由のものに関してはバージョン指定が可能ですし、Gitレポジトリ管理しているものに関してはTag指定での取得が可能です。
一般的にコミュニティCookbookはバージョン=Tag指定になっているものが多いので自分たちで作る際もそれに習っておくのが良いね。うん。
berkshelfの公式のAPI指定は前まではapi.berkshelf.comだったんですが、Supermarketのリリースにともなってhttps://supermarket.getchef.comに変更になったようです。
また、自分たちでBerks-APIを立てることもできます。依存関係を一括管理する場合は自分たちのBerks-APIを立てるのがいいと思います。
その場合はひろせさんのこちらの記事が参考になります(ありがとうございます)

# Berks-API指定
# source "https://api.berkshelf.com"
source "https://supermarket.getchef.com"

# コミュニティクックブック
cookbook 'yum'

# コミュニティクックブック(バージョン指定)
cookbook 'yum-epel' , ">= 0.4.0"

# Gitレポジトリ
cookbook 'ca_sysctl', git: 'http://git.example.com/ca-cookbooks/ca_sysctl.git'

# Gitレポジトリ(tag指定)
cookbook 'ca_td-agent', git: 'http://git.example.com/ca-cookbooks/ca_td-agent.git' , tag: "1.0.0"

# LocalFilePath
cookbook 'webserver', path: '/Users/kuwano/cookbook/directory/somewhere/webserver'
cookbook 'nginx-test', path: '/Users/kuwano/cookbook/directory/somewhere/nginx-test'
cookbook 'apache-test', path: '/Users/kuwano/cookbook/directory/somewhere/apache-test'

主要なコマンドの使い方

berksコマンドの主要な使い方について。コマンドリファレンス的な物があんまり無いんだよね、、、なんでか、、、。

Berkshelfの使い方の流れ

Berkshelfでの作業の流れは大体このようになるかと思います。

  • Berkshelfのひな形作成(berks cookbook berks-cookbook)
  • Cookbookのインストール(berks install)
  • (Cookbook記述作業)
  • Cookbookのアップデート(berks update [Cookbook名])
  • Cookbookのインストール(以下繰り返し)
Berksfileのバージョン確認

berks versionコマンド。

$ berks version
3.1.1
Berksfileのひな形作成

上でもやったberks cookbookです。

$ berks cookbook berks-cookbook
      create  berks-cookbook/files/default
      create  berks-cookbook/templates/default
      create  berks-cookbook/attributes
      create  berks-cookbook/libraries
      create  berks-cookbook/providers
      create  berks-cookbook/recipes
      create  berks-cookbook/resources
      create  berks-cookbook/recipes/default.rb
      create  berks-cookbook/metadata.rb
      create  berks-cookbook/LICENSE
      create  berks-cookbook/README.md
      create  berks-cookbook/CHANGELOG.md
      create  berks-cookbook/Berksfile
      create  berks-cookbook/Thorfile
      create  berks-cookbook/chefignore
      create  berks-cookbook/.gitignore
         run  git init from "./berks-cookbook"
      create  berks-cookbook/Gemfile
      create  .kitchen.yml
      append  Thorfile
      create  test/integration/default
      append  .gitignore
      append  .gitignore
      append  Gemfile
      append  Gemfile
You must run `bundle install' to fetch any new gems.
      create  berks-cookbook/Vagrantfile
cookbookのインストール

まず、Cookbookをberkshelfのワーキングディレクトリへとインストールしましょう。
berks installコマンドを使用します。
ここでインストールしたCookbookが実際のchef soloで使用されるCookbookとなります。

Resolving cookbook dependencies...
Fetching 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Fetching 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Fetching 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Fetching cookbook index from https://supermarket.getchef.com...
Using 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Using 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Installing apt (2.4.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing ark (0.8.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing build-essential (2.0.4) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing chef_handler (1.1.6) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing consul (0.2.3) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing cron (1.4.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing erlang (1.5.4) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing golang (1.3.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing rabbitmq (3.2.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing redisio (1.7.1) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing rsyslog (1.12.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing runit (1.5.10) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing selinux (0.8.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing sensu (1.0.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing ulimit (0.3.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing windows (1.31.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum (3.2.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-epel (0.3.6) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-erlang_solutions (0.2.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-repoforge (0.3.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)


このタイミングで作成される、Berksfile.lockにインストールされたCookbookのバージョンや、依存関係の情報が含まれています。
Berksfile.lockファイルが既に存在していればその記述バージョンのCookbookがインストールされます。

DEPENDENCIES
  apt
  consul
  cron
  selinux
  sensu
  webserver
    git: http://git.example.com/ca-cookbooks/webserver.git
    revision: 998d3e415e43c900e3f043513fa72bff6b1441c0
  yum
  yum-epel

GRAPH
  apt (2.4.0)
  ark (0.8.2)
  build-essential (2.0.4)
  chef_handler (1.1.6)
  consul (0.2.3)
    ark (~> 0.8.0)
    golang (~> 1.3.0)
    runit (>= 0.0.0)
    yum-repoforge (>= 0.0.0)
  cron (1.4.0)
  erlang (1.5.4)
    apt (>= 1.7.0)
    build-essential (>= 0.0.0)
    yum (~> 3.0)
    yum-epel (>= 0.0.0)
    yum-erlang_solutions (>= 0.0.0)
  golang (1.3.0)
  rabbitmq (3.2.2)
    erlang (>= 0.9.0)
  redisio (1.7.1)
    ulimit (>= 0.1.2)
  rsyslog (1.12.2)
  runit (1.5.10)
    build-essential (>= 0.0.0)
    yum (~> 3.0)
    yum-epel (>= 0.0.0)
  selinux (0.8.0)
  sensu (1.0.0)
    apt (>= 0.0.0)
    rabbitmq (>= 2.0.0)
    redisio (>= 1.7.0)
    windows (>= 1.8.8)
    yum (>= 0.0.0)
  ulimit (0.3.2)
  webserver (0.1.1)
    apt (>= 0.0.0)
    rsyslog (>= 0.0.0)
    selinux (>= 0.0.0)
    sensu (>= 0.0.0)
    yum (>= 0.0.0)
    yum-epel (>= 0.0.0)
  windows (1.31.0)
    chef_handler (>= 0.0.0)
  yum (3.2.0)
  yum-epel (0.3.6)
    yum (~> 3.0)
  yum-erlang_solutions (0.2.0)
    yum (~> 3.0)
  yum-repoforge (0.3.0)
    yum (~> 3.0)
    yum-epel (>= 0.0.0)
新しいバージョンのCookbookがないか確認

コミュニティクックブックはすごいスピードでリリースされるので、インストールしたタイミングから新しいCookbookが出てることも少なくありません。新しいCookbookの存在を確認するにはberks outdatedを使います。
もしCookbookの更新があればこのように出力されます。

$ berks outdated
The following cookbooks have newer versions:
  * ark (0.8.2 => 0.9.0) [https://supermarket.getchef.com]
  * consul (0.2.3 => 0.3.0) [https://supermarket.getchef.com]
  * erlang (1.5.4 => 1.5.6) [https://supermarket.getchef.com]
  * golang (1.3.0 => 1.4.0) [https://supermarket.getchef.com]
  * sensu (1.0.0 => 2.0.0) [https://supermarket.getchef.com]
  * windows (1.31.0 => 1.34.0) [https://supermarket.getchef.com]
  * yum (3.2.0 => 3.2.2) [https://supermarket.getchef.com]
  * yum-epel (0.3.6 => 0.4.0) [https://supermarket.getchef.com]
Cookbookを最新状態に更新

berks updateコマンドを使用する事でberks outdatedで示されたような変更を適用する事が出来ます。
berks updateを引数を指定しなければ、全Cookbookの強制アップデートになりますが、これを行うとCookbookの挙動が変わった場合に動作が意図したものでなくなる場合があるので、テストなどを行った上で実行しましょう。


実行時にBerksfile.lockが更新されます。


berks update [Cookbook名]
とすることで、Cookbook毎にアップデートが可能なので、アップデートが必要なCookbookのみアップデートするようにしましょう。

実行例としてはこのような感じになります。

$ berks update
Resolving cookbook dependencies...
Fetching 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Fetching 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Fetching 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Fetching cookbook index from https://supermarket.getchef.com...
Using 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using 'nginx-test' from http://git.example.com/ca-cookbooks/nginx-test.git (at master)
Using 'apache-test' from http://git.example.com/ca-cookbooks/apache-test.git (at master)
Using apt (2.4.0)
Using ark (0.8.2)
Using build-essential (2.0.4)
Using chef_handler (1.1.6)
Installing consul (0.3.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using cron (1.4.0)
Installing erlang (1.5.6) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using golang (1.3.0)
Using rabbitmq (3.2.2)
Using redisio (1.7.1)
Using rsyslog (1.12.2)
Using runit (1.5.10)
Using selinux (0.8.0)
Installing sensu (2.0.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using ulimit (0.3.2)
Using webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
Installing windows (1.34.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum (3.2.2) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Installing yum-epel (0.4.0) from https://supermarket.getchef.com ([opscode] https://supermarket.getchef.com/api/v1)
Using yum-erlang_solutions (0.2.0)
Using yum-repoforge (0.3.0)


個別に実行した場合はこのようになります。

$ berks update webserver
Resolving cookbook dependencies...
Fetching 'webserver' from http://git.example.com/ca-cookbooks/webserver.git (at master)
Fetching cookbook index from https://supermarket.getchef.com...
Using apt (2.4.0)
Using ark (0.8.2)
(snip)
Using webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using windows (1.34.0)
Using yum (3.2.2)
Using yum-epel (0.4.0)
Using yum-erlang_solutions (0.2.0)
Using yum-repoforge (0.3.0)
現状使用されているCookbookを一括で出力

berkshelfで取得したCookbookを実行するための一般的な方法としてはknife soloが一般的だと思いますが。
各サーバにCookbookを直接配ったり、CI用途等でサーバにCookbookをおきたいときがあるかもしれません。


その場合にはberks vendorコマンドでCookbook群を出力します。
デフォルトではberkshelf実行ディレクトリ配下のberks-cookbook/ディレクトリに出力されます。

$ berks vendor
Resolving cookbook dependencies...
Using apt (2.4.0)
Using ark (0.8.2)
Using build-essential (2.0.4)
Using chef_handler (1.1.6)
Using consul (0.2.3)
Using cron (1.4.0)
Using erlang (1.5.4)
Using golang (1.3.0)
Using rabbitmq (3.2.2)
Using redisio (1.7.1)
Using rsyslog (1.12.2)
Using runit (1.5.10)
Using selinux (0.8.0)
Using sensu (1.0.0)
Using ulimit (0.3.2)
Using webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
Using windows (1.31.0)
Using yum (3.2.0)
Using yum-epel (0.3.6)
Using yum-erlang_solutions (0.2.0)
Using yum-repoforge (0.3.0)
Vendoring apt (2.4.0) to /Users/akuwano/berksdir/berks-cookbooks/apt
Vendoring ark (0.8.2) to /Users/akuwano/berksdir/berks-cookbooks/ark
Vendoring build-essential (2.0.4) to /Users/akuwano/berksdir/berks-cookbooks/build-essential
Vendoring chef_handler (1.1.6) to /Users/akuwano/berksdir/berks-cookbooks/chef_handler
Vendoring consul (0.2.3) to /Users/akuwano/berksdir/berks-cookbooks/consul
Vendoring cron (1.4.0) to /Users/akuwano/berksdir/berks-cookbooks/cron
Vendoring erlang (1.5.4) to /Users/akuwano/berksdir/berks-cookbooks/erlang
Vendoring golang (1.3.0) to /Users/akuwano/berksdir/berks-cookbooks/golang
Vendoring rabbitmq (3.2.2) to /Users/akuwano/berksdir/berks-cookbooks/rabbitmq
Vendoring redisio (1.7.1) to /Users/akuwano/berksdir/berks-cookbooks/redisio
Vendoring rsyslog (1.12.2) to /Users/akuwano/berksdir/berks-cookbooks/rsyslog
Vendoring runit (1.5.10) to /Users/akuwano/berksdir/berks-cookbooks/runit
Vendoring selinux (0.8.0) to /Users/akuwano/berksdir/berks-cookbooks/selinux
Vendoring sensu (1.0.0) to /Users/akuwano/berksdir/berks-cookbooks/sensu
Vendoring ulimit (0.3.2) to /Users/akuwano/berksdir/berks-cookbooks/ulimit
Vendoring webserver (0.1.1) to /Users/akuwano/berksdir/berks-cookbooks/webserver
Vendoring windows (1.31.0) to /Users/akuwano/berksdir/berks-cookbooks/windows
Vendoring yum (3.2.0) to /Users/akuwano/berksdir/berks-cookbooks/yum
Vendoring yum-epel (0.3.6) to /Users/akuwano/berksdir/berks-cookbooks/yum-epel
Vendoring yum-erlang_solutions (0.2.0) to /Users/akuwano/berksdir/berks-cookbooks/yum-erlang_solutions
Vendoring yum-repoforge (0.3.0) to /Users/akuwano/berksdir/berks-cookbooks/yum-repoforge


tar.gz形式で出力したい場合はberks packageコマンドを使います。

$ berks package
Cookbook(s) packaged to /Users/akuwano/berksdir/cookbooks-1407290309.tar.gz


これらを実行したいサーバ等に持って行くことで単体での実行を行うことができます。

あるCookbookが他のどのCookbookから使われているか表示

berks contingent で調べることが出来ます。

$ berks contingent yum
Cookbooks in this Berksfile contingent upon 'yum':
  * sensu (1.0.0)
  * webserver (0.1.1)
  * yum-epel (0.3.6)

この場合、Cookbook[yum]は、webserverと、yum-epel, sensuから使われている事がわかります。

Cookbookのメタ情報表示

Cookbookのメタ情報を表示するコマンドはberks info [Cookbook名]です。

$ berks info yum
        Name: yum
     Version: 3.2.0
 Description: Configures various yum components on Red Hat-like systems
      Author: Chef
       Email: cookbooks@getchef.com
     License: Apache 2.0
   Platforms: redhat (>= 0.0.0)
              centos (>= 0.0.0)
              scientific (>= 0.0.0)
              amazon (>= 0.0.0)
              fedora (>= 0.0.0)
インストールされてるCookbook表示

現在インストールされてるCookbookを表示するのはberks listです。

$ berks list
Cookbooks installed by your Berksfile:
  * webserver (0.1.1) from http://git.example.com/ca-cookbooks/webserver.git (at master)
  * apt (2.4.0)
  * ark (0.8.2)
  * build-essential (2.0.4)
  * chef_handler (1.1.6)
(snip)
  * yum-epel (0.3.6)
  * yum-erlang_solutions (0.2.0)
  * yum-repoforge (0.3.0)
Cookbookの検索

berks search [Cookbook名で]コミュニティクックブックを検索できます。

$ berks search redis
php-redis (0.1.1)
redis (3.0.4)
redis-package (1.0.0)
redis-test (0.2.0)
redis2 (0.5.0)
redis_2_cookbook (0.3.3)
redisio (1.7.1)
現在使っているCookbookの実際のサーバ上での位置を表示する

Berkshelfを使っていると、~/.berkshelf/cookbooks/に同じような名前のCookbook(hoge-22a4059e11eab1f727ddf38f1160e04285e26cf9
hoge-33a4059e11eab1f727ddf38f1160e04285e26cc9 とか)が増えてきて、どっちが使ってる奴だよ、みたいになることがたまーにあるんですが、berks show 使うと今使っているCookbookが出力されます。

$ berks show hoge
/Users/akuwano/.berkshelf/cookbooks/hoge-22a4059e11eab1f727ddf38f1160e04285e26cf9


ということで、hoge-33a4059e11eab1f727ddf38f1160e04285e26cc9 は消しても問題ないわけですね。( ´∀`)つ ミ● <-[hoge-33a4059e11eab1f727ddf38f1160e04285e26cc9]

おまけ1:CookbookのChef Serverへのアップロード

もし、Berkshelfで使ったCookbookをChef-serverにアップロードしたい場合はberks uploadコマンドを使います。
Cookbookの管理にBerkshelfを使って、実行はchef client経由でしたい。バージョン管理はChef-server側で行いたい、等の場合はberks uploadしましょう。

$ berks upload
おまけ2:Cookbookの依存関係を画像出力

berks vizコマンドを使用すると管理しているCookbookの依存関係を図示したものが生成されます。
graphvizをインストール(brew等が簡単)してから実行してください。


こんなん↓

つかれた

最後の方ちょっと(ちょっと?)雑になってんなと思った方。それは正しい。
Berkshelfをこれから使う方にちょっとでも役に立てばいいなーとか思ったり思わなかったりします。


ではではー三(卍 〓ω〓))卍


Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)

Chef実践入門 ~コードによるインフラ構成の自動化 (WEB+DB PRESS plus)