はじめまして、WEBサービス開発グループでOJT中で2017年度新入社員の添野です。
みなさんは「プロビジョニング」という言葉を聞いたことがありますか?文献 [1] によればプロビジョニングとは「利用者から要求があった場合や障害時などに、必要な分だけのICTリソースを動的に割り当てる技術」だそうです。
今回はプロビジョニングツールとしてchefを取り上げます。またchefに同梱されているknifeツールのプラグインknife-soloも取り上げます。あわせて動作の確認も行います。なぜchefを紹介しようと思ったのか、それはOJTの業務の中でサーバー構築することがあり、また社内でchefが使用されていたので、今回のOJTでもchefを使用したからです。
まずchefについて簡単に説明をします。chefとは2009年1月に配信が開始されたインフラ構築を自動化するツールで、現在はバージョン13系まで出ています。複数台のマシンに同じ設定を施すときには便利なツールです。
またchefにはchefリポジトリを操作するためのknifeと呼ばれるツールがあります。そしてそのツールをより便利にするknife-soloプラグイン(2017年5月末現在ではバージョン0.6.0)というものがあります。詳細は文献 [2] に譲りますが、イメージは下図の通りです。
Recipe群とSettingsからノードを作成し、chef-clientがインストールされているマシンで、Recipeに記述した通りの手順が展開されていきます。なお図には無いですがknife-soloではリモートサーバーに対してもプロビジョニングを行えます。
chefではすなわちインフラをどのように構築するかという定義をRuby言語のソースコードとして記述していきます。それが先ほどのRecipeにあたります。この処理概念のことを「Infrastructure as Code」と呼びます。なお初心者でも読みやすい本として「Infrastructure as Code(オライリー社出版)」をおすすめしますので、興味を持った方は読んでみてください。
それではchefの世界にどんどん入っていきましょう。まずオムニバスインストーラ [3] を用いてChef Development Kit(以下ChefDK)とchefを導入します。
1 2 |
$ curl -sL https://www.chef.io/chef/install.sh | sudo bash -s -- -P chefdk $ curl -sL https://www.chef.io/chef/install.sh | sudo bash |
なぜオムニバスインストーラが二つ必要なのか。その理由はchefの最新バージョンにおいてレシピの作り方が大きく変わったからです。昔(chefの11系など)は次のような書き方をしていましたが、
1 |
$ knife cookbook create hello -o site-cookbooks |
chefの12系の最新バージョンや13系では次のような書き方をする必要があります。chefコマンドに関してはChefDKをインストールしないといけません。なおchef-soloのみを使う場合には下の行のコマンドだけで十分です。
1 |
$ chef generate cookbook site-cookbooks/hello |
次にknifeコマンドを便利にするknife-soloプラグインのインストールについて説明します。knife-soloのインストールはchefに同梱されているgemコマンドで行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
$ /opt/chef/embedded/bin/gem install knife-solo Fetching: net-ssh-3.2.0.gem (100%) Successfully installed net-ssh-3.2.0 Fetching: net-ssh-gateway-1.3.0.gem (100%) Successfully installed net-ssh-gateway-1.3.0 Fetching: knife-solo-0.6.0.gem (100%) Thanks for installing knife-solo! If you run into any issues please let us know at: https://github.com/matschaffer/knife-solo/issues If you are upgrading knife-solo please uninstall any old versions by running `gem clean knife-solo` to avoid any errors. See http://bit.ly/CHEF-3255 for more information on the knife bug that causes this. Successfully installed knife-solo-0.6.0 Parsing documentation for net-ssh-3.2.0 Installing ri documentation for net-ssh-3.2.0 Parsing documentation for net-ssh-gateway-1.3.0 Installing ri documentation for net-ssh-gateway-1.3.0 Parsing documentation for knife-solo-0.6.0 Installing ri documentation for knife-solo-0.6.0 Done installing documentation for net-ssh, net-ssh-gateway, knife-solo after 3 seconds 3 gems installed |
おやおや?、knife-soloプラグインだけをインストールするつもりが余計なgemファイルが二つインストールされましたね。
この状態でknife-soloを実行してみると・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ knife solo init chef-repo /opt/chef/embedded/lib/ruby/2.4.0/rubygems/specification.rb:2291:in `raise_if_conflicts': Unable to activate knife-solo-0.6.0, because net-ssh-4.1.0 conflicts with net-ssh (< 4.0, >= 2.7) (Gem::ConflictError) from /opt/chef/embedded/lib/ruby/2.4.0/rubygems/specification.rb:1411:in `activate' from /opt/chef/embedded/lib/ruby/2.4.0/rubygems.rb:220:in `rescue in try_activate' from /opt/chef/embedded/lib/ruby/2.4.0/rubygems.rb:213:in `try_activate' from /opt/chef/embedded/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:126:in `rescue in require' from /opt/chef/embedded/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:40:in `require' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/knife-solo-0.6.0/lib/chef/knife/cook.rb:1:in `<top (required)>' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife/core/subcommand_loader.rb:85:in `load' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife/core/subcommand_loader.rb:85:in `block in load_commands' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife/core/subcommand_loader.rb:85:in `each' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife/core/subcommand_loader.rb:85:in `load_commands' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife/core/subcommand_loader.rb:95:in `load_command' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife/core/subcommand_loader.rb:109:in `command_class_from' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife.rb:153:in `subcommand_class_from' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/knife.rb:214:in `run' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/lib/chef/application/knife.rb:156:in `run' from /opt/chef/embedded/lib/ruby/gems/2.4.0/gems/chef-13.1.31/bin/knife:25:in `<top (required)>' from /usr/bin/knife:58:in `load' from /usr/bin/knife:58:in `<main>' |
コンフリクトが起きていますね。
ここで実際にインストール済みgemリストを確認しておきます。
1 2 3 4 |
$ /opt/chef/embedded/bin/gem list | grep net-ssh net-ssh (4.1.0, 3.2.0) net-ssh-gateway (2.0.0, 1.3.0) net-ssh-multi (1.2.1) |
net-sshとnet-ssh-gatewayにおいてバージョン違いのものが混在していますね。どちらかのバージョンをアンインストールする必要があります。
knife-soloプラグインを正常に動作させるため試行錯誤をしました。結果としてchefに元から入っているnet-ssh 4.1.0、net-ssh-gateway 2.0.0をアンインストールするとknife-soloが正常に動作することが判明しています。なおもう一方をアンインストールした場合にはコンフリクトが解消されないことが判明しています。
またGemfileで記述されているchef-soloとknifeについても以下のようなバージョンチェックを緩める細工をする必要があります。
1 2 3 4 |
$ sed -i.bak -e 's/gem \"net-ssh\", \"= 4.1.0\"/gem \"net-ssh\", \"<= 4.1.0\"/' \ > -e 's/gem \"net-ssh-gateway\", \"= 2.0.0\"/gem \"net-ssh-gateway\", \"<= 2.0.0\"/' \ > /opt/chef/bin/chef-solo \ > /opt/chef/bin/knife |
ようやくこれでchefとknife-soloのインストールが完了しました。なおknife-soloのインストールに関してはオチがありますが、それは詳しいことは後編の記事に書きます。急いでいる方は後編をお読みください。
さて、ここからは動作確認をします。今回は簡単のためにHello Worldをログとして出力するレシピの作成、そしてそのレシピを実行してみます。レシピの作成場所はユーザのホームディレクトリ配下としておきます。
まず、以下のコマンドでchef-repoというテンプレートディレクトリを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ knife solo init chef-repo WARNING: No knife configuration file found Creating kitchen... Creating knife.rb in kitchen... Creating cupboards... $ cd chef-repo $ chef generate cookbook site-cookbooks/hello Generating cookbook hello - Ensuring correct cookbook file content - Ensuring delivery configuration - Ensuring correct delivery build cookbook content Your cookbook is ready. Type `cd site-cookbooks/hello` to enter it. There are several commands you can run to get started locally developing and testing your cookbook. Type `delivery local --help` to see a full list. Why not start by writing a test? Tests for the default recipe are stored at: test/smoke/default/default_test.rb If you'd prefer to dive right in, the default recipe can be found at: recipes/default.rb |
「WARNING: No knife configuration file found」はknifeに対する初期設定をしていないために表示された警告です。「knife configure」を用いて初期設定を行うことができますが、今回の場合は設定をしなくても大丈夫ですので割愛いたします。knife configureについて詳しいことは文献 [4] に譲ります。
次に、レシピの本体である~/chef-repo/site-cookbooks/hello/recipes/default.rbに以下の記述を行います。
1 |
log "Hello World" |
次に、どのレシピを実行するかを司る~/chef-repo/nodes/hello.jsonに以下の記述を行います。
1 2 3 4 5 |
{ "run_list": [ "recipe[hello]" ] } |
最後に、クックブックの場所を司る~/chef-repo/solo.rbに以下の記述を行います。
1 |
cookbook_path ["~/chef-repo/site-cookbooks/"] |
総括すると・・・
になります。
最後にユーザーのホームディレクトリ(=今回の場合はchef-repoディレクトリの直上)内で以下のコマンドを実行します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ chef-solo -j chef-repo/nodes/hello.json -c chef-repo/solo.rb Starting Chef Client, version 13.1.31 resolving cookbooks for run list: ["hello"] Synchronizing Cookbooks: - hello (0.1.0) Installing Cookbook Gems: Compiling Cookbooks... Converging 1 resources Recipe: hello::default * log[Hello World] action write Running handlers: Running handlers complete Chef Client finished, 1/1 resources updated in 03 seconds |
結果を見ると「log[Hello World] action write」の行があるので正常に動作していることが分かります。これであなたもchefマスターに一歩近づきましたね。
これにて前編は終了です。ご付き合いいただきありがとうございました。ニフティでのものづくりを垣間見られる「ニフティものづくりブログ」へのご愛顧を今後ともよろしくお願いします。
後編はknife-soloプラグインのインストールについてのオチを記事にします。お楽しみに。