いますぐ実践! Linuxシステム管理

いますぐ実践! Linux システム管理 / Vol.253 / 読者数:2527名

あけましておめでとうございます、うすだです。

おそらく9日間ほどのお休みがありましたが、みなさま満喫されましたでしょうか。

わたしは、この9日間で、いろいろできていないことを挽回するぜ! などと思っていましたが、案の定、挽回できていません。(現在進行形)

せめて、今年の抱負は、いち早く決めねば、と思っています。(遅)

さて、当メルマガは、そもそも、初心者を脱したいと思っているシステム管理者 (および見習い)の方々の手助けとなるべく、はじめたものです。

ですが、意外と玄人(?)の読者の方が少なからずいらっしゃること、 自分の知識や経験が古くなってきていることから、 もう少し新しいものに目を向けてもいいのではないか、 と今さらながらに思い始めています。

初心者+αくらいの方がメインターゲットというのは変えないつもりですが、 昔からありどこででも動くもの、にとらわれないで、いろいろご紹介していけたら、 と企んでおります。

というわけで、今年も引き続き、よろしくお願いいたします。

今回のお題 - fluentd を使ってみる (レベル:初級)

ここ数年、ビッグデータやら DevOps やら XaaS やらなんやらかんやらが壮大に流行っているようですね。
…いえ、ようですね、というレベルでもない気もします。

ぽつねんと世間から取り残されている感を、非常に感じておる次第です。

そこで、いずれのキーワードにもそれなりに絡んでいて、 システム管理に必要と思われる「fluentd」を、新年早々取り上げて、 世間に追いつこう!と思います。…お手数ですが、お付き合いください。

fluentd とは?

fluentd とは、泣く子も黙る「Treasure Data」が開発している、 様々なログを収集して処理するためのツールです。
(恥ずかしながら、Treasure Dataという会社の存在は最近知りました。)

Fluentd: Open Source Log Management
http://fluentd.org/

ログには、syslog(rsyslog, syslog-ng)、 Apacheなどのデーモンやアプリケーションの出力など、様々な種類があります。 そして、各所で記録され続けているのではないかと思います。

これらに変更を加えることなく、各所のログをまるっと収集して、 多彩な処理をしてくださるすごいひとが、fluentd です。

fluentd のすごいところは、様々な入出力に対応していることと、 それらがプラグイン形式になっていて、いろいろ組合せられることです。
もちろん、プラグインを自分で作ったりもできます。

fluentd では、ログの種類を「タグ」で分類します。
タグは通常、「.」でつないで階層的に扱います。 syslog の facility と level に似ていますね。ただし、 3つ以上の指定も余裕でできます。
また、ログの中身は、「JSON(JavaScript Object Notation)」形式です。

…と、言葉だけではピンと来ないと思いますので、 早速インストールして使っていこうと思います。

まずはインストールから

インストールするには、 前述のホームページにある Install Fluentd と書かれたところの手順通りに行います。

いずれのディストリビューションでも、 インストールを行うためのシェルスクリプトをダウンロードして、実行します。

Ubuntu などの場合は、 以下のように、curl コマンドでシェルスクリプトをダウンロードして実行します。
下記のURLは Ubuntu 12.04LTS 用ですが、Ubuntu 13.04でも特に問題なく動作しています。

  $ curl -o install-ubuntu-precise.sh \
  http://toolbelt.treasuredata.com/sh/install-ubuntu-precise.sh
  $ sh install-ubuntu-precise.sh

CentOS など RedHat系の場合も、ほぼ同様の手順で行います。

  $ curl -o install-redhat.sh \
  http://toolbelt.treasuredata.com/sh/install-redhat.sh
  $ sh install-redhat.sh

どちらの場合も、リポジトリを追加し、 「td-agent」というパッケージをインストールしています。
短いスクリプトですので、気になる貴兄は、ぜひ中を見てみてください。

設定ファイルの概要

td-agent の設定ファイルは、「/etc/td-agent/td-agent.conf」です。

おおまかな設定として、以下の3つのディレクティブがあります。

「source」ディレクティブは、入力で使用するプラグインと、 その設定を行うためのものです。
「match」ディレクティブは、処理する内容を指定するためのものです。
「include」ディレクティブは、別のファイルにある設定を読み込むためのものです。

 

sourceディレクティブでは、「type」パラメータでプラグインを指定し、 他のパラメータでプラグインごとの設定を行います。

たとえば、デフォルトの設定には、以下が含まれています。

