2011/06/27

第1回 DevOpsカンファレンスのお礼と話したことの補足



こんにちは。「ふいんき」と書いて「なぜか変換できない」の流れをやろうとしたらgoogle日本語入力だと余裕で変換できてしまい、沸き起こる複数の感情と戦っているhiroshiです。

去る2011/06/25(金)、DevOpsカンファレンスという勉強会でスピーカーをやらせてもらいました。そのお礼と、お話の補足をさせていただこうと思います。
勉強会での発表は社を代表した内容にしたつもりですが、このエントリは、けっこう個人的な想いを多めにしてますので、もし異論反論ありましたら@hiroshi19790209までください><。

去年末の「ZABBIX勉強会」以来のスピーカーで、あのときの参加者が60人くらい、今回も最初は80人くらいの募集だったから「実際くるのは応募人数の8掛けで60人くらいだろうから、このくらいの人数だったら経験済みだぜ!」と思って立候補したら、参加枠が120人まで伸びた上に当日もほとんどまんま120人近くの方が参加してきて、@marqsさん恐るべしな感じでした。

謝辞
@marqsさん、@kuwa_twさん、ぼくにしゃべらせてくれてありがとうございました!また呼んでください!
@さん、「こんな感じの内容であってるのかなぁ」、とビクビクしていたのですが、「カルチャー」の話のおかげで、気楽に話せました。気楽過ぎたかもしれません><
@riywoさん、僕もシャイボーイなのでちょっとしかお話できなかったです。またゆっくりお話したいです。
CAのみなさん、会場提供・設営などお世話になりました!
ご参加くださったみなさん、ご清聴ありがとうございました。あえて苦言を呈させていただくと、カイジをご存知のかたは「圧倒的閃き・・・!」のところでもっと笑ってもらいたかったです。


お話の補足
僕は今回、せっかくだから楽しいほうがよかろーと思ったのと、根がシャイボーイなのでああいう感じじゃないと恥ずかしくて話せないので、結果ネタっぽい感じになってしまいましたが、本筋を外したつもりはありません。

すべては
それはみんながよろこぶことなのか
というところにつながります。

そして、「みんな」とはユーザーのみなさん、クライアントさん、協業さんだけでなく、自分たちも含んでいます。「自分たち」です。「自分」じゃありません。でも「自分たち」の中には「自分」も含まれています。


僕たちは別に少数でやることがポリシーなわけでもなんでもないので、これはただの制約にしか過ぎません。
この制約の中でサイトを安定させるだけでなく、進化させていかなければなりません。

って、そんなのどこだって同じ、あたりまえの話だと思うんですよね。6人が多数か少数かは状況によって違うわけで、人手なんてどこももっと欲しいと思ってると思います。
だから(人手の募集はなんとかするとして)そんな中どうやったら一番アウトプットが最大化するか、っていう話なんだと思います。

それを僕達は、6人いるメンバーをDevに寄らせたりOpsに寄らせたりしてやっているつもりです。

アウトプットを最大化するためにはいろいろなアプローチがあると思います。
  • 作業の効率化(自動化)
  • タスクの取捨選択
  • アウトソース
  • 情報共有
  • etc..

それぞれの中で
  • やらなければいけないこと
  • やるべきなこと(ベキ論的な意味で)
を冷静に見極めなければいけないと思っています。

特にIT界はベストプラクティスと言われる「あるべき事例集」みたいなものがたくさん流通している気がします。
僕の心が汚れているせいだとわかっていますが、それらからはなんとなく「これをやらないから、おまえんところはデスマになるんだ!」的なオーラがただよっているように思えます。
※それを提唱している人や、推し進めようとしている人からでているオーラではなく、ただ単に僕の汚れた心がWeb上あたりからそういうオーラを感じているだけです。念のため。

が、それらはすべては考え方の話で、前提条件が揃わなければそれは最高の選択肢でありうることは少ないと思っています。
※提唱している人や、推し進めようとしている人は、考え方の話をしているはずです。

特に収益を得ることの手段としてのITであればなおさらだと思います。

たとえばテストは書くべきだと思います。テストは拡張性、保守性、可読性を高めます。確実に入るであろう今後の変更を考えたらやらない手はありません。でも、常に今後のことを考えた選択肢が正しいとは限らないと思います。「今、ここで、リリースできないと今後なんかない!」というノリの状況は少なくないと思っています。そんな状況ではTDDの採用は正しいとはいえない選択肢だと思います。(テストを書いても開発スピードが落ちないという人しかいない場合を除く)

「今、ここで、リリースできないと今後なんかない!」という考え方を理解しようせず「TDD!TDD!」とか言っている人は、ユーザーのよろこびに比べ、自分のよろこびにかなり重きを置いている、といえると思います。

そして、よろこびが偏った選択肢は、サービス全体として非効率な選択肢になります。


