Edited at

Splunkのクラスター環境を10分で構築してやるよ

More than 1 year has passed since last update.


はじめに

Splunkはデータの規模に応じてスケールアップすることができます。

ログやデータをインデックスしている Indexer がダウンした場合でもサーチを続けられるように冗長構成を組むこともできます。

この冗長構成を クラスター と呼びますが、今回はクラスター環境の簡単な構築方法を記載します。


予備知識

まずはSplunkのクラスター環境についての基礎知識を少々。

知ってるよ、って方は読み飛ばしてください。


Splunkコンポーネント


  • Indexer : ログやデータをインデックスするところ。クラスター環境の場合、 Search Peer もしくは Peer Node という。Elastic Stackでいうと、Elasticsearch。


  • Search Head : 主にユーザーがログインしてサーチするところ。他にもAPI Callやスケジュールサーチ、アラートもここで担う。Elastic Stackでいうと、Kibana。


  • Forwarder : データ転送元。ログサーバーやその他ログを保管しているサーバーにインストールするもの。Elastic Stackでいうと、Beats。

    (LogstashはForwarderとIndexerに跨ってる感じかな)


  • Cluster Master : クラスターを管理する管理系コンポーネント。データのレプリケーションをどのIndexerに作るとか、サーチをした際にデータがどのIndexerにあるとか、Indexerがダウンしたらレプリケーション作るとか、けっこう忙しい。


  • License Master : Splunkのライセンスを管理する管理系コンポーネント。どれくらいデータをインデックスしたか、サーチしながらチェックしてやがる。


  • Deployment Server : ForwarderにAppを展開する管理系コンポーネント。どのディレクトリのどのファイルをインデックスするかとか、どのIndexerに送るか、というのもAppとして管理するんだぜ。



ポート

Splunkの各コンポーネントが通信する際のポートは下図参照

369-splunk-common-network-ports-ver1.5.jpg



  • 8089 全てのSplunkインスタンス(ForwarderではInbound不要)で必須


  • 8000 Search Headのみ


  • 9997 Indexerのみ


  • 8080 Indexerのみ


インデックスのレプリケーション

インデックスしたデータをIndexerでレプリケーションする場合、2つの要素があります。

Search Factor (以下、SF)Replication Factor (以下、RF) です。

そもそもSplunkにインデックスされたデータは、主に 圧縮された生データ(journal.gz)インデックス(tsidx) の2つでSplunk内に保管されます。

この2つが揃って(実際は他のメタデータもありますが)初めてサーチできることになります。

話を戻して、レプリケーションするとき、



  • SF で指定した数字は生データとインデックスをクラスター内でいくつ保有するか


  • RF で指定した数字は生データのみをクラスター内でいくつ保有するか

この2つを指定してやります。

「どうやって決めればいいの?」 という疑問が出てくると思いますが、基本的には 「何台のIndexerダウンを許容するか」 です。

そのうえで、


  • SFは 「サーチを途切れさせないようにするため、何台までのIndexerダウンを許容するか」

  • RFは 「データの欠損が出ないようにするには何台までのIndexerダウンを許容するか」

ということで決めます。

RFで指定した生データのみのコピーの場合、Indexerがダウンしたら生データからインデックスを作成するので、(データ量にもよりますが)サーチ可能になるまで数時間要します。

SF=2, RF=3という構成が一般的(デフォルト?)ですが、この数字はお好みで。

この場合、インデックスはオリジナル含めて2個、生データはオリジナル含めて3個が複数のIndexerに渡って保有されている状態になりますので、最低3台のIndexerが必要になります。


やってみよう

ということで、これからCLIやシェルを駆使して10分でクラスター環境構築してやるよ。

(今までの予備知識は10分にカウントしないでね)

今回は検証環境ということで、9台のEC2を使って構築します。

OSは Amazon Linux


完成イメージ

こんな感じ(逆にわかりづらいか)

general_cluster.png


Splunkインストール

Splunkはこのシェル実行しちゃってサクッとインストール


install.sh

#!/bin/bash

ENT_FILE="splunk-7.0.3-fa31da744b51-Linux-x86_64.tgz"
FWD_FILE="splunkforwarder-7.0.3-fa31da744b51-Linux-x86_64.tgz"

