Knife-Zero まとめ
前回のData Bagの記事に加え、サーバー構成管理ツールKnife-Zeroおよび関連ツールの使い方を備忘録として記します。 なおRecipeの書き方については今回割愛させていただきます。
Knife-Zeroについて
Chef-Serverなどを介さずに直接サーバーにChefのインストール、Cookbook(サーバーをよしなにセットアップしてくれるやつ)を実行してくれるものです。素でChefを使うよりも楽に管理できると先輩氏から聞いています。
弊社のサーバー構成管理ツール群の中でのKnife-Zeroの立ち位置は以下となります。
- Capistrano…Railsの管理
- Knife-Zero…AWSで定義したサーバーの中で動くソフトウェア(nginxなど)の管理
- Terraform…AWSの管理
Knife-Zero基本コマンド
リモートサーバーの追加
~/.ssh/config
を編集し対象のサーバーにアクセスできるようにした状態で、
bundle exec knife zero bootstrap -N [ノード名] -x [SSHのユーザー名] --sudo [SSHのサーバー名]
-N
…Knife-Zero管理するノード名-x
…Knife-Zero実行時にSSHするときのユーザー名--sudo
…Knife-Zeroのbootstrapをsudoで実行する
もろもろファイルがつくられるので、バージョン管理できます。
Cookbook追加
CookbookはChefで実際にサーバーのセットアップをしてくれるRecipeなどがまとまったものです。Coookbookの中にはRecipeの他に、セットアップに必要なnginx.confなどのファイルなども管理されています。
例: Server1というCookbookがあり、中にはnginx, td-agentという使うソフトウェアをひとつひとつセットアップするRecipeがある
bundle exec knife cookbook create [Cookbook名] -o [作成先のPATH]
作成先のPATHはbootstrap後にできるknife.rbにデフォルト値を指定することもできます。
Cookbookの設定
Berkshelfによる依存性解決
Bundlerみたいな形で、Cookbook毎に依存性を解決できるツールです。
Cookbook内で依存性を記述した後、berks vendor
コマンドで依存性解決してくれます。
ただし、berksコマンドで色々セットアップすると、Thorfile, Vagrantfileなど用途によっては不必要なファイルなどもいっぱい作られる… ただ依存性を解決してくれれば十分なので、弊社では以下のような形でつかっています。
- 特定のCookbookディレクトリにBerksfile(BundlerでいうGemfileみたいなもの)を作成
- 特定のCookbookディレクトリにあるmetadata.rbに依存性
depends
を記述 - Berksfileに以下のように
metadata
を記述し、berks vendor
でmetadata.rbに記述した依存性を解決してもらう
source "https://supermarket.getchef.com" metadata
Berkshelfによる依存性解決コマンド
bundle exec berks vendor [Cookbook群が格納されているディレクトリPATH] -b [BerksfileのPATH]
-b
…該当のCookbookのBerksfileを指定
なぜCookbook群が格納されているディレクトリPATHを指定してるかというと、Berkshelfのcookbook_pathはKnife-Zeroのcookbook_pathと自動で同じにはならないからです。BundlerでいうとRailsのディレクトリをわざわざ指定しないといけない感じかと。
Berkshelfを使う場合、Knife-ZeroのCookbook群が格納されているディレクトリを意識して指定する必要があります。
他にもBerkshelfで引っかかるポイントとして、Recipeの内容を変更した後もberks vendor
コマンドを実行しないと、サーバー先に変更が反映されません。デプロイ前にberks vendor
コマンドを必ず実行するように注意する必要があります。
Recipeの設定
attributes
Chef Supermarkedt公開されているCookbookを使う際、細かな情報を指定するときに記述します。
例えばnginxのCookbookに関しては、node['nginx']['dir']
やnode['nginx']['conf_template']
などが指定できます。
file
nginx.confなどサーバーに配置したいファイルを管理できます。
fileディレクトリは以下に配置することで、cookbook_file
でRecipe中に指定し、配置先を指定することでデプロイ先に配置されます。
templates
fileと似た形ですが、ERBを使い動的にファイルを生成したい場合に使います。
パスワードなど、秘密情報のバージョン管理
Data Bagを使います。前回記事参照。
ノードへのCookbookの設定
作成したCookbookはノードに以下のコマンドでアサインする必要があります。
bundle exec knife node run_list add [ノード名] [Cookbook名]
不必要なCookbookを削除する場合は以下
bundle exec knife node run_list remove [ノード名] "recipe[Cookbook名]"
デプロイ
Berkshelfを使用しているため、前述の通りberks vendor
コマンドを使わないとRecipeの変更が反映されません。
そのため以下のようにしてデプロイします。
- 変更したCookbookに対して
berks vendor
を実行 - 変更したいノード(サーバー)に対し、
knife converge
コマンドを実行
bundle exec knife zero converge name:[ノード名]
まとめ
今回Knife-Zero及び関連ツールで忘れやすいコマンド、ポイントをまとめました。あまり綺麗でないサーバー環境で、いきなりDocker化するのも難しい状況があると思います。そんなときKnife-Zeroが使える時があるかと。いろいろつまづきやすいところも多いかと思いますが、所感としてはBerkshelfをさわっているときが一番禿げそうでした。少しでもこの記事がサーバー管理者のストレス軽減につながれば幸いです。
追記: Knife-ZeroとBerkshelfを使う際の便利な設定方法
@sawanobolyさんから教えていただきました。
Cookbookマネージャと一緒に · Knife-Zero
以下のようにKnife-Zeroにbefore hookが用意されており、それを使いノード追加のbootstrap
コマンド、デプロイのconverge
コマンド実行前にberks vendor
を実行する方法です。
coobook_path [ File.expand_path('../../berks-cookbooks', __FILE__) ] knife[:before_bootstrap] = "berks vendor" knife[:before_converge] = "berks vendor" ## ex. under the bundler environment. # knife[:before_bootstrap] = "bundle/chef exec berks vendor" # knife[:before_converge] = "bundle/chef exec berks vendor"
上記の場合、弊社のスタイルと違いKnife-Zeroを管理するディレクトリ配下に単一のBerksfileを起き、各Cookbookの依存関係を記述するスタイルになるかと思います。 ちょうどRailsのディレクトリにGemfileを置く形に似ています。 以下のリンクも参考になるかと思います。
Provisioning Remote server accessible by SSH with Chef and knife-zero · GitHub
弊社のようにCookbook毎にBerksfileを用意するとCookbookごとの依存関係が明確になる良い点ありますが、上記の形で管理するとオペレーション断然楽になると思います。良い!
@sawanobolyさんありがとうございます!