Slide 1

Slide 1 text

ChefはRubyで出来ている ~サーバもRubyで管理しよう~ 2017/12/2 ながのRUBYの会#1

Slide 2

Slide 2 text

自己紹介  谷口 和哉  長野市在住  自他ともに認める非プログラマ  RubyはSilver認定(を持ってるだけ)  開発は管理しかさせてもらえない  元々インフラ系→セキュリティ系を経て、結局何でも屋さんに落ち着いた  @tmtmsさんの前の席に座ってます  最近はPython勉強中(しろめ)  趣味:Ingress

Slide 3

Slide 3 text

Chefとは  サーバ構成管理ツール  「サーバの状態を定義し、そのとおりにサーバを構成する」ツール  「自動化ツール」とも言われるが、それは余録  「状態」を定義しているので、何度実行してもサーバの結果は同じになる「は ず」  「冪等性(idempotence)」  Rubyで作られている  Chef Serverの一部コア部分のみ、Erlangで記述されている  類似するソフトウェアにPuppet / Ansible / Fablic等がある

Slide 4

Slide 4 text

最近あまり話題になりません…  やはりAnsibleに勢いがある(RedHatが買ったのも大きいか)  Ansibleも良いものだが、Rubyを使っているプログラマの皆様にはやはり Chefの方が親和性が高いと(勝手に)信じており、特に誰から頼まれたわけ でもないが布教開始

Slide 5

Slide 5 text

Chefの記述はRubyの内部DSL  Ruby言語を「ベースにした」記述ができる  リテラル、配列変数、ハッシュ、正規表現、基本的な制御構文(if、case)  特に%w(空白ベースの配列)は大変お世話になる(複数リソースに対して処 理をする時など) %w{ aaaa bbbb cccc }.each do |pkg| package pkg do action :install end end  ただし100%ではない(むしろ使えないものの方が多い)  詳細は「Chef Style Guide」を参照 https://docs.chef.io/ruby.html

Slide 6

Slide 6 text

素のRubyを記述するなら  ruby_blockというリソースがあり、その中であれば自由にRubyで記述で きる ruby_block “リソース名” do block do (Rubyのコードをそのまま書ける) end action :run end  ただしbashリソースと同じ扱いで、その中の冪等性は担保されないので、 そこは自分でなんとかすること  私はつい、bashリソースに走ってしまう(スマン!)

Slide 7

Slide 7 text

Puppetってありますよね  Chefと同様Rubyで記述されたツール  こっちは外部DSLなので、内部の構文はRubyっぽくない  (おなじみngnixのインストール) package { “ngnix”: ensure => “installed” } 先ほどの例(複数のパッケージをインストールする)をPuppetで実施する なら、 package { ensure => “installed” } $pkg = [ aaaa bbbb cccc ] package { $pkg } となる。

Slide 8

Slide 8 text

よく使うリソースTOP5 1. cookbook_file / template 2. directory 3. package 4. bash / execute 5. service 過去、作成したrecipeからざっくり抽出 上位5つでrecipe全体の8割をカバー

Slide 9

Slide 9 text

cookbook_file  Cookbookにあるファイルをサーバに転送する  設定ファイルの配置、インストーラの転送等に大 活躍  配備するファイルの内容を動的に調整するなら template cookbook_file “/etc/hosts” do owner ‘root’ group ‘root’ mode ‘0755’ action :create not_if { File.exist?(“/etc/hosts”) } end 所有者とモードの設定は必ずして おく 「無い場合だけ作成」という create_if_missingというのもあ るが、あまり使わない 例では/etc/hostsが既にあったら 実施しない(not_if制御)としている が「状態を管理」するならば本来は 毎回上書きで良いはず(そうしないと 意図した状態に収束しない) Cookbookのfiles/default/hosts が自動的に選ばれる

Slide 10

Slide 10 text

template  収束の段階で設定ファイルに動的な値を埋め込みたい  RubyのERBによるテンプレートを使う  例: hosts → hosts.erb(cookbookのtemplates/にあるファイルを優先的に、 拡張子.erbを抜いて検索してくれる)  置き換えたいところを<%= @(変数) %>とする  templateリソースで、変数化した部分をattributeに結びつける template “/etc/hosts” do owner ‘root’ group ‘root’ mode ‘0755’ variables( :localip => node[‘server’][‘ipaddress’] ) end  attributeとは ( ゚д゚ )クワッ!! 127.0.0.1 localhost.localdomain <%= @localip %> hoge.fuga.com hosts.erbの例

