おまけ

7月に@さん主催で開催された Automation Tech Casual Talks #1 で使った資料をBlogに上げて無かったので今更ではありますが置いておきます。思うところあってtwitterでひっそりURLを公開してましたが、気が変わりました。

内容は、Sqaleで行なっているEC2インスタンスの構築や運用の自動化についての話です。

モニカジ2

先日開催された Monitering Casual Talk #2 でMuninのスケールアウト構成について話してきました。

資料はこちら。

ご存知通り、Muninにはスケールアウト機能が無いのですが、幾つかのスクリプトとcronだけでそれっぽいことをやってみた、という内容です。

最近Munin2.0が出て、1台で捌ける台数もそれなりに増えたとは思うんですが(自分はまだ検証してないです)、

  • 数百台規模
  • 何故かリソースの余っているサーバが複数台ある

という環境でしたら、便利に使って頂けるかも。コードはgithubで公開しているので、もしこれから試してみる人が居たら、使用感等教えてもらいたいです。

当日自分は会場で障害対応ぽいことをしていたというがあって、あまり他の方の話をちゃんと聞けてなかったんですが、みなさんがビールを好きだということはよく伝わったので、やはりモニカジはいいイベントだと思いました。

次回は同期の@が主催するらしいですね。陰ながら応援します。

しかし、みんな立派な感想エントリを書いてるのに、自分はこんないい加減な内容でいいんでしょうか。

RDSのログの話

というわけで、懇親会で話題に上がったSqaleでやっているRDSのログの扱いを晒して、お茶を濁させて頂こうかと思います。

RDSってAWSのDBインスタンスのあれです。で、あれって当然、中にSSHでログインしたり出来ないので、ログ(一般ログ、スロークエリログ)をファイルで見ることができません、その代わりテーブルに書き込まれる(デフォルトではオフです)ので、それをselectすれば確認できます。しかし、この仕様だと下記の様な不都合が発生します。

  • 放っておくと容量を圧迫する
  • ローテート出来るが1世代のみ
  • スロークエリログを料理する既存のツールが使えない
    • mysqldumpslow
    • mk-query-digest など

なので、Sqaleではその問題を解消すべく運用ツールを作りました。

それが、rds-logrotate-and-upload-to-s3 です。

これはcronで実行することを想定していて、下記のことを行います。

  1. 特定AWSアカウントの全RDSインスタンスに対して
  2. slow_log, generic_logをローテート
  3. ログの内容をローカルの日付suffixをつけたファイルに書き出し
  4. スロークエリログについては、通常のファイルと同じフォーマットに変換と、mk-query-digestでの解析
  5. ログファイルを設定されたS3バケットに同期

スロークエリログのフォーマット変換部分は別のperlスクリプトに分離してあるので、単体でも使えます(パーサ部分はもともと何処かで見つけたpythonスクリプトが下敷きになっています。)。

公開するにあたって、結構コードを変えたんですが、ちゃんとデバッグしてないので、近い内にちゃんと仕上げます。pullreqくれてもいいです。というか下さい。

Monitoring Casual Talk #1でNagiosの運用について話してきました

プレゼン2度目ですが、前回引き続き、脇、首の異常な発汗が抑えられません。どうしたら平然と発表できるんでしょうか。

自分の資料はこちらです。

幾つかの*-casualを見てきましたが、今回が一番カジュアルでしたね。とくにid:hirose31さんはカジュアルを完璧に体現されており、さすがだと思いました。

全員発表というコンセプトといい、内容のいい意味での緩さといい、とても良いイベントでした。ぜひとも第2回を期待したいです。

関係者の皆様、ありがとうございました!お疲れ様でした!

7/20 追記

友人から資料のnagiosのコンフィグレイアウトについて質問があっったのでそこで答えた内容を追記しておきます。

質問は「どうしてそこにobjectsファイルをおいたか?」というもの。

なぜわざわざデプロイパスからリンクを貼って、/etc/nagios/objects/sqale 以下に置いたのかって感じの趣旨です。

それに対してこう答えました。

  1. 設計した人しかその場所に辿りつけないのがよくないから。これならnagiosについて知ってうひとならちょっと探せば、あ、ここかってわかるでしょ。
  2. あと、デフォルト(標準)の配置ってのは歴史があって、それなりの理由があってそうなったのだと尊重してるので、あんまり好き勝手にやると、あとで、あーそういうことだったのか…って後悔するかもよ。というか過去にそういう事例があったりする。nagios以外でだけど。

そういうわけです。明確に理由が無い限りは標準に沿って使った方が幸せですよ。

MySQL Casual Talk #3 で30daysのことを話してきました

先日19日に開催されたMySQL Casualで自分がペパボでインフラを担当している30days albumの運用について話してきました。

実は、技術者として社外でちゃんとプレゼンするのが初めてだったので、緊張しすぎて直前までマジで帰ろうかと思ってたんですが、手のひらに「カジュアル」と書いて飲み込むという伝統的なおまじないで気を落ち着けることが出来ました。

時間20分なのにどういう訳かスライドを80枚もありますが、当日お話したのは、52枚目以降だけです。そこまでは華麗にワープしました。実はそこが一番受けていたらしいので、とりあえず書いた甲斐はありましたね。

因みにスライド内の図は同僚の@さんがほとんど書いてくれました。持つべきものはイケメンの同僚だなぁと非常にありがたく思っています。

