LoginSignup
14
16

More than 5 years have passed since last update.

Chef Solo から Chef Client Local Mode にすんなりと移行などできなかった

Last updated at Posted at 2015-10-02

Chef Solo が Deprecated 扱いされてもう1年以上経つので、そろそろ Chef Client Local Mode モードに乗り換えようかと思ったのですが、予想以上に手こずってしまいました。嵌ったところと解決方法をメモしておきます。

検証バージョン

  • Chef Client 12.4.3
  • CentOS release 6.6

そもそも Chef Client Local Mode って?

Chef Solo がローカルの設定ファイルを直接コンパイルしてプロビジョニングするのに対して、Chef Client Local Mode はローカルに揮発性の Chef Server を作り、そこに knife を使って node, cookbook, role 等各種ファイルを登録し、プロビジョニングを行います。

詳しくは Chef Solo ではなく Chef Client Local Mode を使おう - Qiita の「Chef Client Local Mode (旧 Chef Zero) って?」を参照してください。

Chef Solo の時の構成

Chef Solo の頃は、以下のようなディレクトリ構成で各ファイルを管理していました。

/var/chef/chef-repo/
  cookbooks/
  data_bags/
  environments/
  nodes/
  roles/
  site-cookbooks/

また、chef-solo コマンド実行時にいちいち設定ファイルなどを引数で渡さなくて済むよう、以下のように設定ファイルを配置していました。

/etc/chef/solo.rb

cookbook_path [
  "/var/chef/chef-repo/cookbooks",
  "/var/chef/chef-repo/site-cookbooks"
]
json_attribs "/var/chef/chef-repo/nodes/{ノード名}.json"
log_location "/var/log/chef-solo.log"
log_level :info

これで、sudo chef-solo を実行するだけでそのノードに応じた run_list が実行されます。かなり楽でした。

Chef Client Local Mode に変更してハマったところ

JSON じゃないと role が読み込まれない

単純に sudo chef-client -z (-z は Local Mode で動作させるオプション) を実行すれば動くかと思いきや、以下のようなエラーが出て止まってしまいました。

$ sudo chef-client -z

[2015-10-02T13:46:40+09:00] WARN: No config file found or specified on command line, using command line options.
Starting Chef Client, version 12.4.3
[2015-10-02T13:46:42+09:00] ERROR: Role work (included by 'top level') is in the runlist but does not exist. Skipping expand.

================================================================================
Error expanding the run_list:
================================================================================

Missing Role(s) in Run List:
----------------------------
* work included by 'top level'

Original Run List
-----------------
* role[work]


Running handlers:
[2015-10-02T13:46:42+09:00] ERROR: Running exception handlers
Running handlers complete
[2015-10-02T13:46:42+09:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 2.136252085 seconds
[2015-10-02T13:46:42+09:00] FATAL: Stacktrace dumped to /root/.chef/local-mode-cache/cache/chef-stacktrace.out
[2015-10-02T13:46:42+09:00] ERROR: The expanded run list includes nonexistent roles: work
[2015-10-02T13:46:44+09:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)

今回 Chef を実行しているサーバーでは work というロールを指定していたのですが、なぜかそれが発見できないというエラーが出てしましました。

このサーバーの node JSON ファイルは以下のような中身。Chef Solo の頃はこれで問題なく実行できていました。

{
  "run_list": [
    "role[work]"
  ]
}

いろいろ試行錯誤してみた結果、roles/ 配下のファイルを .rb ではなく .json で書き換えたら動くようになりました。Chef 公式ブログの "chef-client -z: From Zero To Chef In 8.5 Seconds" という記事 を見ていたら、data_bags, nodes, roles などのファイルが全て .json で終わっていたので気付きました。

「Chef Client の場合は JSON ファイルじゃなくちゃダメ」という仕様でもあるのでしょうか?私の検索力が足りず、残念ながら発見できませんでした。

作業ディレクトリにキャッシュが作成される

sudo chef-client -z を実行すると、そのコマンドを叩いたディレクトリに local-mode-cache というディレクトリが作成されます。この中にはレシピ内でダウンロードする一時ファイルなどが全てキャッシュされています。このため、作業ディレクトリを変えると Chef は「キャッシュが無いからもう一度ダウンロードしよう」という動きをしてしまいます。

これでは鬱陶しいので、/etc/chef/client.rbfile_cache_path を指定しておくといいでしょう。

node JSON ファイルが強烈に書き換えられる

プロビジョニング前のもともとの nodes/{ノード名}.json は、以下のような内容でした。

{
  "run_list": [
    "role[work]"
  ]
}

ところがプロビジョニング後は、以下のように書き換えられてしまいます。

{
  "name": "{ノード名}",
  "normal": {
    "tags": [

    ],
    "tz": "Asia/Tokyo",
    ...
    (猛烈に長いJSON)
  }
}

このせいで、Chef リポジトリを Git などで管理している場合、git pull しようとするとしばしばコンフリクトします。また、この JSON を使って Chef Solo を実行しようとしても解釈できないらしく、エラーになります。

これについてはまだどう対処するべきか決まっていません。いいアイディアがあればコメントください。

正しくファイルが読み込まれているか確認する方法

cookbooks や roles が正しく読み込まれているかどうかは、knife list をローカルモードで実行すれば確認できます。(Chef Client Local Mode は内部で Knife を呼んでいるので)

$ sudo knife cookbook list -z

build-essential   2.2.3
chef_handler      1.2.0
dmg               2.2.2
...

$ sudo knife role list -z

work

まとめ

最終的に、各種設定ファイルは以下のようになりました。

# /var/chef/chef-repo/.chef/knife.rb

cookbook_path [
  "/var/chef/chef-repo/cookbooks",
  "/var/chef/chef-repo/site-cookbooks"
]
# /etc/chef/client.rb

role_path "/var/chef/chef-repo/roles"
json_attribs "/var/chef/chef-repo/nodes/{ノード名}.json"
log_location "/var/log/chef-client.log"
log_level :info
file_cache_path "/var/chef/cache"

これで sudo chef-client -z を叩くだけでプロビジョニングできるようになりました。いつ Chef Solo が無くなっても安心です。

でもこれ、Chef Solo の代替と呼ぶには複雑すぎるような気がします。Deprecated にしない方がいいと思うのですが…。

参考

14
16
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
16