Ruby
chef
vagrant
VirtualBox
chef-zero

Chef-clientとKnife-zeroを触ってみた記録

More than 3 years have passed since last update.

新卒エンジニアがChef-clientとknife-zeroを使ってみた記録です。
まだまだ勉強中なのですが、Chef-zeroに関してだったり、情報が色々あって混沌としていたのでまとめてみました。

『初めてChefを触るぜ!!』という読者が、最終的には『リモートサーバーの環境設定、管理をChefでやってみよう!!』と思えるようになることがこの投稿の目標です。

1. Chef(シェフ)って?

コードでサーバー環境を整備、管理するツール

本家によると

Chefはインフラをコードにする。Chefを使えば、ビルドやデプロイ、インフラのマネジメントを自動で行うことができる。するとアプリケーションのコードのようにインフラがバージョン管理やテスト、繰り返し可能になるぜ!!

⊂二二二( ^ω^)二⊃ブーン
なるほど!!
つまりミスが減るのか(ざっくり...)!!
自動でというのがキーですねw

これまでの環境整備と管理は、サーバーにSSHなどでログインし、人が手順書に従って1つずつ作業してました。

  • スペルミス
  • 時間がかかる(一つの作業もですが、サーバーが増えると...)
  • 手順書の更新忘れ
  • あれっどこまでやってたっけ?ってなる

といった問題が考えられます(他にもいろいろ)。
以上の問題をコードを実行して 自動化 することで、解決しようというツールです。
問題を経験したことがない人はぜひドットインストールでさくらVPSの設定開発環境で行ってみてください。

2. 実際に触ってみる

ゴールは『サーバーにSSHログインせずに、Chefコマンドをリモート実行で環境整備・管理』することですが、まずはゲストOS上に『SSHログインしてみて、Chefコマンドを叩いて環境整備・管理』を実行してみます。

2-1. 仮想環境の準備(VirtualBoxとVagrant)

サンプル実行時の環境は

  • MacOSX(Yosemite:10.10.3)(ホストOS)
  • VirtualBox(4.3.26)
  • Vagrant(1.6.5)
  • CentOS6.6(ゲストOS)

VirtualBoxとVagrantに関しては他の記事をどうぞ!!

Mac上でターミナルを開き作業をはじめます。