ENT_VERSION=`echo $ENT_FILE | sed 's/-/ /g' | awk '{print $2}'`
FWD_VERSION=`echo $FWD_FILE | sed 's/-/ /g' | awk '{print $2}'`

ENT_URL="https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=linux&version=$ENT_VERSION&product=splunk&filename=$ENT_FILE&wget=true"
FWD_URL="https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=linux&version=$FWD_VERSION&product=universalforwarder&filename=$FWD_FILE&wget=true"

while read line
#for line in `cat servers.list`
do
ip=`echo $line | awk '{print $1}'`
package=`echo $line | awk '{print $2}'`
name=`echo $line | awk '{print $3}'`

INSTALL_FILE=`eval echo \\"\\${${package}_FILE}\\"`
WGET_URL=`eval echo \\"\\${${package}_URL}\\"`
if [ $package = "ENT" ]; then
DIRECTORY="splunk"
elif [ $package = "FWD" ]; then
DIRECTORY="splunkforwarder"
fi

REMOTE_SCRIPT="
echo '# Add User and Group'
sudo groupadd -g 501 splunk
sudo adduser -u 501 -g 501 splunk
echo '# Wget Package File'
wget -nv -O
$INSTALL_FILE '$WGET_URL'
echo '# Install Splunk'
sudo tar zxf /home/ec2-user/
$INSTALL_FILE -C /opt/
echo '# Change Owner to splunk'
sudo chown -R splunk:splunk /opt/
$DIRECTORY
echo '# Start Splunk'
sudo -u splunk /opt/
$DIRECTORY/bin/splunk start --accept-license --answer-yes --no-prompt
echo '# Set Hostname'
sudo -u splunk /opt/
$DIRECTORY/bin/splunk set default-hostname $name -auth admin:changeme
echo '# Set Server Name'
sudo -u splunk /opt/
$DIRECTORY/bin/splunk set servername $name -auth admin:changeme
echo '# Enable Boot-Start'
sudo /opt/
$DIRECTORY/bin/splunk enable boot-start -user splunk
echo '# Restart Splunk'
sudo -u splunk /opt/
$DIRECTORY/bin/splunk restart
"

echo "Connecting... $ip"

ssh -n ${ip} "${REMOTE_SCRIPT}"
echo "---------------------------"

#done
done < servers.list

echo "Done"


-- 2018/04/25 追記 ココカラ --

Splunkのバージョン 7.1.0 (2018年4月24日リリース)以降を使う場合は、 --no-prompt 使ってはいけないみたいです。

どうやら初回起動で admin ユーザーのパスワードを設定するみたいなので、 --no-prompt を指定するとパスワード設定の処理をスキップしてしまい、ユーザーが作成されていない状態のままログインできなくなるみたいです。(対処法あるにはあるのですが...)

なので、 7.1.0 以降を使う場合は初回起動を以下のように書き換えましょう。

sudo -u splunk /opt/$DIRECTORY/bin/splunk start --accept-license --answer-yes --seed-passwd changeme

この --seed-passwd は7.1.0の新しいオプションのようです。

-- 2018/04/25 追記 ココマデ --

シェルと同じディレクトリにサーバーのIPとSplunホスト名・サーバー名をリストにします。

※ 第2項目は、Splunk Enterpriseなら ENT 、Universal Forwarderなら FWD


servers.list

10.0.0.101 ENT cm    # Cluster Master

10.0.0.102 ENT lm # License Master
10.0.0.103 ENT ds # Deployment Server
10.0.0.111 ENT sh # Search Head
10.0.0.121 ENT idx-1 # Indexer Cluster #1
10.0.0.122 ENT idx-2 # Indexer Cluster #2
10.0.0.123 ENT idx-3 # Indexer Cluster #3
10.0.0.131 FWD fwd-1 # Forwarder #1
10.0.0.132 FWD fwd-2 # Forwarder #2

各サーバーに splunk というユーザーを作成してSplunk起動しているので、以降CLI実行するときには  sudo -u splunk をつけています。


ライセンス関連

ライセンスはLicense Masterで一括管理します。


まずはLicense Masterにライセンスを追加

## Add License @License Master

