LoginSignup
1
3

More than 3 years have passed since last update.

Elastic Stack を構築する 改め,Elastic Stack のクラスターを構築する

Last updated at Posted at 2020-01-12

はじめに

仕事でElastic Stack のクラスターを構築する可能性が出てきたので,プライベートの検証環境で勉強がてら構築して検証してみた.

構築した環境は以下の通り.断続的にログが転送されてくる環境にしたかったので,Web サーバーにアクセスするスクリプトを作成してそのログをSyslog サーバーに転送させ,そのログファイルをscp でElastic Stack に取り込む形にした.
Elasticsearch はElasticsearch の機能に集中させたいため,Kibana とLogstash とは分離させ,障害が発生しても機能するようにクラスター構成とした.

elasticcluster.png

各ノードの構成は以下のとおりである.

ノード名 OS ミドルウェア/アプリケーション
Webサーバー Cent OS 8 apache,rsyslog,jq (1.5)
Syslogサーバー Cent OS 8 rsyslog,jq (1.5)
ログ処理サーバー Cent OS 8 logstash (7.4.0),kibana (7.4.0),openjdk (1.8.0),jq (1.5)
Elasticsearch #1 Cent OS 8 elasticsearch (7.4.0),openjdk (1.8.0),jq (1.5)
Elasticsearch #2 Cent OS 8 elasticsearch (7.4.0),openjdk (1.8.0),jq (1.5)
Elasticsearch #3 Cent OS 8 elasticsearch (7.4.0),openjdk (1.8.0),jq (1.5)

Web サーバーの構築

最初に,Web サーバーを用意し,そのアクセスログをsyslog にてSyslog サーバーに転送するインスタンスを構築する.

apache の構築

apache をインストールする.

実行コマンド
# dnf -y install httpd

Cent OS 8 から?IPアドレス指定だけでアクセスしようとすると403がレスポンスされる.それだと正常にアクセスできたかどうかわからなかったので,ドキュメントルート直下に以下のhtml ファイルを作成して配置した.curl でアクセスするとtest とだけレスポンスされる.

/var/www/html/test.html
test

最後に,ログ転送関連の設定を行う.

アクセススクリプトの作成

以下のスクリプトを作成し,アクセスログを定期的に発生させるようにした.
最初はsleep コマンドはなかったが,ないとログが多すぎるのでログ量を調整することにした.

access.sh
#!/bin/bash

while [ true ]
do
    curl http://192.168.226.135/test.html
    sleep 60    
done

rsyslog の設定

rsyslog により,apache のアクセスログをSyslog サーバーに転送するため,apache の設定ファイルに以下を追記する.ユーザー定義のlocal0 を利用する.

/etc/httpd/conf/httpd.conf
CustomLog "|/usr/bin/logger -p local0.info -t httpd_access" combined

次に,rsyslog でSyslog サーバーに転送の設定を記述する.今回は,UDP でログ転送をする.

/etc/rsyslog.conf
local0.* @192.168.226.136:514

ファイアウォールの許可設定をしておく.

実行コマンド
# firewall-cmd --add-port=80/tcp --permanent
# firewall-cmd --reload

最後にapache とrsyslogの自動実行をON にし,起動させる.

実行コマンド
# systemctl enable httpd
# systemctl start httpd
# systemctl enable rsyslog
# systemctl start rsyslog

Syslog サーバーの構築

Syslog サーバーでは,rsyslog に受信の設定を記述する.
送信側がlocal0 でログ転送するので,そのファシリティで受信したログの保存先を指定する.

/etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514

local0.*    -/var/log/test/access.log

ファイアウォールの許可設定をしておく.

実行コマンド
# firewall-cmd --add-port=514/udp --permanent
# firewall-cmd --reload

最後にrsyslogの自動実行をON にし,起動させる.

実行コマンド
# systemctl enable rsyslog
# systemctl start rsyslog

ログ処理サーバーの構築

Elastic Stack の役割は,Syslog サーバーに保存されているログファイルを取得してLogstash でパースおよびElasticsearch に取り込み,Kibana で可視化することである.

ログファイルを取得するスクリプトの作成

Syslog サーバーに保存されているapache のアクセスログファイルを取得するため,以下のスクリプトを作成する.このスクリプトをcrontab により定期的に自動実行させる.
logstash サービスが,logstash ユーザーで実行されるため,取得したログファイルのオーナーをlogstash ユーザーに変更し,実行権限も付与しておく.

/home/elastic/log_copy.sh
#!/bin/bash

scp -i /root/.ssh/id_rsa root@192.168.226.136:/var/log/test/access.log /var/log/test
chown logstash /var/log/test/access.log
chmod +x /var/log/test/access.log

スクリプトを作成したら,実行権限を付与しておく.