Slide 11

Slide 11 text

attribute(templateの続き)  Recipeが使用する変数等の値を、Recipe外から取得する仕組み  Recipeの汎用化には必須  node[‘aaa’][‘bbb’]の形式で指定  Ohai(Chefが使用しているOS/HW情報取得ツール)もこのI/F  初期値はCookbookのattributes/default.rbに記載しておける default[‘server’][‘ipaddress’] = ‘192.168.1.1’  適用するサーバ単位で、個別情報を設定することができる “server”: { “ipaddress: “192.168.100.100” } Template hosts.erb Node 情報 hosts 個別node default 指定があれば なければ

Slide 12

Slide 12 text

service  サービス(/etc/init.dに設定されているもの)の状態を定義する  enable / disable → chkconfigやsystemctl上のOn / Off  start / stop → サービス自体の動作 service “ntpd” do supports :restart => true, :status => false action [ :enable, :start ] end  Recipeをまたぐと、serviceリソースを認識できない場合があるので、service の定義と、notifies等で行うrestartアクションは同じrecipe内がベター  大抵が「enable, start」だが、逆に動いていては困るサービスを止めるため にも使う そのサービス(rcスクリプト)が使える命 令を定義できる

Slide 13

Slide 13 text

package  定番過ぎるので、Tips的な例を…  Packageリソース自体は複数の○○_packageの親玉的存在  OSによって、実体がrpm_packageだったりapt_packageだったり  直接○○_packageを指定することも可  Rubygemsのパッケージを入れる「gem_package」は、そのままだとOSに 入っているRubyのGemを操作するが、「Chef自体」に包含されているRubyの Gemを操作する場合は、「chef_gem」を使用する  例: Workstationのknifeにknife-soloを追加する  外部リポジトリではなく、ローカルにあるファイルからインストールしたい場 合は、「source」を指定する。その場合、cookbook_fileリソースであらかじめ コピーすることを忘れずに  大抵が、action:installだが、入っていると衝突するため外しておきたいパッ ケージをaction: uninstallで外すのにも使う  例: OSに最初から入っているmysql-server

Slide 14

Slide 14 text

directory  配備の下準備として、意外に使うことが多い  数えてみたら上位に来た directory “/var/local/hoge” do owner ‘root’ group ‘root’ mode ‘0755’ recursive true action :create end  再帰的に作成する場合は、recursive trueを指定する  同じRecipeの中で作成→使用(中にファイルを入れるとか)をするのは(順序性の問題で) 基本避ける  なんとなくよろしくやってくれる感じではあるのですが…  どうしても必要であれば、別のrecipeにする(run_listには順序性があるため)

Slide 15

Slide 15 text

bash / execute  なんでもできる。ヤバい  よく知られている通り、冪等性が担保されないので、何度実行しても同じ結果になるよう、 recipe作成者が配慮しないといけない  手っ取り早いのは、not_if制約  not_if “コマンド実行” → trueの場合、実行しない(grep等で使用)  not_if { File.exists?(ファイルのPath) } → ファイルがあったら実行しない  not_if { Dir.exist?(ディレクトリのPath) } → Dirがあったら実行しない  逆の「only_if」というのもある(個人的にはあまり使わない)  Shellの本文に、recipe内のRuby変数を入れ込めるので便利 dir = “/tmp/testdir” bash “hogehoge” do user ‘root’ cwd ‘/tmp’ code <<-EOS mkdir #{dir} EOS end bashリソースの外部にある変数を参 照

Slide 16

Slide 16 text

ところで、Itamaeってあり(ry  Rubyとほぼ同じ構文で記述できる互換ツール  国内開発(CookPadのエンジニアの方が開発した)  Rubyとの違いは・・・  エージェントレスである  使えるリソースが限定されてる  directory / execute / file / gem_package / git / group / http_request / link / local_ruby_block / package / remote_directory / remote_file / service / template / user  本家ChefにあるWindows系のリソースは いさぎよくカット  ぶっちゃけ ほぼ網羅してるといえる  ただし同じリソースでもChefとは微妙に挙動が異なったりする  あまりあれこれ求めない場合は有力な選択肢  個人的には「Chefとの微妙な差異」を追いかけるのが大変なので、もっぱら普通 のChefを使っている

Slide 17

Slide 17 text

是非使ってみてください! ※ Chef社から私へのキックバックはありませんwww