ssh 10.0.0.102
sudo -u splunk /opt/splunk/bin/splunk add licenses <license_file_path> -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart


License Slave設定

Cluster Master、Deployment Server、Search Head、IndexerをLicense Slaveにする。

つまり、Splunk Enterpriseを入れたコンポーネントのライセンスは全てLicense Masterに集約するということ。

## Switch to License Slave

## @Cluster Master
ssh 10.0.0.101
sudo -u splunk /opt/splunk/bin/splunk edit licenser-localslave -master_uri https://10.0.0.102:8089 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

## @Deployment Server
ssh 10.0.0.103
sudo -u splunk /opt/splunk/bin/splunk edit licenser-localslave -master_uri https://10.0.0.102:8089 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

## @Search Head
ssh 10.0.0.111
sudo -u splunk /opt/splunk/bin/splunk edit licenser-localslave -master_uri https://10.0.0.102:8089 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

## @Indexer #1
ssh 10.0.0.121
sudo -u splunk /opt/splunk/bin/splunk edit licenser-localslave -master_uri https://10.0.0.102:8089 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

## @Indexer #2
ssh 10.0.0.122
sudo -u splunk /opt/splunk/bin/splunk edit licenser-localslave -master_uri https://10.0.0.102:8089 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

## @Indexer #3
ssh 10.0.0.123
sudo -u splunk /opt/splunk/bin/splunk edit licenser-localslave -master_uri https://10.0.0.102:8089 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart


確認してみよう

ちゃんとLicense設定できたかな?

## Check License Slaves

ssh 10.0.0.102
sudo -u splunk /opt/splunk/bin/splunk list licenser-slaves -auth admin:changeme

License SlaveになっているSplunkインスタンスのGUIDが表示されます。

    32C8226F-E30E-4E18-82CD-04040F569025

active_pool_ids:
auto_generated_pool_enterprise
label:lm
pool_ids:
auto_generated_pool_enterprise
auto_generated_pool_forwarder
auto_generated_pool_free
stack_ids:
enterprise
forwarder
free
warning_count:0

5F6F26AE-ADF3-4E94-BE51-12219BFAB1CF
active_pool_ids:
auto_generated_pool_enterprise
label:idx-1
pool_ids:
auto_generated_pool_enterprise
auto_generated_pool_forwarder
auto_generated_pool_free
stack_ids:
enterprise
forwarder
free
warning_count:0

...

各SplunkインスタンスのGUIDを確認するには下記コマンドで

sudo -u splunk grep guid /opt/splunk/etc/instance.cfg


クラスター関連


Cluster Master設定

SFは2、RFは3でCluster Masterを作成する。

## Add Cluster Master

ssh 10.0.0.101
sudo -u splunk /opt/splunk/bin/splunk edit cluster-config -mode master -replication_factor 3 -search_factor 2 -secret idxcluster -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

-secret の引数で指定する値は何でもいいけど、以降のステップで指定するものと同じにしないといけないよ。


IndexerをクラスターのSearch Peerにする

レプリケーションで使うポートは 8080 として、ついでにForwarderからのデータ受信をポート 9997 で設定しておく。

## Add Cluster Peer

ssh 10.0.0.121
sudo -u splunk /opt/splunk/bin/splunk edit cluster-config -mode slave -master_uri https://10.0.0.101:8089 -replication_port 8080 -secret idxcluster -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk enable listen 9997 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

ssh 10.0.0.122
sudo -u splunk /opt/splunk/bin/splunk edit cluster-config -mode slave -master_uri https://10.0.0.101:8089 -replication_port 8080 -secret idxcluster -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk enable listen 9997 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart

ssh 10.0.0.123
sudo -u splunk /opt/splunk/bin/splunk edit cluster-config -mode slave -master_uri https://10.0.0.101:8089 -replication_port 8080 -secret idxcluster -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk enable listen 9997 -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart


Search HeadでサーチできるようにCluster Masterと紐付ける

## Add Search Head to Cluster

ssh 10.0.0.111
sudo -u splunk /opt/splunk/bin/splunk edit cluster-config -mode searchhead -master_uri https://10.0.0.101:8089 -secret idxcluster -auth admin:changeme
sudo -u splunk /opt/splunk/bin/splunk restart


