324 Views
March 29, 13
スライド概要
今日から使い始めるChef
2013-03-29
Xtone Ltd. ピザ会 (without pizza><)
Aki / @nekoruri
秋葉原生まれ大手町育ちの歌って踊れる江戸っ子インフラエンジニア。 0と1が紡ぐ「ゆるやかなつながり」に魅せられ早20年、 SNSとCGMの力で世界を幸福にするのがライフワーク。 市民、幸福は義務です。 あなたは幸福ですか?
今日から使い始めるChef 2013-03-29 Xtone Ltd. ピザ会 (without pizza><) Aki / @nekoruri
いくつかの案件がChef管理に移行しました 必ず覚えて欲しいこと
Chef • サーバの構成管理ツール – サーバの「完成状態」を書く – 「現状」との違いを判断する – その差分を埋める • • • • • • パッケージのインストール 設定ファイルの設置 サービスの起動 DBのユーザ作成 ファイアウォール設定 etc. ここ全部 Chefが やってくれる
禁止事項 • サーバ上でrootで設定ファイル変更
禁止事項 • サーバ上でrootで設定ファイル変更 Chefで設定戻されて突然の障害
使ってみる 1. Chefのレポジトリを取ってくる 2. rootで入れるサーバを一台作る 3. 対象サーバにchef-soloを入れる – knife solo prepare [email protected] 4. ノード設定を適当に書く – vim nodes/192.0.2.100.json {"run_list": ["role[base]"]} 5. chef起動 – knife solo cook [email protected]
使ってみる 1. Chefのレポジトリを取ってくる 2. rootで入れるサーバを一台作る 3. 対象サーバにchef-soloを入れる – knife solo prepare [email protected] 4. ノード設定を適当に書く – vim nodes/192.0.2.100.json {"run_list": ["role[base]"]} 5. chef起動 – knife solo cook [email protected] 以降はここだけ
ざっくりChefのしくみのおさらい ざっくりCHEFの紹介
Chef用語 • Resource – 設定の最小単位 – ファイルやパッケージ単位の設定 • Recipe – 複数のResourceで構成されるひとまとまり • Cookbook – Recipeをグループにまとめたもの – 一つのRecipeしか含まない場合もある • レポジトリ(キッチン) – Chefの動作に必要なファイル群 – 複数のCookbookや、ロール・ノードの設定を含む
Chef用語 • ノード – Chefで管理されるサーバ • Role – ノードの役割を定義 – 使うRecipeとか変数とかをここで設定する(抽象化) • chef-solo – サーバ無しでChefを利用するコマンド – chef-soloを動かしたノード自身が操作対象となる • knife-solo – 対象ノードにレポジトリを転送してchef-soloを動かす
Resource
• 設定の最小単位
– ファイル
– パッケージ
– ファイアウォール
template '/etc/apache2/sites-available/www.example.jp' do
source 'www.example.jp.erb'
ファイルを更新したら
mode '0644'
apache2サービスを
action :create
再起動
notifies :restart, "service[apache2]"
end
%w{zsh zip sysstat libcache-cache-perl}.each do |pkg|
package pkg do
action :install
完全にRuby
end
end
firewall_rule "zabbix" do
port 10050
source "192.0.2.5"
action :allow
notifies :enable, "firewall[ufw]"
end
Recipe
• 複数のResourceで構成されるひとまとまり
munin_servers = [' 192.0.2.6/32', ' 192.0.2.140 /32']
package "munin-node"
Rubyの内部DSLなので
変数とかも利用し放題
service_name = node['munin']['service_name']
service service_name do
supports :restart => true
action :enable
end
サーバ毎の設定を利用
template "#{node['munin']['basedir']}/munin-node.conf" do
source "munin-node.conf.erb"
mode 0644
variables :munin_servers => munin_servers
notifies :restart, "service[#{service_name}]"
end
変数をerbに渡す
サーバの情報を利用して分岐
case node['platform']
when "arch", "smartos"
execute "munin-node-configure --shell | sh" do
not_if { Dir.entries(node['munin']['plugins']).length > 2 }
notifies :restart, "service[#{service_name}]"
end
end
Template
log_level 4
log_file /var/log/munin/munin-node.log
port 4949
pid_file /var/run/munin/munin-node.pid
background 1
setseid 1
# Which port to bind to;
host *
user root
group <%= node['munin']['root']['group'] %>
setsid yes
サーバ毎の設定を利用
<% end %>
# A list of addresses that are allowed to connect. This must be a
# regular expression, due to brain damage in Net::Server, which
# doesn't understand CIDR-style network notation. You may repeat
# the allow line as many times as you'd like
引き渡された変数を利用
allow ^127¥.0¥.0¥.1$
<% @munin_servers.sort.each do |server| -%>
cidr_allow <%= server %>
<% end -%>
Cookbookの構成 cookbooks/munin ├── README.md ├── attributes ├── definitions ├── files │ └── default ├── libraries ├── metadata.rb ├── providers ├── recipes │ └── default.rb │ └── server.rb ├── resources └── templates └── default 変数のデフォルト値 erbしない配布ファイル デフォルトのRecipe 「munin」で利用可能 デフォルト以外のRecipe 「munin::server」で利用可能 配布ファイルの置き場 erb利用可能
新しいChefレポジトリを作って、 既存のCookbookを組み合わせて 自分用のRecipeを書いて 実際のノードに適用するまで 一からやってみる
レポジトリを作る • knife-solo gemを入れる % gem install knife-solo • knife soloでレポジトリ作成 % knife solo init demo % cd demo % git init % git add . % git commit -m 'new chef repo'
opscode-cookbooks • Chef開発元が公開しているCookbook集 – オープンソースとして開発 – Github上で公開 https://github.com/opscode-cookbooks/ – Ubuntuなら組み合わせるだけでそのまま使える ※ CentOSだとイマイチという意見多し(未確認) – knifeコマンドで取ってこれる
opscode-cookbooksのインポート • knife cookbookでCookbookを取ってくる % knife cookbook site install apt -o cookbooks % knife cookbook site install users -o cookbooks % knife cookbook site install sudo -o cookbooks % knife cookbook site install mysql -o cookbooks 依存関係を見て引っ張って くるツールがあるが、 今回は未使用 • knife-github-cookbooksというgemもある – github上の任意のCookbookをインポートできる
新しくCookbook/Recipeを作る • knife cookbook createでCookbookを作成 – site-cookbooks以下に置くのが慣習 % knife cookbook create base -o site-cookbooks • Recipeを書いていく % vim site-cookbooks/base/recipes/default.rb include_recipe 'apt' # ユーザ設定 include_recipe 'users::sysadmins' node.override['authorization']['sudo']['passwordless'] include_recipe 'sudo' = true
Roleに経由してRecipeを利用する
• ロールに対して利用するレシピを設定
% vim roles/base.rb
name "base"
description "base packages"
run_list(
'recipe[base]',
'recipe[mysql::server]'
)
default_attributes({
'mysql' => {
'server_root_password' => 'rootpw',
'server_repl_password' => 'replpw',
'server_debian_password' => 'maintpw',
'tunable' => {
'log_bin' => 'mysqld'
}
}
})
Roleに経由してRecipeを利用する • ノードに対してロールを紐付ける % nodes/192.0.2.100.json { "run_list": ["role[base]"], ノード別で異なる設定は "mysql": { ここで定義できる "tunable": { "server_id": "1", "innodb_buffer_pool_size": "2048M", "innodb_log_file_size": "128M" } } }
data_bags
• ユーザ情報などを置いておけるデータ置き場
– chef-solo環境だと、data_bagsディレクトリ内
% data_bags/users/hoge.json
{
"id": "hoge",
"uid": "10001",
"comment": "FOO Bar",
"ssh_keys": [
"ssh-rsa AAAAなんちゃら= [email protected]"
],
"groups": [ "sysadmin" ],
"shell": "/usr/bin/zsh"
}
chef-solo実行 1. 対象サーバにchef-soloを入れる – knife solo prepare [email protected] 2. chef起動 – knife solo cook [email protected]
ありがとうopscode-cookbooksありがとう おすすめCOOKBOOK
apt • aptレポジトリの更新 – https://github.com/opscode-cookbooks/apt – 「include_recipe 'apt'」でapt-getしてくれる – 使わないと古いパッケージを取りに行き失敗
users::sysadminsとsudo • ユーザ管理(users::sysadmins) – https://github.com/opscode-cookbooks/users – data_bagsにsysadminグループのユーザ設定を入 れておくと勝手に作ってくれる – ユーザ追加の度にRecipeを変更しなくてよい • sudoers管理(sudo) – 上記sysadminグループはデフォルトで入ってる
firewall • ファイアウォールのルール設定 – https://github.com/opscode-cookbooks/firewall firewall "ufw" do firewall Cookbookで定義された action :enable 独自リソース end firewall_rule "ssh" do port 22 action :allow notifies :enable, "firewall[ufw]" end – Ubuntu標準ではpingが拒否されているので、 変更したbefore.ruleも配る
apache2 / php
• 各ミドルウェアを入れてくれる
– https://github.com/opscode-cookbooks/apache2
node.default['apache']['listen_ports'] = [80, 443]
node.default['apache']['serversignature'] = 'Off'
node.default['apache']['traceenable'] = 'Off'
include_recipe 'apache2::mod_proxy_http'
include_recipe 'apache2::mod_php5'
include_recipe 'apache2::mod_rewrite'
include_recipe 'apache2::mod_ssl'
include_recipe 'apache2'
include_recipe 'php::package'
include_recipe 'php::module_apc'
include_recipe 'php::module_mysql'
include_recipe 'php::module_gd'
node.default['php']['directives'] = { 'date.timezone' => 'Asia/Tokyo' }
mysql / database
• データベースのユーザを作成する
– https://github.com/opscode-cookbooks/database
include_recipe 'database::mysql'
mysql_connection_info = {
:host => "localhost",
:username => 'root',
:password => node['mysql']['server_root_password']
}
mysql_database 'myapp_production' do
connection mysql_connection_info
action :create
end
mysql_database_user 'myapp_production' do
connection mysql_connection_info
password 'passwordpassword'
database_name 'myapp_production'
host 'localhost'
action :create
end
関連情報 • 伊藤直也さんの電子書籍がベスト – 入門Chef Solo - Infrastructure as Code http://www.amazon.co.jp/dp/B00BSPH158/ http://tatsu-zine.com/books/chef-solo • opscode-cookbooksを読む – 宝の山 – https://github.com/opscode-cookbooks
ぐぬぬ 悩んでいること
Unicorn環境 • unicorn::default – Unicorn gemいれる→普通Bundlerだし – 設定ファイル→アプリと一緒にデプロイするし • application_ruby::unicorn – 似てるようで似てるだけのCapistranoデプロイと いまいち相性が悪い! – runitでUnicornのプロセス自動再起動!すごい! – graceful restartさせると死ぬ!すごい!!1
OpsWorks • AWS + Chef – http://aws.amazon.com/jp/opsworks/ – AWS提供のChef Cookbookを組み合わせる – まだ遊んでない
その他のアプローチ • RightScale / Scalr – もう一つ上のレイヤーでの構成管理したい派 – Xtoneでも某ゲーム案件で利用 • PaaS – そもそもミドルウェアなんて面倒みたくない派 – Heroku、EngineYard、 AWS Elastic Beanstalk ニフクラC4SA、IIJ Mogok