'''bash
$ mkdir testchef01
$ cd testchef01
```

Vagrantfileを以下のように作成し

Vagrantfile
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "opscode-centos-6.6"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/vmware/opscode_centos-6.6_chef-provisionerless.box"
  config.vm.network "private_network", ip: "192.168.33.100"
end

仮想環境を立ち上げます。

$ vagrant up

これで仮想環境が立ち上がりました。
次にsshでログインを行います。

$ vagrant ssh

2-2. Chef-dk(Chef-DevelopmentKit)の導入

ゲストOSにchef-dkを導入します

$ curl -O https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chefdk-0.5.1-1.el6.x86_64.rpm

気長に待ちます...
ダウンロードできたら

sudo rpm -Uvh chefdk-0.5.1-1.el6.x86_64.rpm

これで必要なツールはすべてインストールされました。

2-3. Chefを使ってみる

ここでは基本的なChefの機能を触ってみます。

まずはChefのリポジトリを作ります。

$ chef generate repo chef-repo
$ cd chef-repo

chef-repo/をホームとして作業を進めていきます。
続いてクックブックというものを作成します。
クックブックはツールをインストールする際に必要になるデータやファイルをまとめたディレクトリです。
今回はapacheをインストールして起動してみます。

$ chef exec knife cookbook create apache -o cookbooks

これでcookbooksの中にapacheという名前のクックブックが作成されました。
それではレシピを編集していきます。
レシピはサーバー設定の手順書のようなものです。

cookbooks/apache/recipes/default.rb
package "httpd" do
  action :install
end

service "httpd" do
  action [ :enable, :start ]
end

httpdをインストールして、起動してねと書いてます。
package、 service等をリソースといいます。
では実行して実際にレシピを適用してみます。
その前にどのレシピを使うかChefに教えてあげる必要があります。
json形式でファイルを作成します。

centos.json
{
  "run_list":[
    "recipe[apache]"
  ]
}

新しくレシピを追加したら、ここに追加してから実行する必要があります。
結構忘れるので気をつけてくださいw
では今度こそ実行します。

$ sudo chef exec chef-client --local-mode -j centos.json

完了したらブラウザで192.168.33.100にアクセスしてみてください。
apacheのテストページが表示されていればOKです。

続いてアトリビュートという機能を使ってみます。
これは、レシピに汎用性を持たせるために変数が使えるよという機能です。
mysqlを入れてみます。

$ chef exec knife cookbook create mysql -o cookbooks

mysqlのクックブックのひな形ができました。
レシピを作ります。

cookbooks/mysql/recipes/default.rb
%w{mysql mysql-server}.each do |pkg|
  package pkg do
    action :install
  end
end

service "mysqld" do
  action [ :enable, :start ]
end

execute "set root password" do
  command "mysqladmin -u root password '#{node['mysql']['server_root_password']}'"
  only_if "mysql -u root -e 'show databases;'"
end

12行目にある#{node['mysql']['server_root_password']}はRubyの変数展開です。
ではこの変数を設定します。
ファイルを作成します。

cookbooks/mysql/attributes/default.rb
default['mysql']['server_root_password'] = "password"

これでmysqlのクックブックができました。
ではcentos.jsonに追加します。

centos.json
{
  "run_list":[
    "recipe[apache]",
    "recipe[mysql]"
  ]
}

run_listに追加したら実行します。

$ sudo chef exec chef-client --local-mode -j centos.json

mysqlがインストールされて、mysql -u root -ppasswordでmysqlのコンソールに入ることができるようになりました。

この項の最後としてテンプレートという機能を使ってみます。
設定ファイル等を予め準備しておいて、書き込みを行う機能です。
iptablesの設定を例に作ってみたいと思います。

$ chef exec knife cookbook create iptables -o cookbooks

レシピを記述していきます。

cookbooks/iptables/recipes/default.rb
template "/etc/sysconfig/iptables" do
  source "iptables.erb"
  owner "root"
  group "root"
  mode 0644
end

service "iptables" do
  action [ :enable, :start ]
  supports :status => true, :restart => true
end

templateというリソースが出てきました。
/etc/sysconfig/iptablesファイルにiptables.erbを適用するという意味を持ってます。
iptables.erbを作成します。

cookbooks/iptables/template/default/iptables.erb
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:SERVICES -    [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT
-A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -j SERVICES
-A INPUT -p udp --sport 53 -j ACCEPT
-A INPUT -p udp --sport 123 --dport 123 -j ACCEPT
-A SERVICES -p tcp --dport 22 -j ACCEPT
-A SERVICES -p tcp --dport 80 -j ACCEPT
-A SERVICES -p tcp --dport 443 -j ACCEPT
COMMIT

内容についてはさくらVPSの設定で確認してください。

erbということなのでテンプレート内でもアトリビュート機能は使えます。

今回は使いませんが...
ではcentos.jsonにiptablesを追加して、chefを実行します。

centos.json
{
  "run_list":[
    "recipe[apache]",
    "recipe[mysql]",
    "recipe[iptables]"
  ]
}
$ sudo chef exec chef-client --local-mode -j centos.json

iptables -Lコマンドで設定が適用されているのが確認できます。

この節では
sshログインを行ってサーバー上でChefコマンドを叩いて環境設定を行いました。
これらの設定を次はサーバーにSSHログインせずに、Chefコマンドをリモート実行して環境整備・管理を行いました。

ではexitコマンドでホストに戻って下さい

3. リモートサーバーの環境設定をしてみる

上記の2、3の部分をリモート実行によって行えば目的は達成できます。
それを可能にするchefクライアントがknife-zeroです。

ではMac上にchef-dkをインストールします。
https://opscode-omnibus-packages.s3.amazonaws.com/mac_os_x/10.8/x86_64/chefdk-0.5.1-1.dmg

待ちます...
ダウンロードが完了したら、実行してください。
ツールのインストールが始まります。

インストールが完了すればターミナルに戻ってknife-zeroを入れます。

$ chef gem install knife-zero

これでknife-zeroが入りました。
新しく作業ディレクトリを作ります。

$ cd ~
$ mkdir testchef02
$ cd testchef02

再びVagrantfileを作成します。
ipの値を2-3で使ったファイルとは違う値にしているので気をつけてください。

Vagrantfile
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "opscode-centos-6.6"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/vmware/opscode_centos-6.6_chef-provisionerless.box"
  config.vm.network "private_network", ip: "192.168.33.101"
end

vagrant upで立ち上げます。
少し雰囲気を出すためにhostsを編集します。

$ sudo vi /etc/hosts
#最後の行に以下の一行を追加
192.168.33.101 testchef01.com

2-3で作成したchef-repoを引っ張ってきます。

$ git clone https://github.com/Islands5/chefsample01.git
$ cd chefsample01

ここをメインに作業を行います。
設定ファイルを書きます。

$ mkdir .chef
$ echo 'local_mode true' >> .chef/knife.rb

2-3では使いませんでしたが、ロールというものを使います。
説明は後ほど...
role/example.jsonを開いてみてください

role/example.json
{
    "name": "example",
    "description": "This is an example role defined as JSON",
    "chef_type": "role",
    "json_class": "Chef::Role",
    "default_attributes": {
    },
    "override_attributes": {
    },
    "run_list": [
        "recipe[example]"
    ]
}

run_listの部分を編集し、recipeを追加していきます。

role/example.json
#編集
    "run_list": [
        "recipe[apache]",
        "recipe[mysql]",
        "recipe[iptables]"
    ]
#

それではサーバーに適用します。

$ chef exec knife zero bootstrap testchef01.com -x vagrant -Pvagrant --sudo -r 'role[example]'

少し待ちます。
完了すれば、ブラウザでtestchef01.comにアクセスするとapacheのテストページが確認できます!!

-xはユーザー名
-Pはパスワード(鍵認証を使った設定方法もあります)
--sudoはリモートサーバー上でsudo権限で実行してねという指示(つまりパスワードなしでsudoできる権限をもったユーザーじゃないと実行できない)
-rはroleかrecipeを適用するのですが、今回はroleを渡しました。

ロールは、アプリサーバーやデータベースサーバーといった役割の違いを役割別にレシピをまとめておく機能
今回はただ単にまとめてレシピを記述できるという点に着目して使いました。

以上が今回調べてみてわかったことです。

4. まとめ

『初めてChefを触るぜ!!』という読者が、最終的には『リモートサーバーの環境設定、管理をChefでやってみよう!!』と思えるようになることを目標に記事を作成しました。
仮想環境を使って『SSHログインしてみて、Chefコマンドを叩いて環境整備・管理』することからスタートします。その際、chefの便利な機能の一部として、パッケージのインストール、アトリビュートの適用、テンプレートの適用を触ってみました。最後にメインである『サーバーにSSHログインせずに、Chefコマンドをリモート実行で環境整備・管理』を行いました。
同じ手法を用いることで、ドメイン名がわかっているホスト+sudoをパスワードなしで実行できる権限を持ったユーザー(リモート上で)があればリモート実行が可能になります。
次はさくらVPSに対して行ってみようと思っています。
また、今回はクックブックを作成しましたが、Berkshelfを使えば有志が作ったクックブックを使うことができます。

5. あとがき

本投稿では触れなかったchef-soloやknife-soloに関しての今後はこちらの記事が大変わかりやすいです。
記事によるとknife-soloから乗り換えを急ぐ必要は無いとということです。なぜならknife-soloも内部でChef-clientローカルモードを利用するように検討されているそうです。みんなknife-soloはchef-soloと心中しないぞ!!

今日もいい天気だ\(^o^)/

用語集

クックブック
レシピやテンプレート、アトリビュート等をまとめたフォルダ
レシピ
リソースを並べたRubyコード、環境構築の手順書
リソース
package、service、execute、templateといったサーバーの状態を記述している命令
テンプレート
設定ファイル等を予め準備しておいて、書き込みを行う機能
アトリビュート
レシピに汎用性を持たせるために変数が使えるよという機能
ロール
アプリサーバーやデータベースサーバーといった役割の違いを役割別にレシピをまとめておく機能
ノード
サーバーのことをノードといったりします

参考資料

サイト

Chef-SoloからChef-Clientローカルモードへの移行: http://www.creationline.com/lab/6380
Chef-dkを使ってみよう: http://www.creationline.com/lab/6255
knife-zero: https://github.com/higanworks/knife-zero
knife-zeroでInfrastructure as Codeを始めよう: http://www.creationline.com/lab/6718
chef界隈のまとめ: http://www.creationline.com/lab/9840
技術的な文章を書くための1,2,3歩: http://qiita.com/vvakame/items/d657baf26cf83ac98bd0

書籍

Chef実践入門