他の方々の発表も前回までより一層現場感の強い実践的な内容が多く、とても勉強になりました。またこれから復習しようと思います。

最近、会社の新人事評価制度で「シニアエンジニア」という肩書きを頂き、今後は社外でのアウトプットもある程度期待される立場となったので、今回発表させて頂く機会を頂けた事はとてもタイムリーでした。お声をかけてくれた@さん並びに、関係者の皆様ありがとうございました!

puppetのclass間依存の話

最近chefに押され気味な気がしないでもないpuppetのことでも書こうかな。

puppetでは各種リソース(file、package、service 等など)間の依存関係を定義出来るのですが、class(複数リソースをまとめたセットみたいなもの)間でも依存を定義することができます。

class間でそれが出来るとなにが嬉しいかというのは、mizzyさんのこのエントリが具体的で分かりやすいです。http://mizzy.org/blog/2011/07/10/ProPuppet00/

で、自分も最近ようやくpro puppetをちゃんと読んでみたわけなんですが、classの依存を宣言するには、実は4っつの方法があるんですね。

一つ目は普通にリソースのrequireパラメータで指定する方法。例えばfileだったら。

file { '/etc/sshd/sshd_config':
  source  => 'puppet:///ssh/config/etc/sshd_config',
  require => Class['ssh::install']
}

こんな感じで、別でsshをインストールさせるclassを定義しておいて、sshd_configはそっちの処理が全部終わってからぶっこもうねって感じ。

2つ目は、カレントclass内のリソース全てに上記と同じ内容をデフォルトで突っ込んでしまえるやり方。metaparameter defaults と言うらしいです。

class ssh::config {
  @require => Class['ssh::install']

  file { '/etc/ssh/sshd_confg':
    source  => 'puppet:///ssh/config/etc/sshd_config',
    # ここでは ssh::install に対する依存を明示する必要がない。
  }
}

3つ目はrequire functionを使った方法。2つ目と同じような感じだけど、こっちは同時にincludeと同等の処理をしてくれる。

class ssh {
  require ssh::install
  include ssh::config
}
class ssh::config {
  ...
}
class ssh::install {
  ...
}

4つ目は、いままでのやり方やシンタックスとはかなり異色な方法。arrow operator でClass間の依存を定義します。

class ssh {
  Class['sshg::install'] -> Class['ssh::config']
  include ssh::install
  include ssh::config
}

以上です。

一つ目は知っていたんだけど、他は今回はじめて知って便利そうだったので検証してみることにしました。

こんな感じで /tmp/relation.pp というmanifestを作ります。

class aaa {
  notify {'aaa':}
}

class aaa_with_meta_param {
  notify {'aaa': require => Class['bbb'] }
}

class aaa_with_metaparam_default {
  $require = Class['bbb']
  notify {'aaa':}
}

class bbb {
  notify {'bbb':}
}

##--------------------------
class normal {
  include aaa
  include bbb
}

class resource_level_require {
  include aaa_with_meta_param
  include bbb
}

class metaparam_default {
  include aaa_with_metaparam_default
  include bbb
}

class require_function {
  include aaa
  require bbb
}

class arrow {
  Class['bbb'] -> Class['aaa']
  include aaa
  include bbb
}

##--------------------------
include normal
#include resource_level_require
#include metaparam_default
#include require_function
#include arrow

で、最後のセクションをコメントアウトしたり、コメントしたりして1つずつ実行。puppet 2.7.9の環境でやってます。

puppet apply /tmp/relation.pp

期待する結果としては、一番上のnormal以外は全て'aaa'より'bbb'を先に出力して欲しいのですが、どういうわけか実際には、2つ目と4目(resource_level_require、arrow)しかそのようになりませんでした。

他にも別のパターンでmanifestを作成して色々試してみましたが、同様でした。

ただし、詳しく切り分けできていないのですが、うまくいかなかったrequire functionとmetaparameter defaoutも場合によっては順番を制御してくれるようです。

    • -

というわけで自分が検証した限りではclass間の依存定義で当てになるのは、arrow operatorだけどいう結果になしました。

本当はrequire functionが見た目的に一番馴染みやすそうだったので、残念です。何か全然勘違いしてるのかな?ツッコミや情報がありましたら教えてほしいです。

postfixのキューをフィルタリングするやつ

たくさんメールサーバを管理してると、様々な理由でダメな感じの滞留キューを調べたり消したりしたくなることがあるわけですよ。

postfixだとmailqってコマンドでキューのサマリが取得できるんだけど、こいつは1レコード複数行なので、特定FromであったりToであったりでフィルタリングするのが結構きつい。

例えばawkで特定ToなキューIDを得ようとするとこんな事になってしまう。

mailq | awk 'BEGIN{FS="\n"; RS=""} /\n *todokanai@gmail.com\n?/{print $1}'| awk '{print $1}' | sed 's/\*//'

こんなもん覚えてられないし、覚えたとしても毎回こんなにタイプしたくない。

というわけで、perlでちゃちゃっと作ったのがこれ。

https://github.com/lamanotrama/mailq-filter

例えば上のawkでやってる例だと

mailq-filter -t todokanai@gmail.com

でいけるし、パイプで続けて

mailq-filter -t todokanai@gmail.com | postsuper -d -

とかやると、とても晴れやかな気分になると思います。なりました。