実行コマンド
# chmod +x /home/elastic/log_copy.sh

crontab の設定

定期的にログファイルをSyslog サーバーから取得するため,crontab の設定を行う.以下のファイルを作成する.

/etc/cron.d/log_get
#分 時 月 日 曜日 ユーザ名 コマンド
*/5 * * * * root /home/elastic/log_copy.sh

このファイルにより,5分おきにlog_copy.sh が実行され,Syslog サーバーからapache のアクセスログファイルがログ処理サーバーのローカルにコピーされる.

ssh の設定

scp によりファイルを取得するため,まずはssh に使用する公開鍵と秘密鍵のペアを作成する.
以下のコマンドは,ログ取り込みサーバー上で実行する.

実行コマンド
# ssh-keygen -t rsa
# chmod 600 /root/.ssh/id_rsa

パスフレーズなどは設定せず,すべての質問はEnter を入力して進む.

次に,公開鍵をSyslog サーバーに登録する.以下からは,Syslog サーバー上で実行する.

実行コマンド
# scp root@192.168.226.140:/root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
# chmod 600 /root/.ssh/id_rsa.pub

これで公開鍵が登録できたので,次は設定ファイルより公開鍵認証でログインできるようにする.

/etc/ssh/sshd_config
PubkeyAuthentication yes

今回は設定実施しなかったが,インターネット公開系のシステムであったりすると,root ログインやパスワード認証を無効にする.

/etc/ssh/sshd_config
PermitRootLogin no           #root ログインを無効
PasswordAuthentication no    #パスワード認証を無効

ssh の設定が完了したら,ssh を再起動しておく.

実行コマンド
# systemctl restart sshd

java のインストール

Logstash やElasticsearch のインストールに必要なjava をインストールする.

実行コマンド
# dnf -y install java-1.8.0-openjdk

Logstash のインストール

Logstash をインストールする.インストールするためのファイルは,以下のページからダウンロードする.
https://www.elastic.co/jp/downloads/

今回は,「logstash-7.4.0.rpm」をインストールする.

実行コマンド
# rpm -ivh logstash-7.4.0.rpm

Logstash の設定

取り込むログファイルに関しての設定を行う.Logstash はinput,filter,output のパイプラインで取り込んだデータを処理する.
inputは,取り込むデータの指定,filter はデータのパース,output は,出力先を指定する形式である.

/etc/logstash/conf.d/access.conf
input {
 file {
   mode => "tail"
   path => ["/var/log/test/access.log"]
   sincedb_path => "/var/log/test/test_pointer"
   start_position => "beginning"
   type => "access"
  }
}

filter {
if[type] == "access" {
grok {
match => {
      "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{HOSTNAME:source} %{USERNAME}\[%{INT}\]: %{IPV4:destination} - - \[%{HTTPDATE:access_time}\] %{GREEDYDATA:message}"
remove_filed => ["message"]
}
}
}
}

output {
if[type] == "access" {
#debug
#stdout {
#codec => rubydebug
#}
 file {
   path => ["/var/log/test/result_access.log"]
       }
  elasticsearch {
                  hosts => ["192.168.226.137:9200", "192.168.226.138:9200", "192.168.226.139:9200"]
                  index => "test"
            }
}
}

上記設定ファイルで,syslog 経由で送信されてくるapache のログファイルをパースできる.

設定が正しくできているかはlogstash を設定ファイルを指定して実行させることで確認できる.その前に,以下の文を追記しておき,パスを通しておく.

/root/.bashrc
export PATH="$PATH:/usr/share/logstash/bin"

以下のコマンドを実行し,結果を確認する.

実行コマンド
# logstash  -f "/etc/logstash/conf.d/access.conf"

以下のような形で,json 形式でログが取り込まれていればOK.

ログ取り込み結果
{
  "message": [
    "Jan  3 01:36:13 localhost httpd_access[8378]: 【WebサーバーのIPアドレス】 - - [03/Jan/2020:01:36:13 -0500] \"GET /test.html HTTP/1.1\" 200 5 \"-\" \"curl/7.61.1\"",
    "\"GET /test.html HTTP/1.1\" 200 5 \"-\" \"curl/7.61.1\""
  ],
  "syslog_timestamp": "Jan  3 01:36:13",
  "destination": "【WebサーバーのIPアドレス】",
  "path": "/var/log/test/access.log",
  "access_time": "03/Jan/2020:01:36:13 -0500",
  "@timestamp": "2020-01-03T13:38:53.721Z",
  "host": "elastic1",
  "@version": "1",
  "source": "localhost"
}

Kibana のインストール

今回は,「kibana-7.4.0-x86_64.rpm」をインストールする.ファイルはLogstash と同じページからダウンロードした.

実行コマンド
# rpm -ivh kibana-7.4.0-x86_64.rpm