<source>
  type forward
</source>

TCP経由でログを入力する「forward」というプラグインを使うよ、 というシンプルな設定です。
forwardプラグインは、別の fluentd にログを転送する際に使いますが、 「fluent-cat」というコマンドで入力することもできます。
デフォルトでは 24224番ポートを使いますが、 「port」パラメータで別のポート番号を指定できます。

また、以下の設定も含まれています。

<source>
  type http
  port 8888
</source>

これは、HTTPでログを入力する「http」プラグインを使う設定です。
forwardと同様、「port」パラメータでポート番号を指定できます。

 

matchディレクティブでは、対象となるタグをパターンで指定し、 さらに「type」パラメータで出力プラグインを指定します。
sourceディレクティブと同様、プラグインごとのパラメータもあります。

たとえば、デフォルトの設定には、以下が含まれています。

<match debug.**>
  type stdout
</match>

最初に、「debug.**」というパターンを指定しています。
「**」は、0個以上の任意のタグに合致します。
「*」だと、1個の任意のタグに合致します。
「{X,Y,Z}」だと、XかYかZのいずれかのパターンに合致します。

そして、「stdout」という、標準出力に出力するプラグインを、 ここでは指定しています。
つまり、この設定は、debugで始まるタグのログがあったら、 標準出力に出力するよ、という処理を表しています。

 

includeディレクティブでは、別の設定ファイルを指定します。
特にひねりもなく、絶対パスで設定ファイルを指定することもあれば、

include /usr/local/etc/td-agent/local.conf

以下のように、/etc/td-agent を起点とした相対パスで、 ワイルドカード(globパターンというそうです)を使った指定もできます。

