Chef 勉強会 #1

2014-01-31
Shin Tokiwa @ ZEALOT Inc.

Chef がどんなものか
知っている人?

Chef を使ったことある人?

Chef とは?

サーバ環境のメタデータを管理し
役割・状態を収束させる
オペレーションフレームワーク

「自動化ツール」
…ではない!


「ノードの状態を管理」
するものである!

Convergence
(収束)

Recipe を実行することで
最終的にどういう状態になるべきか

Chef の種類

  • Chef Server
    • Chef Server に構築対象ノードの情報を登録
    • 対象ノードで通信先 Chef Server を登録
    • Chef を実行して Recipe を適用

  • Chef Solo
    • 実行する Recipe などの情報は JSON に保存
    • Cookbook や Recipe を対象ノードに転送
    • 対象ノードへは SSH ログインして Recipe を適用

  • (Knife Solo)
    • Knife コマンドの拡張 (サブコマンド)
    • Workstation から対象ノードを操作する感じ

Chef Server

Chef Solo

Knife Solo

ノードの属性

  "kernel": {
    "name": "Linux",
    "release": "3.2.0-48-generic",
    "version": "#74-Ubuntu SMP Thu Jun 6 19:45:16 UTC 2013",
    "machine": "i686",
    ...
  "languages": {
    "ruby": {
      "platform": "i686-linux",
      "version": "1.8.7",
      ...
    "perl": {
      "version": "5.14.2",
      "archname": "i686-linux-gnu-thread-multi-64int"
    },
    "python": {
      "version": "2.7.3",
      "builddate": "Aug 1 2012, 05:16:07"
    },
    ...

ohai

  • Chef はノードの各種情報を集めるために ohai を使用
  • ohai は Opscode によって作られた Gem ライブラリ
  • https://github.com/opscode/ohai

属性によるノード検索

Chef Server 使うとノードの検索も簡単
$ knife search node "platform:centos AND languages_ruby_version:1.8*
$ knife search node "chef_environment:production AND platform:ubuntu"

これらのノードに対して
任意の Recipe や Role を適用する
なんていうことが可能

ノードの構築

  • ノードの構築方法は Run List によって定義
  • Run List には Recipe と Role を指定できる
"run_list": {
  "role[webserver]",
  "role[database_master]",
  "recipe[redis-io]"
}
"run_list": {
  "role[webserver]"
}
"run_list": {
  "role[database_master]",
  "recipe[redis-io]"
}

Chef を構成する主なもの

  • Recipe - ノードがどうあるべきかを記述する
  • File - ノードに配置するファイル
  • Template - ノードに配置するファイルのテンプレート
  • Attribute - 外部から与える属性値
  • Data Bag - ドメインモデル的データ (ユーザなど)
  • Cookbook - 上のものをまとめた概念

Kitchen > Cookbook > Recipe

Chef Repo > Apache2 > Basic Installation (default)
Chef Repo > MySQL > Basic Installation (default)

Kitchen (Repository) の構成

  • chef-repo/ - Kitchen (Repository)
    • cookbooks/ - 3rd Party 製の Cookbook 置き場
      • apache2/
      • mysql/
      • redis-io/
    • data_bags/ - 作成するユーザなどの情報
    • nodes/ - Chef Solo で構築するノードの設定
      • node1.json
      • node2.json
    • site-cookbooks/ - 自作の Cookbook 置き場
      • my-cookbook1/
      • my-cookbook2/

3rd Party Cookbooks

既に誰かによって作られて
しっかりメンテされている
Cookbook は使った方がいい

たくさんの人に見られてバグも収束している

しかし

どんな Recipe なのか
理解した上で使わないと危険

e.g. Apache2 Cookbook

Apache は特に有名なのでメンテが行き届いている

e.g. Apache2 Attribute

e.g. Apache2 Recipes

あらゆるモジュールのインストールにも対応

e.g. Apache2 Default Recipe

ディストリビューションの違いはこうやって吸収…

e.g. Apache2 Template

Convergence
(収束)

Recipe を実行することで
最終的にどういう状態になるべきか

つまりノードの状態更新にも Chef を使うべき

Idempotence
(冪等性)

その操作を複数回行っても結果が同じであるという概念

つまり、何度 Recipe を適用しても
最終的に期待する状態になること

1回目はきちんと動くけど
2回目はコケる…なんていうのはダメ
  • ぶっちゃけ Chef なんか使わずオレオレ Shell でも OK
  • ただし冪等性の担保が難しくなってくる
  • それに複数ディストリビューションに対応するなんてもっと難しい
  • Chef は原則的に冪等に実行できる仕組みを持っている
    • 結局 Chef の実体は Recipe なので書き手による
    • Puppet や Ansible でもそのへんサポートしてるはず

Sample: リポジトリの作成

Opscode が提供しているテンプレートを使うといい
$ git clone git://github.com/opscode/chef-repo.git
$ cd chef-repo
$ tree
.
|-- certificates
|   `-- README.md
|-- chefignore
|-- config
|   `-- rake.rb
|-- cookbooks
|   `-- README.md
|-- data_bags
|   `-- README.md
|-- environments
|   `-- README.md
|-- LICENSE
|-- Rakefile
|-- README.md
|-- roles
|   `-- README.md
`-- tree.txt

Sample: Cookbook の作成

# knife コマンドを使う前に設定
$ knife configure
$ cd chef-repo
$ mkdir site-cookbooks
$ knife cookbook create hello -o site-cookbooks
$ cd site-cookbooks
$ tree
.
`-- hello
    |-- attributes
    |-- CHANGELOG.md
    |-- definitions
    |-- files
    |   `-- default
    |-- libraries
    |-- metadata.rb
    |-- providers
    |-- README.md
    |-- recipes
    |   `-- default.rb
    |-- resources
    `-- templates
        `-- default

Sample: Recipe の編集

$ vim site-cookbooks/hello/recipes/default.rb
# zsh をインストールする

package "zsh" do
  action :install
end
  • Ubuntu であれば apt install zsh として解釈
  • CentOS であれば yum install zsh として解釈

Sample: run_list の設定

$ vim localhost.json
{
  "run_list": [
    "recipe[hello]" # recipe[hello::default] と同義
  ]
}
  • どの Cookbook のどの Recipe を実行するのか指定する
  • この場合には hello という Cookbook の default を指定

Sample: chef-solo の設定

  • Chef Server がないので Solo を実行する WS で設定を持つ
  • 設定ファイルは solo.rb とする

Sample: chef-solo の設定

$ vim solo.rb
file_cache_path  "/tmp/chef-solo"
cookbook_path    ["#{Dir::pwd}/cookbooks", "#{Dir::pwd}/site-cookbooks"]

# Role Settings
# role_path        "#{Dir::pwd}/roles"

# Proxy Settings
# http_proxy       "http://proxy.example.com:8080"
# https_proxy      "http://proxy.example.com:8080
  • Cookbook によってはファイルをダウンロードするものもある
  • Recipe や Attribute ではバージョンなどを指定して
  • バイナリはダウンロードして展開、インストール

Sample: chef-solo の実行

もう1回実行してみる
コケない\(^o^)/

Idempotence
(冪等性)

その操作を複数回行っても結果が同じであるという概念

Chef は Ruby で書かれた DSL

つまり Ruby の構文を使える!

%{ zsh gcc make readline-devel }.each do |pkg|
  package pkg do
    action :install
  end
end
やべーちょー簡単じゃん

Resource について

  • Recipe を書くときに用いる命令を Resource という
  • Chef にはたくさんの Resource が用意されている
  • See: About Resources and Providers

Chef Server vs Chef Solo

  • 結局どっちを使えばいいのか?
  • 使い分けはどうすればいいのか?
  • ~ 十数ノード
    • 小規模なサービスレベル
    • Chef Solo で十分
    • というか Chef Server 導入しても逆に管理が面倒

  • ~ 数十ノード
    • 同じ役割のノードが増えてくる
    • まだ Chef Solo でなんとかなるが…
    • Chef Server の導入を考え始める

  • 数百ノード以上
    • Chef Server 入れないとムリポなレベル

今日のまとめ

  • Chef は3種類のやり方がある
    • Chef Server / Chef Solo / (Knife Solo)
  • Chef Repository の構成
  • Recipe の書き方と実行
  • Resouce
  • Convergence (収束)
  • Idempotence (冪等性)

ご清聴ありがとうございました

Made with Slides.com