Graylogで大規模なログ収集環境を構築する

More than 1 year has passed since last update.


要件


  • クライアント数は、約2000ノード

  • 各ノードから秒間1~2件のログ (5000件/秒程度)

  • ログの保存期間は2週間


アプリケーション/ミドルウェア


  • Glaylog Server 2.1.1

  • MongoDB (v3.0.4を使用)

  • Java 1.8.0

  • ロードバランサー(lvs, haproxy, nginx等)

  • Elasticsearch 2.4.1 (Graylog2.1から2.4系に対応)

  • Graylog Collector 0.5.0 (0.4系は非対応)


ハードウェア


  • MongoDB .... 3台

  • バランサ用サーバ ... 1台

  • Graylog server ... 10台 (12GB memory / 300GB HDD)

  • Elasticsearch ... 200台 (96G memory / 700GB SSD)


構成

各ミドルウェアの配置については、以下のようにしました。公式ドキュメントも参考になります。以前はGraylog Web interface というGUIが別途存在しましたが、Graylog2からは、Graylog Serverに統合されました。JavaScriptベースに書き直され、GUIがクライアントサイドで動くようになっています(データ自体はAPIから取得)

graylog.png

Mongodbについては、それほど高スペックなサーバは必要とされませんが、Mongoのノードが死ぬとGraylogが停止しますので、推奨されている3台構成がよいでしょう。

Graylog ServerおよびElasticsesrchについては、秒間のリクエスト数と、保存期間に応じて、それなりの台数までスケールする必要があります。

Graylog Serverのマスターノードは1台しか設定できません。マスターノードの停止中でもログは受信できますが、Inputの追加などの設定変更などができません。


ログの保存件数

必要なレコード数は、5000件/秒 * 86400秒 * 14日 なので、

1世代あたりのログの上限 x 世代数が、これを超えている必要があります。

elasticsearch_max_docs_per_index ... 1世代あたりのログの上限

elasticsearch_max_number_of_indices ... 世代数

この値はセットアップ後にも、GUI上から変更できます。


ElasticSearchの構築

今回はElasticsearchが200ノードありますが、冗長性を考え、1ノードあたり2シャード以下、かつ1シャードに対し2つのレプリカを構成します。だいたい120シャードが適切と計算しました。 200 * 2 > 120 * 1(プライマリ) + 120 * 2(レプリカ)

こちらに関しては、別途記事を書きたいと思います。


Graylog のインストール

基本的にはtarを展開して、コンフィグを修正するだけです。

コンフィグの各行を見ていきましょう。

is_master = true   

# マスターノードか否か。マルチノードの場合、1台だけtrueに設定する

password_secret = xxxxx
# mkpasswd などで生成する

root_password_sha2 = xxxx
# echo -n "password" | sha256sum などで生成

rest_listen_uri = http://xxx.xxx.xxx.xxx:9000/api/
web_listen_uri = http://xxx.xxx.xxx.xxx:9000/
web_endpoint_uri = /api/
# ListenするIPを書く。0.0.0.0ではなく、IPアドレスを指定する。
# GUIとRestAPIのポートは分けても良いし、同じにしてもよいですが、同じ場合は、URLで分けるため、`web_endpoint_uri` を設定する。

elasticsearch_max_docs_per_index = 30000000
elasticsearch_max_number_of_indices = 20
# 1インデックスあたりのログ上限と、インデックスの世代数を設定(GUIからも変更可能)

elasticsearch_shards = 120
elasticsearch_replicas = 2
elasticsearch_index_prefix = graylog
# シャードとレプリカの数の設定

elasticsearch_discovery_zen_ping_unicast_hosts = xxx.xxx.xxx.xxx:9300, xxx.xxx.xxx.xxx:9300, xxx.xxx.xxx.xxx:9300
# elasticsearchのマスターノードの一覧を設定

elasticsearch_node_master = false
elasticsearch_node_data = false
# Graylogは、内部でElasticSearchのクライアントノードとして動作して、クラスタにJOINするので、両方Falseにする

elasticsearch_transport_tcp_port = 9300
elasticsearch_network_host = 0.0.0.0
# クライアントノードとして動作する場合、外からの通信も受け入れなくてはいけないので、127.0.0.1ではなく、グローバルでListernする

mongodb_uri = mongodb://xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx,xxx.xxx.xxx.xxx/graylog
# MongoDB 3台分のURL。ポート番号27017は省略可能。


ロードバランサ

ロードバランサは、NginxやHAProxy、LVSなどを利用するのが良いでしょう。ただし、UDPでロードバランスしたい場合(たとえば、Syslogを収集したい場合など)は、現状ですと、LVS以外に選択肢はないと思います。

本来であれば、ロードバランサ自体もKeepalived等で冗長化するべきですが、今回は1台構成にしています。

各Graylogサーバはヘルスチェックコンテンツ(/api/system/lbstatus)を持っているので、ロードバランサ側に設定します。

HAProxyの場合、以下にするとよいでしょう。

Backend web-ui-backend

option httpchk GET /system/lbstatus
server webui-001 192.168.100.100:9000 check
server webui-002 192.168.100.101:9000 check
server webui-003 192.168.100.102:9000 check

GUIとAPIのポートを分けている場合は、以下のようにするとよいでしょう。

Backend web-ui-backend

option httpchk GET /system/lbstatus
server webui-001 192.168.100.100:9000 check port 12900
server webui-002 192.168.100.101:9000 check port 12900
server webui-003 192.168.100.102:9000 check port 12900


総括

以上のような構成にすることで、最大で、秒間数万件のログを受信できることを確認しました。クライアントノード数も、数千ノードまでは問題なく動きます。

その際に気を付けないといけないのは、1件あたりのログのサイズにも依存しますが、トラフィックになるかとおもいます。実際にネットワークの上限に到達すると、Graylog側のログに、indexing failのログが残ります。