こんにちは、インフラ開発部の鳥垣です。
今回のブログではアクセスログの解析作業の効率化を図るため、ログの可視化のお話をさせていただければと思います。 導入の背景は、仕組みとしてサーバーからsyslogサーバーへのログの集積はすでに実装されていました。 しかし、syslogへの送信元のサーバー数の肥大化に伴い多量のログが保存されるようになり、ログ調査に時間がかかるようになってきました。 もっとサックリとログの調査を行う基盤が欲しいということで、今回Fluentd + Elasticsearch + Kibanaを導入しました。 FluentdでsyslogサーバーからElasticsearchにログを送り、Elasticserchでログ検索、Kibanaでグラフ化しました。 Fluentd + Elasticsearch + Kibanaを導入する際の設定や、構成などを紹介します。
システム構成
- サーバー情報(10台)
OS | CPUコア数 | メモリ | HDD |
---|---|---|---|
CentOS 7.3 | 24 | 64GB | 500GB |
※全台スペック共通の物理サーバーです。
- バージョン情報
ミドルウェア | バージョン |
---|---|
Elasticsearch | 5.5.0 |
kibana | 5.5.0 |
Fluentd | 2.3.5 |
※Elasticsearchは10台でクラスタ構築しています。
※Kibanaで使用するサーバーがリソースに余裕があったのでFluentdと兼用しています。
インストール
Elasticsearch
最初にjdkをインストールします。
sudo yum install java-1.8.0-openjdk
以下手順でElasticsearchをインストールします。
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch sudo vim /etc/yum.repos.d/elasticsearch.repo にて以下内容のファイルを作成します。 [elasticsearch-5.x] name=Elasticsearch repository for 5.x packages baseurl=https://artifacts.elastic.co/packages/5.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md sudo yum install elasticsearch
kibana
最初にjdkをインストールします。
sudo yum install java-1.8.0-openjdk
以下手順でkibanaをインストールします。
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch sudo vim /etc/yum.repos.d/kibana.repo にて以下内容のファイルを作成します。 [kibana-5.x] name=Kibana repository for 5.x packages baseurl=https://artifacts.elastic.co/packages/5.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md sudo yum install kibana
Fluentd
以下手順でFluentdをインストールします。
sudo curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sh
- Fluentdのプラグインをインストール
送信側
sudo /usr/sbin/td-agent-gem install fluent-plugin-multiprocess
受信側
sudo /usr/sbin/td-agent-gem install fluent-plugin-multiprocess sudo /usr/sbin/td-agent-gem install fluent-plugin-multi-format-parser sudo /usr/sbin/td-agent-gem install fluent-plugin-elasticsearch sudo /usr/sbin/td-agent-gem install fluent-plugin-file-alternative
Elasticsearchの設定
/etc/elasticsearch/elasticsearch.yml を変更します。
cluster.name: cluster_name ← 任意の名前を指定。 network.host: 0.0.0.0 ← リモートホストからの接続を受け付けられるように設定。 bootstrap.memory_lock: true ←スワップ無効化の設定。 node.name: hostname ← サーバーのホスト名を指定。 discovery.zen.ping.unicast.hosts: ["xxx.xxx.xxx.xxx", "xxx.xxx.xxx.xxx","xxx.xxx.xxx.xxx"] ←ElasticsearchをインストールしたサーバーのIPアドレスを指定。 discovery.zen.minimum_master_nodes: 6 ← 計算式(ノード数 / 2 + 1)に従った数値を指定。10台の場合は6。
ヒープ設定を変更するため、/etc/elasticsearch/jvm.options を変更します。
今回使用するサーバーのメモリが64GBのため半分の32GBを指定します。
-Xms32g -Xmx32g
kibanaの設定
/etc/kibana/kibana.yml を変更します。
server.host: "0.0.0.0" ← リモートホストからの接続を受け付けられるように設定。 elasticsearch.url: "http://xxx.xxx.xxx.xxx:9200" ←ElasticsearchサーバーのIPを指定。
Fluentdの設定
ログデータの送信
解析対象のアクセスログはsyslogサーバーに集約されているので、syslogサーバーにFluentdをインストールし、アクセスログを読み込んで送信します。
可視化したいログファイルは4つあるので、multiprocess を使ってFluentdをマルチプロセス化して4プロセス起動し、それぞれのプロセスでログファイルを読み込ませて送信させています。
syslogサーバーは低スペックなうえ、様々なバッチ処理が動いているのでサーバー負荷を上げないようにするため、syslogサーバーのFluentdはログファイルを読み込んで送信するだけの処理をしています。
また、送信先が障害になった場合、送信先をスタンバイ機に切り替えるようにも設定してあります。
以下はログ送信のFluentd設定になります。
※multiprocessプラグインを使用しているので、設定は親プロセスと子プロセスに分けてあります。
親プロセス(/etc/td-agent/td-agent.conf)の設定
<source> type multiprocess <process> cmdline -c /etc/td-agent/td-agent-child1.conf --log /var/log/td-agent/td-agent-child1.log ←子プロセスの設定ファイルとログの出力ファイルを指定。 sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/td-agent-child2.conf --log /var/log/td-agent/td-agent-child2.log sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/td-agent-child3.conf --log /var/log/td-agent/td-agent-child3.log sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/td-agent-child4.conf --log /var/log/td-agent/td-agent-child4.log sleep_before_start 1s sleep_before_shutdown 5s </process> </source>
子プロセス(/etc/td-agent/td-agent-child1.conf)の設定
<source> @type tail path /var/log/filename01.log ← 読み込むファイルを設定。 pos_file /var/log/td-agent/filename01.log.pos format none ← 生ログデータを送信するため「none」を設定。 read_from_head true ← ファイルの先頭から読み込ませるため設定。 tag filename01.log </source> <match filename01.log> @type forward require_ack_response true ←再送設定を有効にするため設定。 buffer_type file ←ファイルバッファを有効にするため設定。 buffer_path /var/log/td-agent/buffer/filename01 buffer_chunk_limit 8m buffer_queue_limit 128 <server> host xxx.xxx.xxx.xxx ←アクティブ機のIPアドレスを指定。 port 24221 </server> <server> host xxx.xxx.xxx.xxx ←スタンバイ機のIPアドレスを指定。 port 24221 standby </server> </match>
※上記を4プロセス分設定します。
ログデータの受信と加工
syslogサーバーから送信されたログデータを受信し、fluent-plugin-file-alternative を使って一旦ファイルに書き出します。Elasticsearchに送るデータはこのファイルを読み込んで送信します。
こうすることで、もしElasticsearch側で障害発生した場合でもsyslogサーバー側のFluentdでバッファが溜まることを防ぐことができます。
書き出したファイルは日付でローテーションさせ、過去ログをJenkinsのJOBで定期削除するようにしています。
受信するFluentdプロセスもマルチプロセス化して4プロセス起動しておき、それぞれのプロセスで受信します。
ログデータは3種類のフォーマットが混ざった形で出力されているので、Elasticsearchに送る前に fluent-plugin-multi-format-parser を使ってそれぞれパースします。
Elasticsearchに送信するFluentdもマルチプロセス化して4プロセスで処理させています。
以下は受信側のFluentd設定です。
※multiprocessプラグインを使用しているので、設定は親プロセスと子プロセスに分けてあります。
親プロセス(/etc/td-agent/td-agent.conf)の設定
<source> type multiprocess # 受信したログデータをファイルに出力する子プロセス <process> cmdline -c /etc/td-agent/child_conf.d/file_alternative01.conf --log /var/log/td-agent/file_alternative01.log ←子プロセスの設定ファイルとログの出力ファイルを指定。 sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/child_conf.d/file_alternative02.conf --log /var/log/td-agent/file_alternative02.log sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/child_conf.d/file_alternative03.conf --log /var/log/td-agent/file_alternative03.log sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/child_conf.d/file_alternative04.conf --log /var/log/td-agent/file_alternative04.log sleep_before_start 1s sleep_before_shutdown 5s </process> # 読み込んだデータをパースしてElastcSearchに送信する子プロセス <process> cmdline -c /etc/td-agent/child_conf.d/multi_format_tail01.conf --log /var/log/td-agent/multi_format_tail01.log sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/child_conf.d/multi_format_tail02.conf --log /var/log/td-agent/multi_format_tail02.log sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/child_conf.d/multi_format_tail03.conf --log /var/log/td-agent/multi_format_tail03.log sleep_before_start 1s sleep_before_shutdown 5s </process> <process> cmdline -c /etc/td-agent/child_conf.d/multi_format_tail04.conf --log /var/log/td-agent/multi_format_tail04.log sleep_before_start 1s sleep_before_shutdown 5s </process> </source>
以下は、ログデータを受信してファイルに書き出すFluentdの設定(/etc/td-agent/child_conf.d/file_alternative01.conf)になります。
<source> @type forward port 24221 </source> <match filename01.log> type file_alternative path /var/log/td-agent/file/filename01.log.%Y%m%d ←受信したデータを出力するファイルのパス(日毎でローテーションされます)。 buffer_type file buffer_path /var/log/td-agent/buffer/filename01 buffer_chunk_limit 8m buffer_queue_limit 256 output_data_type attr:message output_include_time false output_include_tag false add_newline true </match>
※上記を4プロセス分設定します。
以下は、ログデータをパースしてElastcSearchに送信する設定(/etc/td-agent/child_conf.d/multi_format_tail01.conf)になります。
<source> @type tail path /var/log/td-agent/file/filename* pos_file /var/log/td-agent/filename01.log.pos format multi_format <pattern> format /^xxxxxxxx$/ ←パースするフォーマットを正規表現で指定。 </pattern> <pattern> format /^xxxxxxxx$/ </pattern> <pattern> format /^xxxxxxxx$/ </pattern> tag filename01_multi_format.log read_from_head true </source> <match filename01_multi_format.log> @type elasticsearch logstash_format true hosts xxx.xxx.xxx.xxx:9200 ←ElasitcSearchサーバーのIPを指定。 logstash_prefix filename_log buffer_type file buffer_path /var/log/td-agent/buffer/filename01_multi_format flush_interval 1 </match>
※上記を4プロセス分設定します。
各プロセスの起動
設定完了後、各ミドルウェアのプロセスを起動していきます。
Elasticsearchの起動
sudo systemctl start elasticsearch
Kibanaの起動
systemctl start kibana
Fluentdの起動
systemctl start td-agent
Elasticsearchの過去Index削除
過去のIndexの削除処理にはelasticsearch-curator を使用しており、Jenkinsから定期実行するようしています。
elasticsearch-curatorをJenkinsサーバーにインストールします。インストール方法は以下になります。
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch sudo vim /etc/yum.repos.d/curator.repo にて以下内容のファイルを作成します。 [curator-4] name=CentOS/RHEL 7 repository for Elasticsearch Curator 4.x packages baseurl=http://packages.elastic.co/curator/4/centos/7 gpgcheck=1 gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch enabled=1 sudo yum install elasticsearch-curator mkdir /var/lib/jenkins/.curator/ ← 設定ファイルを配置するためのディレクトリを作成します。
elasticsearch-curatorの設定は以下になります。
- configファイル(/var/lib/jenkins/.curator/curator.yml) の設定
client: hosts: - xxx.xxx.xxx.xxx ←ElasticsearchサーバーのIPを指定。 port: 9200 url_prefix: use_ssl: False certificate: client_cert: client_key: ssl_no_validate: False http_auth: timeout: 30 master_only: False logging: loglevel: INFO logfile: logformat: default blacklist: ['elasticsearch', 'urllib3']
- actionファイル(/var/lib/jenkins/.curator/delete_indices.yml)の設定
actions: 1: action: delete_indices description: "Delete filename_log indices" options: ignore_empty_list: True continue_if_exception: False disable_action: False filters: - filtertype: pattern kind: prefix value: filename_log- ←削除するIndexのprefixを指定。 exclude: - filtertype: age source: name direction: older timestring: '%Y.%m.%d' unit: days unit_count: 20 ←何日前のIndexを削除するか指定。「20」の場合は20日前のIndexが削除されます。 exclude:
上記設定のうえ、Jenkinsで以下を定期実行しています。
/usr/bin/curator /var/lib/jenkins/.curator/delete_indices.yml
最後に
今回はFluentd + Elasticsearch + Kibanaの構成や設定についてお話させていただきました。
これからログの可視化にチャレンジする方の参考になれば幸いです! それでは!