DevとOpsの対立みたいな話の具体例は残念ながら(?)うちにはありません。DevとOpsの分けがないから。
でもサービス開発にあたって、技術チームとディレクションチームといった分けはあります。この分けも、「同じものを作ってるけど、やっていることがちょっと違うチーム」といった意味ではDevsとOpsの分けとそう性質は変わらないと思います。

が、やっぱり対立みたいなものはありません。

きっとお互いのことを尊重できているからだと思います。

同じものを作っているのになぜ対立が起きるのか、はいろんなきっかけがあると思いますが、たぶん会話が足りないからじゃないかなと思います。

「わかるけど、そうコトはシンプルじゃないんだよ」と言う人もいるかもしれませんが、もうこれくらいしか推すアイデアがないんです。

同じサービスを支えているのに対立するって、おかしいじゃないですか。

会話といっても、酒場に行って飲むとかだけじゃないと思うんです。
なんだったら、DevsとOpsで短期交換留学みたいのしてもいいかもしれないです。

今回のDevOpsに参加された方しかわからないかもしれないですが、家族の理解の件ででてきたBBQの話もこれと同じノリだと思ってます。

ところで、家族の理解の話は、「アラートの監視体制は全員。深夜休日は当番制」といった体制から「家族の理解が得られるのか」といった質問がきたと記憶しており、BBQの提案をついしてしまいましたが、そもそもうちのアラート運用はそんなきっつい運用であると思っていません。

発信されるアラートの閾値や種類の出しワケなど、工夫を重ねていけば、少なくとも家族の理解の話になるような事態にはならないと思っています。
たとえば、ハード障害とかは無理ですけど、同種のアラートはきっちり対応していけば確実に減らせます。
@riywoさんもプレゼンの中でおっしゃっていましたが、それをきっちりやると、本当にメールを見ただけで障害の内容がだいたいわかるようになってきます。

なので、現在のDECOLOGではそのルールがキツイといった状況ではないと思っています。
少なくとも、うちのredmineの数あるタスクの中には「改善するべき」というチケットは切られていません。


冒頭で「みんなよろこぶの『みんな』には自分たちも含まれる」と言ったように、もし、このアラート運用が実際キッツいものであれば、全然ダメダメだと思います。
アラート受け取る側が多くの犠牲を払って成立するサービスなんてどうかと思います。

スライドでは「よろこびの最大化」といったことも書きましたが、これはみんなのよろこびを数値化したらもっとも大きい選択肢を採るということではないです。

最近マイケル・サンデル先生の「これからの「正義」の話をしよう」という本を読んでいますが、この中にオメラスという町の話がでてきます。
"オメラスではすべての人が飢え、貧困、病気もなく、幸せに暮らしているが、その幸せはたった一人の子供が窓もない地下に閉じ込められていることが前提となっている"
といった町です。

こんなの絶対ナシだと思っています。速攻で改善です。
あと、長期的な自己犠牲も禁止です。ダメ。


そんな選択肢を採らなくても、みんなの知恵で工夫を重ねることができれば、一時的にはつらいことはあっても、DevOps的な問題はだいたいなんとかなるもんだと思います。

そして、みんながよろこぶ選択肢を選び続けていれば、たった数人で数十億PVのサイトを運営していても、それなりにやりたいことができる環境が作れると思います。作れていると思います。今のところ。


ここまでの話の具体例とかは、どうしても自分が今WEBサービスをやっているので、その視点になってしまいますが、WEBサービスじゃなくても同じことだと思います。なんならITじゃなくても同じだと思います。

DevOpsのあとがき的な内容として、あっているのかだんだんよくわからなくなってきましたが、言いたいことは言った感はあります。ほんと、すみません。

最後に、会場設営のときのCAの方がたの若々しいふいんき(変換できるけど変換しない)はなんとも楽しそうな感じで「こういうふいんき(ry)が大事なんだよなーって思いました。今度飲みに誘ってください。ということをもって僕の挨拶とかえさせていただきます。
おわり。


2011/06/14

Chefでサーバのセットアップ・管理作業を楽チンにしよう~実践編その2~


前回紹介したスパムメールがさらに進化して「メアド変えたのでよろしく!」的な内容になってて、この人らPDCA実践してるわ―、と感心してしまったhiroshiです。

「3.レシピを書いたりする」の途中で終わった前回の続きです。

phpのインストールに必要なパッケージをインストールするところで終わっていましたので、次はphpのインストールです。

ここでphpをインストールする条件として
  • インストールされてない
  • 規定のバージョンと違う
  • 想定のコンパイルオプションと違う
場合にインストールし直してね、と定義したいと思います。

主なところはこんな感じです。

{chef-repo}cookbooks/php/recipes/default.rb
# バージョンのチェックを行い、バージョンが想定と違っていたらインストールを実行する
# サーバ稼働中の予期しないアップグレードを防ぐため、/usr/local/src/PHP_VERSION_CHECK_REQUIRED
# というファイルが存在する場合のみ処理が行われる。
buildtool_check_version "php" do
  action :check
  input '|/usr/local/bin/php -v'
  regex /^PHP ([0-9.]+)/
  version node[:php][:version]
  only_if "cat /usr/local/src/PHP_VERSION_CHECK_REQUIRED"
  notifies :create, "cookbook_file[/usr/local/src/#{node[:php][:tarball]}]", :immediately
  notifies :install, "buildtool_make_install[php]", :immediately
  pecl_packages.each do |package_name, install_name|
        if node[:php][:extension][package_name.to_sym] then
        notifies :run, "execute[pecl-install-#{package_name}-force]", :immediately
        end
  end