include conf.d/*.conf

また、以下のように、httpなURLも指定できてしまうようです。

include http://foo.example.org/fluentd/public.conf

まあ、動かしてみましょう

とりあえず設定ファイルはそのままで、動かしてみましょう。

「td-agent」というサービス名で、SysVinitな設定ファイルが用意されています。 ですので、service コマンドで起動などができます。

  (↓root権限がすでにある場合)
  # service td-agent start
  (↓一般ユーザの場合)
  $ sudo service td-agent start

Ubuntu の場合は、パッケージをインストールしたとき、 すでに起動していますので、上記を実行する必要はありません。
(ちなみに、実行しても問題が発生することはありません。)

 

まず手始めに、forward の確認をしてみましょう。

  $ echo '{"test":"test message."}' | /usr/lib/fluent/ruby/bin/fluent-cat debug.test

fluent-cat のパスは、「/usr/lib64/fluent/ruby/bin/fluent-cat」かもしれません。 もし command not found と言われたら、後者を試してみてください。

で、debugタグを指定していますので、本来なら標準出力に吐かれるはずですが、 デーモンとして動いているため、標準出力は開いていません。
代わりに「/var/log/td-agent/td-agent.log」へ出力されます。

  $ sudo tail /var/log/td-agent/td-agent.log
  ...中略...
  2014-01-04 20:21:29 +0900 debug.test: {"test":"test message."}

 

お次は、http です。
localhostの8888番ポートに対して、POSTメソッドでJSONのデータを送りつけます。 先ほどと同様、debug タグのログですので、td-agent.log を見れば、 出力されていることが確認できます。

  $ curl -X POST -d 'json={"test":"test via http."}' \
  http://localhost:8888/debug.http
  $ sudo tail /var/log/td-agent/td-agent.log
  ...中略...
  2014-01-04 21:53:40 +0900 debug.http: {"test":"test via http."}

メールを送ってみる

以上で終わってしまうとあまりに寂しいので、 ちょっとは設定ファイルをいじってみましょう。

「exec」という、コマンドを実行する出力プラグインがあります。
パターンに合致するログが「TSV(Tab Separated Value)」形式で得られ、 これをコマンドに処理させることができます。
設定は、概ね以下のようになります。

<match パターン>
  type exec
  command コマンド名
  keys キー1,キー2,...
  time_key 時刻のキー名
  time_format 時刻のフォーマット
  flush_interval インターバル時間
  buffer_path パス
</match>

「command」パラメータで、実行するコマンドを指定します。 TSV 形式のログファイルを引数に指定して実行します。
「keys」パラメータでは、TSV形式にするログのキーを指定します。
「time_key」パラメータでは、現在時刻をキーに含めたいとき、 そのキー名を指定します。
「time_format」パラメータでは、時刻のフォーマットを指定できます。 date コマンドのシーケンスと同じっぽいです。これを省略すると、 UNIX時間(1970年1月1日0時0分0秒からの経過秒)が使われます。
「flush_interval」パラメータでは、どのくらいの頻度でコマンドを実行するのか、 時間を指定します。ログが来る度にコマンドを実行していては非効率ですので、 ある程度溜まったところで実行します。時間には「s」「m」「h」をつけます。 (ご想像通り、それぞれ、秒、分、時です。)
「buffer_path」パラメータでは、 ログを一時的にためておくファイルのパスを指定します。 コマンド実行後は消えてなくなります。

 

さて、バカのひとつ覚え的ですが、exec を使って、 ログの内容をメールするものを仕込んでみたいと思います。

以下を、td-agent.conf の最後あたりに追加するか、別の設定ファイルを作って、 td-agent.conf から include してみてください。

<match mail.**>
  type exec
  command /some/where/mailtest.pl
  keys message,time
  time_key time
  flush_interval 5s
  buffer_path /var/log/td-agent/buffer/253
</match>

/some/where/mailtest.pl の中身は、以下の通りです。

#!/usr/bin/perl
use strict;
use warnings;
my $MAILTO = "root\@example.org";

open (MAIL, "|Mail -s \"[fluentd] mail message\" $MAILTO")
    || die "cannot exec Mail";
while (<>) {
    # message unixtime
    if (/^([^\t]*)\t(\d+)$/) {
        my @dt = localtime($2);
        printf(MAIL "%s : %04d/%02d/%02d %02d:%02d:%02d\n",
            $1, $dt[5]+1900, $dt[4]+1, $dt[3],
            $dt[2], $dt[1], $dt[0]);
    }
}
close MAIL;

引数に指定されたファイルには、メッセージと、 UNIX時間の時刻がタブで区切られた状態で、1行ずつ格納されています。
それをひたすら読んでは、Mail コマンドの標準入力に渡しています。
time_format を指定していないので、Perlスクリプトで処理しています。
Mail コマンドでメールが届く設定がされていれば、 変数MAILTO で指定をしたメールアドレスに、メールが届くはず…です。

できたら、Perlスクリプトに実行権をつけ、td-agent を再起動します。

  $ chmod +x /some/where/mailtest.pl
  (↑これは初回のみ必要です。)
  $ sudo service td-agent restart
  (↑すでにroot権限をお持ちなら、sudo は不要です。)

問題なさそうなら、mailタグの message を送りつけてみます。

  $ echo '{"message":"test message."}' | /usr/lib/fluent/ruby/bin/fluent-cat mail.test

うまくいけば、以下のような殺風景なメールが届くはずです。

  Subject: [fluentd] mail message

  test message. : 2014/01/04 23:20:15

届かなかったら、試しに、以下の手順で、 Perlスクリプトを直接動かしてみてください。
これでメールが届かないなら、Perlスクリプトがおかしいか、 残念ながらメールを送れる環境ではないか、のどちらかです。

  $ echo -e "test message.\t10" | /some/where/mailtest.pl

おわりに

以上、fluentd の起動手順と設定の概要を、さらりとご紹介しました。

ご存じな方はご存じな通り、開発者の方々に日本人がいらっしゃるので、 日本語のドキュメントが結構揃っています。下記などで、 右上の「ja」を押してみてください。(それでも英語なら、がんばって読みましょう。)

Quickstart Guide | Fluentd
http://docs.fluentd.org/

そして、ご存じの通り(しつこい!)、fluentdのたくさんの機能のうちの、 ほんのひと握りしかご紹介できていません。 あまり興味がないという反応をいただかない限りは、おそらく数回続くと思います。 ご了承ください。

宿題の答え

前回の宿題は、

  秘密鍵や CRT、CSR を改竄するとエラーになることを確かめましょう。

でした。

単純に、テキストエディタを使って、適当な場所の1文字を、 違う文字に置き換えてみましょう。
置き換えたファイルがそれぞれ、server-bad.crt および server-bad.csr だとすると、 以下のようになりました。

  $ openssl x509 -in server-bad.crt -text -noout
  unable to load certificate
  何か:error:何か:asn1 encoding routines:ASN1_get_object:header too long:asn1_lib.c:150:
  ...後略...

  $ openssl req -in server-bad.csr -verify -noout
  unable to load X509 request
  ...後略...

フォーマットがおかしいよ的なエラーのようです。

うーん、適当ではなく、きちんと(?)中身の一部を改竄してみましょう。
いずれのファイルも、base64 でエンコードされていますので、ほぐしてみます。 前後の BEGIN とか END の行も要らないので取り除きます。

  $ grep -v '^\-\-\-\-\-' server.crt > server.base64
  $ base64 -d < server.base64 > server.raw

フォーマットは、前述のエラーメッセージでお察しの通り、ASN.1 という形式です。 「dumpasn1」というコマンドで中身を確認できます。
(コマンドがなければ、同名のパッケージをインストールしましょう。)

  $ dumpasn1 server.raw
    0 936: SEQUENCE {
    4 656:   SEQUENCE {
    8   9:     INTEGER 00 F3 5D C5 04 BA 1E 4A 08
   19  13:     SEQUENCE {
   21   9:       OBJECT IDENTIFIER sha1WithRSAEncryption (1 2 840 113549 1 1 5)
   32   0:       NULL
         :       }
   34 149:     SEQUENCE {
   37  11:       SET {
   39   9:         SEQUENCE {
   41   3:           OBJECT IDENTIFIER countryName (2 5 4 6)
   46   2:           PrintableString 'JP'
         :           }
         :         }
  ...後略...

ここでは安直に、"JP" を "JQ" とかにしてみます。
46バイト目くらいにあるようです。バイナリエディタなどで、 えいやーと改竄しちゃってみてください。
(vi で 「:%!xxd」→変更→「:%!xxd -r」→セーブ、でもOKです。)

改竄したら、もう一度 base64 でエンコードして、BEGIN や END を前後に付け足します。

  $ base64 -w 64 < server.raw > server-bad2.base64
  $ (head -1 server.crt; cat server-bad2.base64; tail -1 server.crt) > server-bad2.crt

そして、再度 openssl コマンドに確認してもらうと…

  $ openssl x509 -in server-bad2.crt -text -noout
  unable to load certificate
  何か:error:何か:asn1 encoding routines:ASN1_get_object:header too long:asn1_lib.c:150:
  ...後略...

…結果は同じでした。OTZ

やや苦労した割には、報われない結果となってしまいましたが、 CRT などのフォーマットの確認にはなりました。(と思っておきます。)

ちなみに、ASN.1 については、下記で少し触れていました。

Vol.233 - MRTG でネットワークを監視する
http://www.usupi.org/sysad/233.html

今回の宿題

今回の宿題は、

  ある fluentd の出力を、別の fluentd へ転送してみましょう。

です。

forward は、別の fluentd に転送するためのプラグインです。
複数のサーバのログをかき集めて処理したいというご要望は、 あちこちであるんじゃないかと思います。
出力の forward の説明は全然していませんが、 前述の fluentd のサイトに情報があります。ちょちょっと調べて設定してみてください。

あとがき

2013年は、いろんなことをせねばと思っていたのに、 結局どれもできないまま終わってしまった年だったように思います。

もともと器用な方ではないので、2014年は、 どれかに絞って注力せねばと思っています。まだどれに絞るか、決めかねていますが…。

さて、お仕事でも個人的にも興味のあるテーマの中で、 昔からずっと気になっているのが、トラブルとかバグとかへの対処です。

それに絡む記事がありましたので、ちょっとご紹介します。

人間は誰でもミスをする、システムは必ず障害を起こす−トラブルを減らす“6つの知恵” : ITPro
http://itpro.nikkeibp.co.jp/article/COLUMN/20131212/524346/

医療ミスから話が始まっていますが、肝の6つの知恵は、システム管理に限らず、 いろんなところに適用できる、大切な指摘だと思います。

「はい」「いいえ」でできる受け答えをしない、 インシデントレポートや個人を叱咤しない文化の定着など、いずれも耳が痛いです。

これらは、勉強して習得する、といったたぐいのものではないと思いますので、 仕事場などで少しずつ取り入れたい、すぐできなくても意識はしておきたい、 などと思っています。

まあ、そういうのもどんどん溜まっていくので、 古いものはどんどん忘却の彼方へ追いやられてしまうのですが…。 (外部記憶が欲しいです…。)

 

今回も、ここまで読んでいただき、誠にありがとうございました。
次回は、1月19日(日) の未明にお会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」- 今年こそは、どかーんとブレークさせねばと思います。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://usupi.org/k/ (モバイル栗日記)
http://twitter.com/kuriking/ (栗つぶやき)
http://facebook.com/kuriking3 (栗顔本)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本