簡単だけど注意しておきたいSplunkインストール前の考慮点

本記事は、Splunk Advent Calendar 2019 の2日目の内容になります。
# はじめに

普段、主に業務でSplunkを0からインストールし各種設定を行うことを対応しております[石橋](https://qiita.com/bashi100kmrun)と申します。よろしくお願いします。
Splunk歴は浅いですが、これまで様々なOS/構成のSplunk構築業務を行ってきましたので、それらから得たコトよりSplunkをインストールする時の考慮点などを共有したいと思います。
ちょっくらSplunkを使ってみっかと考えている人の参考になれば幸いです。

## Splunkはインストールだけなら超簡単

いきなり自分の仕事を否定するようなことを書きますが、Splunkは「いったん手持ちのデータを分析できるようにする」だけなら、すぐに使うことができます。

Splunk外のモジュールやライブラリを予めインストールしておくことは基本的にはなく、カーネルパラメータや環境変数の設定などといったOS環境に関わる変更も事前にすることはあまりないため※1、アンインストールも特に苦労はせず実施できます。製品評価を行う点において、検証環境にサクッと入れて評価後はサクッと消すことが簡単に出来るのはSplunkの一つのメリットではないかと思います。

※1.LinuxOSにインストールする場合はSplunk起動ユーザやリソース割り当てに関する考慮が必要です(後述)

## 設定変更も難しくはない(Splunkだけなら)

Splunkの設定方法は、大きく分けて3種類あります。

1. GUI(Splunk管理画面)で変更する。
2. CLI(splunkコマンド)で変更する。
3. 設定ファイルの内容を変更する。

それぞれメリット/デメリットがありますが、どの方法でも最終的に設定ファイルに設定パラメータが記録されます。Splunkは仕様上さまざまな設定ファイルを持っていますが、設定パラメータはいずれかの設定ファイルに残るようになっています。よって、Splunkをまずはデフォルト設定でインストールし、後から設定を変更することはあまり難しいことではありません。
そう、Splunkのことだけならね。

# 本題

ようやく本題ですが、Splunkを何らかのシステムの一つとして使う場合に気を付けるポイントについて説明します。

1. インストールパス(`SPLUNK_HOME`)
2. データ保存パス(`SPLUNK_DB`)
3. Splunkプロセス起動ユーザー
4. 通信ポート
5. NTP
6. 自動起動設定(主にUnix版)

## 1.インストールパス(`SPLUNK_HOME`)

Windows版Splunkインストーラは、インストーラー実行時にインストールパスを指定できます。デフォルトでは`C:\Program Files\Splunk`が指定されます。一方Unix版はrpmパッケージでインストールした場合とtar.gzファイルを展開した場合とでインストールパスが異なります。

1. rpmパッケージでインストールした場合・・・デフォルトでは`/opt/splunk`にインストールされ、自動でOSにsplunkユーザーが生成されます。(uid,gidは10777のようです。なお、執筆当時のバージョンでは1001でした) なお、インストールパスを変更する場合は、rpmのコマンドオプションに`--prefix=<Install Path>`を指定することで任意のパスに変更することができます。

2. tar.gzファイルを展開した場合・・・tarの`-C`オプションを指定しない限り、tar.gzがあるパスに`splunk`ディレクトリが生成され、その中に実行モジュールが一式展開されます。(中身のuid,gidは10777のようです。なお、執筆当時のバージョンでは1001でした)

なお、マニュアルではUnix版のインストールパスは`/opt/splunk`で統一されているようです。また、マニュアルやREADMEではインストールパスのことを`$SPLUNK_HOME`というキーワードで説明されていたりしますが、環境変数の設定は不要です。

## 2.データ保存パス(`SPLUNK_DB`)
Splunkに取り込んだデータは、デフォルトではSplunkインストール先と同じパスに保存されます。
インストール先はOSによって異なります。

| Host OS | Data Path | Default Path |
|:---:|:-- |:-- |
| Linux | `<Install Path>/var/lib/splunk` | `/opt/splunk/var/lib/splunk` |
| Windows | `<Install Path>\var\lib\splunk` | `C:\Program Files\Splunk\var\lib\splunk` | 

データ保存先をデフォルト設定から変える場合、以下の設定ファイルにパラメータを絶対パスとして設定します。
※設定を変更した後はSplunkプロセスの再起動が必要です。

| Configuration File | Parameter Name | Default Value |
|:-:|:-:|:-:|
|`<Install Path>/etc/splunk-launch.conf` | SPLUNK_DB | `<Install Path>`/var/lib/splunk |

なお、データ保存パスを変更しても、パス変更前のデータは変更後のパスに自動で移動しませんし、変更前パスの削除もされません。このため「パス変更前のデータを変更後もSplunkでサーチできるようにしたい」といった要件がある場合、過去データの移行について検討する必要がでてきます。

また、データ取り込み量の増加やデータ保管期間の変更などによって、ディスク領域を増やす必要が出てきた場合、データ保存先がシステム領域と同じパーティションかそうでないかによって検討事項などが変わってくることが想定されます。

インストール前の段階でSplunk導入後のデータ量について検討しておき、その検討結果に従ってデータ保存先パスをデフォルトのままとするのか考慮するのが望ましいと思います。

### ※NFSについて
データ保存パスをNFSにする場合、インデックスのパフォーマンスに悪影響が出る可能性があることを考慮するようマニュアルに記載されてます。また、マニュアルにはホットバケツやウォームバケツのパスとしてNFSを割りててはいけないと記載されています。

しかし、`SPLUNK_DB`で指定するパスについてバケツ単位での指定は出来ないため、事実上`SPLUNK_DB`にNFSのパスを指定することは不可能です。よって、あるインデックスのコールド/フローズンのバケツのパスのみNFSを指定することが(設定的には)可能ということになります。

※参考
[Considerations regarding Network File System (NFS)](https://docs.splunk.com/Documentation/Splunk/latest/Installation/Systemrequirements#Considerations_regarding_Network_File_System_.28NFS.29)

### ※CIFS/SMBについて
データ保存パスをCIFS/SMBにする場合については、一部のバケツ(コールド/フローズン)では使える旨がマニュアルに記載されています。こちらについてもNFS同様に事実上`SPLUNK_DB`ではCIFSのパスを指定することは不可能です。

※参考
[Considerations regarding Common Internet File System (CIFS)/Server Message Block (SMB)](https://docs.splunk.com/Documentation/Splunk/latest/Installation/Systemrequirements#Considerations_regarding_Common_Internet_File_System_.28CIFS.29.2FServer_Message_Block_.28SMB.29)

## 3.Splunkプロセス起動ユーザー
Splunkはプロセス起動ユーザーが特権ユーザー(いわゆるrootやAdministrator)か非特権ユーザーによって動作が変わることはありません。非特権ユーザーでもインストールパスおよびデータ保存先に適切なパーミッションが設定されていれば実行することができます。
一方、Splunkにデータを自動で取り込めるようにする場合において、起動ユーザーが深く関係してきます。"自動で取り込めるようにする"とは、例えば以下のようなシチュエーションです。

- 例
 - サーバーやアプリケーションが出力するログファイル（例：`/var/log/messages`）をSplunkに継続的に取り込めるようにしたい。
 - スクリプトの実行結果を毎分Splunkに継続的に取り込めるようにしたい。
 - あるディレクトリ（例:`/tmp/upload`）にファイルを置いたら、そのファイルをSplunkに自動で取り込めるようにしたい。

上記を実現するための前提条件として「Splunk起動ユーザーに適切なパーミッションが適用されていること」があります。つまり、ファイルを取り込むためにはSplunk起動ユーザーにファイルの読取権限が要りますし、スクリプトの実行結果を取り込むにはSplunk起動ユーザーにスクリプトの実行権限が要ります。

Splunkの起動ユーザーを特権ユーザーにすればパーミッションを意識する必要は殆どなくなりますが、システムのセキュリティ要件などで、プロセスの起動ユーザーに特権ユーザーが認められない場合、取り込み対象のファイル/実行スクリプトのパーミッションに注意が必要です。

注意が必要な例：
Splunkのプロセス起動ユーザーは非特権ユーザー(root以外)とし、
OSのシステムログ(`/var/log/messages`,Windowsイベントログ(システム))を取り込む設計とする。
→ システムログは通常特権ユーザーしか読取権限がない。OMG。
→ システムログのパーミッションを変える？システムログの内容を別ファイルに出力してそっちを読み取るようにする？
→ 起動ユーザの権限をどげんかする？

・・・というような課題がでてくることに注意が必要です。
また、Splunkはデータ取り込み対象だけではなくSpunkが参照するファイルにも起動ユーザーのパーミッションが必要です。よって、プロセス起動ユーザーを後から別ユーザーに変更する場合は、インストール先パスおよびデータ保存先パスのファイル/ディレクトリのパーミッションも変更する必要があります。

なお、Splunk社は特権ユーザーでのプロセス起動を非推奨とし、Splunkの起動には専用アカウントを作ることを推奨としているようです。

## 4.通信ポート
SplunkはTCPのポートを複数使用します。このポートはインストール後も設定変更できます。しかし、通信ポートを後から変更する場合、ファイアウォールやロードバランサーなどSplunk外の機器の設定などにも影響する可能性があるため、可能であればインストール前に通信要件を十分考慮しておく必要があります。

以下に代表的なポートをご紹介します。
※デフォルト設定ファイルは`<Install Path>/etc/system/default/`に保存されています。

| No | Objective | Default No(TCP) | Configuration File | Stanza | Attribute  | misc | 
|:--:|:----:|:----:|:---:|:---:|:--- |:--|
| 1 | Splunk管理通信用 | 8089 | web.conf | [settings] | mgmtHostPort | Splunkのほとんどの管理通信で使われる超重要なポート。 |
| 2 | Splunk管理画面用 | 8000 | web.conf | [settings] | httpport | Splunkのweb画面のアクセス先ポート。 |
| 3 | Web app-server proxy | 8065 | web.conf | [settings] | appServerPorts | 内部通信で使われるポート。 |
| 4 | KV store Port | 8191 | server.conf | [kvstore] | port | 内部通信で使われるポート。 |

### 通信ポートが既に使われていた場合の注意

CLIでSplunkを起動した時に、Splunkが使う通信ポートが既に別プロセスに使われていた場合、警告プロンプトが表示され、別のポートに変更するか起動処理を停止するか選ぶことができます。よって、Linux版Splunkは初回起動時に、(最悪)ポートが別プロセスに使われているか知ることができます。

一方、Windows版Splunkインストーラは、インストールが正常終了するとSplunkが自動で起動するのですが、Splunkの通信ポートが別サービスで使われていた場合、自動で別ポートを割り当ててしまいます。（8089ポートが既に使われていると8090をSplunk管理ポートとして使うよう設定してしまう。）この時、警告ウィザード等一切出ないため、通信要件が不明確の場合は特にSplunkのポートが使われていないか注意する必要があります。

### その他の通信ポート
その他、デフォルト値が明示されていないSplunkが使用する主な通信ポートについてご紹介します。

| No | Objective | Description |
| :-:|:--:|:--|
| 1 | データ受信用ポート | Splunkが他のSplunk(Universal Forwarder含む)からデータを受信するためのポート。マニュアルやweb画面などでは9997が指定されている。 |
| 2 | ネットワークデータ受信用ポート | syslogなどでデータを受信するためのポート。1ポート=1ソースタイプになる。 |
| 3 | レプリケーション用ポート | Splunkのクラスタリング構成(インデクサークラスター,サーチヘッドクラスター)においてSplunk間で使用するポート。マニュアルやweb画面などでは8080が指定されている。 |
| 4 | HEC 通信用ポート | SplunkでHECを使った場合にデータを受信するためのポート。マニュアルやweb画面などでは8088が指定されている。 |

Splunkのプロセス起動ユーザーを非特権ユーザーにする場合は、well-known-port(1024未満のポート)が使えないため、非特権ユーザーで通信ポートをデフォルトから変える場合は注意が必要です。

## 5.NTP
データを取り込んだときのタイムスタンプのズレを極力なくすため、SplunkサーバーはNTPサーバーと同期させておくのが望ましいです。

## 6.自動起動設定について

OSの起動/停止に合わせてSplunkの起動/停止を制御する場合、OSによって設定が異なります。

### WindowsOSの場合
Splunkのインストール時にデフォルトでOSの起動/停止に合わせてSplunkが起動/停止するよう、Windowsサービスに登録されるため、通常は特に設定する必要はありません。

### UnixOS(MaxOS含む)の場合

UnixOSの場合、Splunkインストール後に自動起動設定を行います。この際に考慮が必要なのが「systemd/sysVinit(initd)のどちらの起動方式を採用するのか」「どのユーザーでプロセスを自動起動させるのか」です。

#### systemd/sysVinit(initd)のどちらの起動方式を採用するのか

Splunkは自動起動を設定するCLIコマンドとして`splunk enable boot-start`というコマンドが用意されています。このコマンドを実行すると、OSの起動/停止に合わせてSplunkが起動/停止するように、OSに起動スクリプトが生成されます。

また、Splunkはバージョン7.2.2よりsystemdによる起動がサポートされました。
上記のCLIコマンド`splunk enable boot-start`を実行する時に、オプション`-systemd-managed 1`を指定することで、systemd起動の設定が行われます。
ここで、オプションを省略した場合、Splunkバージョンによって設定される起動方式が変わるので注意が必要です。

| Version | -systemd-managed 1 オプション省略時に設定される起動方式 | 
| :--:|:--|
| ～7.2.1 | 指定不可(オプションを指定するとエラーになります) | 
| 7.2.2 | systemd起動 | 
| 7.3.x～ | sysVinit(init)起動 | 
| 8.0.0~ | sysVinit(init)起動 | 
| 8.2.2※ | sysVinit(init)起動 | 

※2021/9/22時点の最新バージョン

なお、起動方式や起動ユーザーによって起動中のプロセスの引数が変わるようです。この点はSplunkプロセスの起動状態をSplunk外のプロダクトで監視する場合に考慮が必要です。

```md:psコマンド結果例
#sysVinit(init)起動の場合
root      3525     1 18 08:16 ?        00:00:01 splunkd -p 8089 start

#systemd起動の場合
root      3016     1 26 08:15 ?        00:00:01 splunkd --under-systemd --systemd-delegate=yes -p 8089 _internal_launch_under_systemd
```

#### どのユーザーでプロセスを自動起動させるのか

自動起動設定コマンド`splunk enable boot-start`に、オプション`-user <user_name>`を指定することでOS起動時に自動起動するSplunkのプロセス起動ユーザーを指定できます。
オプションを省略した場合は`root`で起動します。

ここで注意が必要なのが"sysVinit(init)起動"かつ"プロセス起動ユーザーが非特権ユーザー"の場合で、`splunk enable boot-start`コマンドを実行した後に手動で起動スクリプトを書き換える必要があります。

具体的には`/etc/init.d/splunk`ファイルに記載されているプロセス起動コマンドについて
非特権ユーザーで起動するよう修正します。

「-userオプションをつければOK!」と思いがちなので要注意です。

```bash:sysVinit(init)起動の場合の追記(/etc/init.d/splunk)

# 変更前
splunk_start() {
  echo Starting Splunk...
  "$SPLUNK_HOME/bin/splunk" start --no-prompt --answer-yes
(中略)
splunk_restart() {
  echo Restarting Splunk...
  "$SPLUNK_HOME/bin/splunk" restart
(後略)

# 変更後
USER=splunk # 追記
splunk_start() {
  echo Starting Splunk...
  su - ${USER} -c '"$SPLUNK_HOME/bin/splunk" start --no-prompt --answer-yes' # 修正
(中略)
splunk_restart() {
  echo Restarting Splunk...
  su - ${USER} -c '"$SPLUNK_HOME/bin/splunk" restart' # 修正
(後略)
```

※参考
[Enable boot-start as a non-root user](https://docs.splunk.com/Documentation/Splunk/latest/Admin/ConfigureSplunktostartatboottime#Enable_boot-start_on_.2Anix_platforms)

### リソース設定 ※Linux版のみ

Splunkは実行中に多くのOSリソースを消費するため、マニュアルにOSのulimitコマンドを使ったリソース割当設定が記載されています。

| System-wide Resource | ulimit invocation | Recommended min. value |
| :--: | :--: | :--: |
| Open files | ulimit -n | 64000 |
| User processes | ulimit -u | 16000 |
| Data segment size | ulimit -d | 8000000※ | 
| File size | ulimit -f | -1(unlimited) | 
※ドキュメントには*nix OSのData segment sizeについて``The maximum RAM you want Splunk Enterprise to allocate in kilobytes. For example, 8GB is 8000000.``と記載されています。つまり8GBはあくまで例であり、具体的な推奨値は明記されていないようです。

※参考
[Considerations regarding system-wide resource limits on *nix systems]
(https://docs.splunk.com/Documentation/Splunk/latest/Installation/Systemrequirements#Considerations_regarding_system-wide_resource_limits_on_.2Anix_systems)

ここで、OSの起動に合わせてSplunkが自動起動するように設定する場合、起動したプロセスに適切なリソースを割り当てるため、自動起動スクリプトにリソース設定の追記が必要になります。
なお、CLIによるオプションが用意されていないため、手動で設定ファイルを修正します。

また、sysVinit(init)起動方式において、Splunkをインストールパスから直接起動する場合(`<Install Path>/bin/splunk`を直接実行する場合)は、`/etc/init.d/splunk`に設定したulimit値が適用されないため、実行前にulimitコマンドを実行するか、`/etc/security/limits.conf`に、PAM認証を通ったユーザーへのリソース設定を入れておくことで、リソース割り当てを直接起動するSplunkプロセスに適用することができます。

```bash:/etc/security/limits.confのリソース設定例
    (splunk起動ユーザー名)		soft	nofile		64000
    (splunk起動ユーザー名)		hard	nofile		64000
    (splunk起動ユーザー名)		soft	nproc		16000
    (splunk起動ユーザー名)		hard	nproc		16000
    (splunk起動ユーザー名)		soft	data        8000000 
    (splunk起動ユーザー名)		hard	data        8000000
    (splunk起動ユーザー名)		soft	fsize       unlimited 
    (splunk起動ユーザー名)		hard	fsize       unlimited 

```

※参考
[Considerations regarding system-wide resource limits on *nix systems](https://docs.splunk.com/Documentation/Splunk/latest/Installation/Systemrequirements#Considerations_regarding_system-wide_resource_limits_on_.2Anix_systems)

[I get errors about ulimit in splunkd.log](https://docs.splunk.com/Documentation/Splunk/latest/Troubleshooting/ulimitErrors)

### THP設定 ※Linux版のみ

LinuxでSplunkを動かす場合、THPと呼ばれるOSの機能を無効化するようマニュアルに記述されています。
ここでOSの起動に合わせてSplunkが自動起動する場合にTHP機能を無効化するために、リソース設定同様、自動スクリプトに追記が必要になります。

※参考
[Transparent huge memory pages and Splunk performance](https://docs.splunk.com/Documentation/Splunk/latest/ReleaseNotes/SplunkandTHP)
### systemd起動方式時の特殊設定 ※Linux版(7.2.2～7.2.x)のみ

起動方式をsystemdにした場合、systemdのサービス停止時の仕様上、プロセスに強制終了(SIGTERM)シグナルを送るのがデフォルトの動作のようです。
強制終了にさせたくない場合はSplunkdのunitファイル(デフォルトでは`/etc/systemd/system/Splunkd.service`)に以下の設定を追加します。

```bash:
KillMode=mixed
KillSignal=SIGINT
```

なおSplunkバージョン8.0.1では、自動起動設定時に自動的にこの設定が入るようです。

※参考
[Splunkをsystemdサービスとして停止するときの問題について]
(https://answers.splunk.com/answers/735189/splunk%E3%82%92systemd%E3%82%B5%E3%83%BC%E3%83%92%E3%82%B9%E3%81%A8%E3%81%97%E3%81%A6%E5%81%9C%E6%AD%A2%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E5%95%8F%E9%A1%8C%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6.html)


### 起動スクリプトの修正例

以上のリソース設定およびTHP設定をふまえた自動起動スクリプトの例をinitd/systemdそれぞれご紹介いたします。
※設定値は導入サーバーのOSにあわせて適宜変更してください。

```bash:init.d起動の場合の修正例(/etc/init.d/splunk)

splunk_start() {
  if test -f /sys/kernel/mm/transparent_hugepage/enabled; then echo never > /sys/kernel/mm/transparent_hugepage/enabled # 追記
  fi # 追記
  if test -f /sys/kernel/mm/transparent_hugepage/defrag; then echo never > /sys/kernel/mm/transparent_hugepage/defrag # 追記
  fi # 追記
  ulimit -n 64000 # 追記
  ulimit -u 16000 # 追記
  ulimit -d 8000000 # 追記
  ulimit -f -1 # 追記
  echo Starting Splunk...
  su - ${USER} -c '"$SPLUNK_HOME/bin/splunk" start --no-prompt --answer-yes' # 修正
  
}
(中略)

splunk_restart() {
  if test -f /sys/kernel/mm/transparent_hugepage/enabled; then echo never > /sys/kernel/mm/transparent_hugepage/enabled # 追記
  fi # 追記
  if test -f /sys/kernel/mm/transparent_hugepage/defrag; then echo never > /sys/kernel/mm/transparent_hugepage/defrag # 追記
  fi # 追記
  ulimit -n 64000 # 追記
  ulimit -u 16000 # 追記
  ulimit -d 8000000 # 追記
  ulimit -f -1 # 追記
  echo Restarting Splunk...
  su - ${USER} -c '"$SPLUNK_HOME/bin/splunk" restart' # 修正
  RETVAL=$?
  [ $RETVAL -eq 0 ] && touch /var/lock/subsys/splunk
}
```
```bash:systemd起動の場合の追記(/etc/systemd/system/Splunkd.service)
(中略)
[Service]
Type=simple
Restart=always
ExecStartPre=/bin/bash -c "echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled && echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag" # 追記
ExecStart=/opt/splunk/bin/splunk _internal_launch_under_systemd
KillMode=mixed # 追記
KillSignal=SIGINT # 追記
TimeoutStopSec=360
LimitNPROC=16000 # 追記
LimitNOFILE=65536
LimitDATA=8589934592 #追記
LimitFSIZE=infinity #追記
TasksMax=8192 #追記
SuccessExitStatus=51 52
RestartPreventExitStatus=51
RestartForceExitStatus=52
Delegate=true
CPUShares=1024
MemoryLimit=1031450624

```

参考
[Enable boot-start on *nix platforms](https://docs.splunk.com/Documentation/Splunk/latest/Admin/ConfigureSplunktostartatboottime#Enable_boot-start_as_a_non-root_user)

# おわりに
はじめに書きましたがSplunkの設定変更自体はあまり難しい作業ではありません。
設定値を決め、設定変更し、設定を適用して終わり。シンプルな流れです。

では、上記で挙げたことを全て気を付けて設定すればどんな環境でも大丈夫！・・・かというと、そうではなく、環境によって注意しなければならないことは環境により他にも様々あることが考えられます。（独自サーバー証明書が要るとか、LDAP認証をするとか）

ポイントは、後から変更することが容易なこと/後から変えることが大変なことを、予め想定したうえで設計を進めてくことが導入時/導入後のトラブルを防ぐうえで大事ではないかと思います。
ありがとうございました。

# 補足
Splunkはインストール時にOSの環境変数を設定しません。また、実行バイナリは<Install Path>/bin/配下に保存されています。よって、本文中に記載しているCLIコマンドを実行するためには、実行バイナリのディレクトリでコマンドを実行するか、コマンドパスを通しておく必要があるのでご注意ください。