end

# PHPのコンパイルオプションが変わっている場合はインストールを実行する
# サーバ稼働中の予期しない再コンパイルを防ぐため、/usr/local/src/PHP_VERSION_CHECK_REQUIRED
# というファイルが存在する場合のみ処理が行われる。
# ただしPHPがインストールされていない場合は必ずインストールが実行される。
file "/usr/local/src/PHP_CONFIG_OPTION" do
  content node[:php][:config_option]
  only_if "cat /usr/local/src/PHP_VERSION_CHECK_REQUIRED || ! /usr/local/bin/php -v"
  notifies :create, "cookbook_file[/usr/local/src/#{node[:php][:tarball]}]", :immediately
  notifies :install, "buildtool_make_install[php]", :immediately
end

cookbook_file "/usr/local/src/#{node[:php][:tarball]}" do
  action :nothing
  source node[:php][:tarball]
  mode "0644"
end

buildtool_make_install "php" do
  action :nothing
  tarball node[:php][:tarball]
  srcdir "php-#{node[:php][:version]}"
  config_option node[:php][:config_option]
  notifies :restart, "service[httpd]"
end



4ブロックありますが、それぞれ以下の役割です。
  • バージョンチェック
  • コンパイルオプションチェック
  • インストールファイルの展開
  • インストール

最初のブロックのバージョンチェック部分からいってみます。
buildtool_check_version "php" do

とありますが、buildtool_check_versionは自前で定義したResourceです。
自前定義のResourceです。で終わるのもなんなので、ここでまた横道にそれてbuildtoolの説明をサックリしてみたいと思います。

buildtoolもcookbookのひとつです。
{chef-repo}/cookbook/buildtool/
に定義があります。

上述のbuildtool_check_versionについては、
{chef-repo}/cookbook/buildtool/resources/check_version.rb
actions :check
# バージョンチェックをする Resource の定義

attribute :input, :kind_of => String, :required => true
attribute :regex, :kind_of => Regexp, :required => true
attribute :version, :kind_of => String, :required => true
とresourcesに定義をし

{chef-repo}/cookbook/buildtool/providers/check_version.rb
action :check do
  begin
    versionstring = IO.read(new_resource.input)
    if new_resource.regex =~ versionstring
      version = $1
      if version != new_resource.version
        Chef::Log.info("Version check for #{new_resource.name}: expected=#{new_resource.version}, actual=#{version}")
        new_resource.updated_by_last_action(true)
      end
    else
      Chef::Log.info("Version check failed: '#{versionstring}' is not match #{new_resource.regex}")
      new_resource.updated_by_last_action(true)
    end
  rescue
    Chef::Log.info("Version check failed: #{$!}")
    new_resource.updated_by_last_action(true)
  end
end
とprovidersに実際の動作を記述します。

providersにあるnew_resourceにはresourcesで定義したattributeがあり、その中身は
buildtool_check_version "php" do
  action :check
  input '|/usr/local/bin/php -v' #ココ!
  regex /^PHP ([0-9.]+)/     #ココ!
  version node[:php][:version]  #ココ!
と、利用時に指定した値が入ります。

このあたりの構成が分かれば、check_version.rbが何しているかはrubyがわからなくてもなんとなくわかるかと思います。ぼくもrubyわかんないし。

ちなみに最後の
version node[:php][:version]


{chef-repo}cookbooks/php/attributes/default.rb
default[:php][:version] = "5.x.x"
default[:php][:tarball] = "php-" + default[:php][:version] + ".tar.bz2"
default[:php][:config_option] = "--with-libdir=lib64 \
~後略~
とここに書いた値が基本的には入ります。node[]で取れるの値ですが、設定できる場所は複数箇所あって優先順位があるので気をつけてください。詳しくは公式のこの辺を参照してみてください。

あと、気づいた人もいると思いますが、このbuildtool自体もRecipeの1つなのでbuildtool_check_versionをここで使うには、事前に
include_recipe "buildtool"
しておく必要があります。

と、横道にそれてたら、このブロックの最初の5行まで追えたので次は

only_if "cat /usr/local/src/PHP_VERSION_CHECK_REQUIRED"
ですね。

これはこのブロックのコメントに書いてあるとおりです。

いやー、コメントっていいですね!

ちなみにウチで「変数宣言」とかいうコメント書いたらグラウンド10週か腕立て200回させられるので注意してください。しかもグラウンド探すところからですからけっこうキツイです。


あっ、もうだめ!今日はここまででカンベンしてください!


では、またまた続きは次回に!