AppをIndexerに配布する場合

前提として、SplunkのAppは $SPLUNK_HOME/etc/apps/ に格納されます。

ただし、クラスターのSearch PeerにAppをインストールする場合は、直接上記ディレクトリに入れるのではなく、 Cluster Master$SPLUNK_HOME/etc/master-apps/ にAppを置いて、Bundle として各Search Peerに配布することになります。

インデックスしたデータのレプリケーションしているからには、設定を含むAppもちゃんとCluster Masterで管理しなさいよ、ということです。

## Deploy Apps to Peer Nodes

ssh 10.0.0.101
sudo -u splunk cp -p -r <APP_DIR> /opt/splunk/etc/master-apps/

## Validate Cluster Bundle
sudo -u splunk /opt/splunk/bin/splunk validate cluster-bundle -auth admin:changeme

## Commit Cluster Bundle
sudo -u splunk /opt/splunk/bin/splunk apply cluster-bundle

## Check Cluster Bundle Status
sudo -u splunk /opt/splunk/bin/splunk show cluster-bundle-status

## Rolling Restart
sudo -u splunk /opt/splunk/bin/splunk rolling-restart cluster-peers -auth admin:changeme


Forwarderセットアップ

Deployment Server$SPLUNK_HOME/etc/deployment-apps/ にAppを置いてForwarderに配布します。

今回の検証環境のようにForwarderが2台だけなら 「そんなめんどくせーもん要らねえよ ( ゚д゚)、ペッ」 となりそうですが、規模が大きくなると数百台、数千台のForwarderを扱うことになり、それぞれで扱うデータも異なるので、Deployment Server使わないと管理が難しくなってしまうのです。


Indexer Discoveryを有効にする

ナニソレ美味しいの? ってなりますよね。

例えば、Forwarderでデータ転送先Indexerをホスト名やIPアドレスでベタ書きすると、Indexerを拡張していったとき、毎回その設定を書き換えなきゃいけなくなります。

Forwarderからの転送先Indexerをクラスター内のSearch Peerにしたい。

だったら、ForwarderからCluster Masterに対象のIndexerが何かを問い合わせればいいや、ってことになります。

ということで、Cluster Masterで設定します。

## Edit server.conf @Cluster Master

ssh 10.0.0.101
sudo -u splunk vi /opt/splunk/etc/system/local/server.conf

server.conf に以下の2行を追加

[indexer_discovery]

pass4SymmKey = idxforwarders

で、Cluster MasterのSplunk再起動

sudo -u splunk /opt/splunk/bin/splunk restart


Deployment ServerでApp作成

ということで、Indexerへのデータ転送をAppという形でForwarderに展開します。

データ転送は outputs.conf で設定します。

まずはAppディレクトリと outputs.conf を作成

## Create App Directory and outputs.conf

ssh 10.0.0.103
sudo -u splunk mkdir -p /opt/splunk/etc/deployment-apps/uf_base/local
sudo -u splunk vi /opt/splunk/etc/deployment-apps/uf_base/local/outputs.conf

outputs.conf で以下を設定

ここでIndexer Discoveryを指定するわけですね。

[tcpout]

defaultGroup = default-autolb-group

[tcpout:default-autolb-group]
indexerDiscovery = idxc1
useACK = true

[indexer_discovery:idxc1]
master_uri = https://10.0.0.101:8089
pass4SymmKey = idxforwarders


ForwarderをDeployment Serverに通信させる

Deployment ServerがForwarderにAppを展開するといっても、どこにForwarderがあるのか把握してなければ無理だよね。

ということで、ForwarderからDeployment Serverに疎通させて、自分の居場所を教えてあげましょう。

Forwarderで下記CLIを実行

## Set Deploy Poll @Forwarder

ssh 10.0.0.131
sudo -u splunk /opt/splunkforwarder/bin/splunk set deploy-poll 10.0.0.103:8089 -auth admin:changeme
sudo -u splunk /opt/splunkforwarder/bin/splunk restart

ssh 10.0.0.132
sudo -u splunk /opt/splunkforwarder/bin/splunk set deploy-poll 10.0.0.103:8089 -auth admin:changeme
sudo -u splunk /opt/splunkforwarder/bin/splunk restart