Kibana の設定

Kibana を使ってElasticsearch に蓄積されたデータを可視化する.

設定ファイルを以下のように記述する.追記した部分のみ抜粋する.

/etc/kibana/kibana.yml
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://192.168.226.137:9200", "http://192.168.226.138:9200", "http://192.168.226.139:9200"] 

ファイアウォールの許可設定をしておく.

実行コマンド
# firewall-cmd --add-port=5601/tcp --permanent
# firewall-cmd --reload

最後にLogstash とKibana の自動実行をON にし,起動させる.

実行コマンド
# systemctl enable logstash
# systemctl start logstash
# systemctl enable kibana
# systemctl start kibana

Elasticsearch の構築

Elasticsearch のインストール

今回は,「elasticsearch-7.4.0-x86_64.rpm」をインストールする.ファイルはLogstash と同じページからダウンロードした.

実行コマンド
# rpm -ivh elasticsearch-7.4.0-x86_64.rpm

Elasticsearch の設定

Elasticsearch は,3台でクラスターを構築し,それぞれデータノードおよびマスター候補ノードとして扱うよう設定する.以下の設定ファイルの記述は,node-1において構築に必要なため追記/修正したものを抜粋した.

/etc/elasticsearch/elasticsearch.yml
cluster.name: exam-cluster

node.name: node-1 #node-2,node-3とnode ごとに名前を変える

network.host: 0.0.0.0
http.port: 9200
transport.host: 192.168.226.137 #node-2,node-3とnode ごとに値を変える
transport.tcp.port: 9300

discovery.zen.ping.unicast.hosts: ["192.168.226.137", "192.168.226.138", "192.168.226.139"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

ファイアウォールの許可設定をしておく.

実行コマンド
# firewall-cmd --add-port=9200/tcp --permanent
# firewall-cmd --add-port=9300/tcp --permanent
# firewall-cmd --reload

最後にElasticsearch の自動実行をON にし,起動させる.

実行コマンド
# systemctl enable elasticsearch
# systemctl start elasticsearch

クラスターのノードを確認するには以下のコマンドを実行する.

クラスターのノードを確認
# curl http://192.168.226.137:9200/_cat/nodes

ノードが3台表示され,3台でクラスターが構築されていることが分かる.

実行結果
192.168.226.138 12 87 1 0.00 0.00 0.00 dilm * node-2
192.168.226.137 10 91 1 0.00 0.00 0.00 dilm - node-1
192.168.226.139 13 87 1 0.00 0.01 0.00 dilm - node-3

クラスターの状態確認は以下のコマンドを実施する.

クラスターの状態を確認
# curl http://192.168.226.137:9200/_cluster/health?pretty

実行すると,ステータスがgreen となっており,number_of_nodes の値も3となっており,3台で正常にクラスターが組まれていることが分かる.

実行結果
{
  "cluster_name" : "exam-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 4,
  "active_shards" : 8,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

データノードやマスター候補ノードの設定は明示的に設定しなかったが,デフォルトでデータノードおよびマスター候補ノードになることが分かった.

今後の予定

以下,取り組みたい内容は以下のとおりである.

複数の種類のログファイルの安全な取り込み

最新データの更新 (未実装)

他インデックスの情報の結合処理 (未実装)

csvファイルの出力 (未実装)

課題一覧

  • logstash サービスから自動でログが取り込まれない【解決済み】 → logstash サービスがlogstash ユーザーで実行されるため,取り込むログファイルがroot ユーザーなど実行ユーザーのおいて権限がない場合だと,Permission denied となり失敗する.ただし,root ユーザーでlogstash の実行ファイルを実行させると,root ユーザーで実行されるため,その問題が解消される.そのため,前回は実行ファイルの実行だと問題なかったが,サービス起動だとログが取り込まれなかった.ログを取り込むスクリプトでオーナーを変更することで解決した.

本事象は,/var/log/logstash/logstash-plain.log からエラーメッセージを確認することで解決できた.(/var/log/test にあるファイルに権限がないというエラーメッセージが出力されていた.)

  • Elasticsearch でクラスターが組まれない【解決済み】 → /etc/elasticsearch/elasticsearch.yml に以下の記述が必要だった. cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

本事象は,/var/log/elasticsearch/exam-cluster.log からエラーメッセージを確認することで解決できた.(上記の記述がないというエラーメッセージが出力されていた.)

  • 複数の種類のログファイルの安全な取り込み【未解決】 Logstash で複数のログファイルを複数の.conf で取り込もうとすると,ログの保存先インデックスが混ざる.(Aというインデックスにだけ保存したいログデータがBというインデックスにも保存されてしまう) → おそらくlogstash の設定ファイルにtype でif の条件式をfilter やoutput に追記する必要があると思われる.
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3