Deployment ServerからForwarderにAppを配布

さて、いよいよ配布です。

Deployment Serverで、どのAppをどのForwarderに配布するか serverclass.conf で指定

ssh 10.0.0.103

sudo -u splunk vi /opt/splunk/etc/system/local/serverclass.conf

serverclass.conf に以下を追加

[serverClass:uf_base:app:uf_base]

restartSplunkWeb = 0
restartSplunkd = 1
stateOnClient = enabled

[serverClass:uf_base]
whitelist.0 = ip-10-0-0-13*

Deployment ServerのSplunk再起動

sudo -u splunk /opt/splunk/bin/splunk restart

しばらくするとForwarderにAppディレクトリ uf_base が展開されていることが確認できます。

ssh 10.0.0.131

sudo -u splunk ls -l /opt/splunkforwarder/etc/apps

ssh 10.0.0.132
sudo -u splunk ls -l /opt/splunkforwarder/etc/apps


全SplunkインスタンスのデータをSearch Peerに集約

これを忘れちゃいけないよ。

Cluster環境を組むとユーザーはSearch HeadにログインしてSearch Peerにインデックスされたデータをサーチすることになります。

License MasterやCluster Master、Deployment Serverといった管理系コンポーネントや、Search HeadでもSplunkそのもののインターナルログが _internal_audit といった、アンダースコアで始まるインデックス名で勝手にインデックスされます。

なので、これらのコンポーネントでも outputs.conf でSearch Peerにデータ転送するよう設定しましょう。

## Edit outputs.conf @Cluster Master

ssh 10.0.0.101
sudo -u splunk mkdir -p /opt/splunk/etc/apps/outputs/local
sudo -u splunk vi /opt/splunk/etc/apps/outputs/local/outputs.conf

## Edit outputs.conf @License Master
ssh 10.0.0.102
sudo -u splunk mkdir -p /opt/splunk/etc/apps/outputs/local
sudo -u splunk vi /opt/splunk/etc/apps/outputs/local/outputs.conf

## Edit outputs.conf @Deployment Server
ssh 10.0.0.103
sudo -u splunk mkdir -p /opt/splunk/etc/apps/outputs/local
sudo -u splunk vi /opt/splunk/etc/apps/outputs/local/outputs.conf

## Edit outputs.conf @Search Head
ssh 10.0.0.111
sudo -u splunk mkdir -p /opt/splunk/etc/apps/outputs/local
sudo -u splunk vi /opt/splunk/etc/apps/outputs/local/outputs.conf

[indexAndForward]

index = false

[tcpout]
defaultGroup = default-autolb-group
forwardedindex.filter.disable = true
indexAndForward = false

[tcpout:default-autolb-group]
indexerDiscovery = idxc1
useACK = true

[indexer_discovery:idxc1]
master_uri = https://10.0.0.101:8089
pass4SymmKey = idxforwarders

で、Splunk再起動

sudo -u splunk /opt/splunk/bin/splunk restart

これも Deployment Server で管理してもいいかもですね。


Splunkにログインして確認

ブラウザからSearch Headにログインして確認してみましょう。

サーチ画面に進んで下記サーチ文を実行

| tstats count where index=_internal by host splunk_server

tstats はインデックスのみを検索してメタデータの統計を出すコマンド。

通常のサーチよりちょっぱやで結果が帰ってきます。

Screen Shot 2018-04-13 9.30.35 PM.png

ここで、 host はログ発生元のホスト名、 splunk_server はインデックスされているSplunkサーバー名です。



  • host はCLI $SPLUNK_HOME/bin/splunk set default-hostname で設定


  • splunk_server はCLI $SPLUNK_HOME/bin/splunk set servername で設定

各Splunkインスタンスのインターナルログが idx-1 idx-2 idx-3 に分散されてインデックスされていることがわかります。


最後に

ね、簡単でしょ?

ユーザーが増えたときに負荷分散するためにSearch Headを冗長化する Search Head Cluster や、DRのために複数拠点でレプリケーションする Multisite Cluster というのもありますが、それはまた別の機会に。


反省

10分というのは盛りすぎましたね。

ちょこちょこ再起動してるので、もうちょい時間かかるかもです。