ログ分析基盤の構築#1（Elastic Stack）

# はじめに
ログ分析基盤の有名どころとしてはSplunkだが、やはり商用での壁としてライセンス問題がある。
Splunkライクな使い方をElasticStackで実現してみる。
なお、ユーザー認証がbasicライセンスで提供されているため、ユーザー認証を有効にする。

# 環境
できるだけナウい環境を利用する。今回はコンテナを利用する。
なお、複数のコンテナより実現するため、docker-composeを利用する。

```
# MacBook Pro(13-inch, 2017, Four Thunderbolt 3 Ports)
# 3.1GHz DualCore Intel Core i5
# 16GB 2133 MHz LPDDR3
strike:~ marseille$ uname -a
Darwin strike.local 19.5.0 Darwin Kernel Version 19.5.0: Tue May 26 20:41:44 PDT 2020; root:xnu-6153.121.2~2/RELEASE_X86_64 x86_64
strike:~ marseille$ docker -v
Docker version 19.03.8, build afacb8b
```
# コンテナの準備
オフィシャルイメージを利用する。詳しい環境変数の解説は各サブセクションにて実施する。

## フォルダ構成

- mnt/configに各コンテナの設定ファイルを設置し環境設定を柔軟にできるように準備したが、現状では利用していない。
- mnt/es-dataにはelasticsearchが蓄積するデータを格納する。ホスト側ボリュームをマウントすることによりデータの永続化を行う。
- mnt/logstash-pipelineは、logstashにて収集するデータに関する処理を定義するファイルを格納する。
- reference/elasticsearchは、mnt/configに設置するためのベースとなるelasticの設定ファイルを一時的に保存してある。
- reference/kibanaもelasticsearchと同様。
- reference/kibana-dockerは、コンテナの環境変数で設定できる引数が一覧化されたファイルが設置されている。

```
.
├── docker-compose.yml
├── mnt
│   ├── config
│   ├── es-data
│   └── logstash-pipeline
│       └── hello-logstash.conf
├── reference
│   ├── elastichsearch
│   │   ├── elasticsearch.yml
│   │   └── elasticsearch.yml.origin
│   ├── kibana
│   │   ├── kibana.yml
│   │   └── kibana.yml.origin
│   └── kibana-docker
└── tmp
    └── syslog.cfg

```

## コード
kibanaはdocker-composeの環境変数を利用して設定する場合、以下に注意する必要がある。

- dot(.)を(_)にする
- アルファベットを大文字にする

ちなみに、コンテナ内部に格納されている「/usr/share/kibana/config/kibana.yml」ファイルを読むとこの説明書きが記載されている。

```:記述例
# configファイル
elasticsearch.password=your-password
# container environment
ELASTIC_PASSWORD=your-password
```

```yml:docker-compose.yml
version: "3"

## https://tsgkdt.hatenablog.jp/entry/2019/07/10/234747

services:
    elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:7.6.2
        environment:
            - discovery.type=single-node
            - cluster.name=docker-cluster
            - bootstrap.memory_lock=true
            - "ES_JAVA_OPTS=-Xms512m -Xmx1g"
            - xpack.security.enabled=true
            - xpack.security.authc.api_key.enabled=true
            - ELASTIC_PASSWORD=your-password
        ulimits: 
            memlock:
                soft: -1
                hard: -1
        volumes: 
            #- ./mnt/config/elastichsearch:/usr/share/elasticsearch/config
            - ./mnt/es-data:/usr/share/elasticsearch/data

# kibana config file => /usr/share/kibana/config/kibana.yml in container
# kibana container environment: https://www.elastic.co/guide/en/kibana/current/settings.html
    kibana:
        image: docker.elastic.co/kibana/kibana:7.6.2
        depends_on: 
            - elasticsearch
        ports: 
            - 80:5601
        environment: 
            - ELASTICSEACH_URL=http://elasticsearch:9200
            - I18N_LOCALE=ja-JP
            - ELASTICSEARCH_USERNAME=elastic
            - ELASTICSEARCH_PASSWORD=your-password
        #volumes:
            #- ./mnt/config/kibana:/usr/share/kibana/config

    logstash:
        image: docker.elastic.co/logstash/logstash:7.6.2
        depends_on: 
            - kibana
        environment:
            - xpack.monitoring.enabled=false
        volumes: 
            - ./mnt/logstash-pipeline:/usr/share/logstash/pipeline
```

### elasticsearchの環境変数設定について
今回利用していないものも含め、少し難しいものを意訳したものを以下に記載。

#### vm.max_map_countを最低でも262144に設定する
本番環境で利用する場合は、カーネルの設定vm.max_map_countを最低でも262144にする必要があります。
vm.max_map_countの設定方法はプラットフォームによって異なります。
> [補足]vm.max_map_countはプログラムによるメモリ領域サイズ（プログラムが確保できるメモリサイズ）の最大値を指定するパラメーターです

#### スワッピングの無効化
パフォーマンスとノードの安定性のために、スワッピングを無効にする必要があります。
bootstrap.memory_lock: trueで設定する場合、Dockerデーモンでmemlock: true ulimitを定義するか、サンプルのコンパイルファイルのようにコンテナに明示的に設定する必要があります。
docker runを使用する場合は、以下のように指定します。

```
-e "bootstrap.memory_lock=true" --ulimit memlock=-1:-1
```

#### ヒープサイズを設定する
ヒープサイズを設定するには、/usr/share/elasticsearch/config/jvm.options.dにあるJVMオプションファイルをバインドマウントします。
デフォルトのルートjvm.optionsファイルはデフォルトのヒープを1GBに設定していますが、バインドマウントされたJVMオプションファイルで設定した値は
すべて上書きされることに注意してください。

バインドマウントされたJVMオプションでヒープサイズを設定することが推奨されていますが、
環境変数ES_JAVA_OPTSを使用してヒープサイズを設定することもできます。
例えば、16GBを使用するには、-e ES_JAVA_OPTS="-Xms16g -Xmx16g "とdocker runで指定します。
デフォルトのルート jvm.options ファイルはデフォルトのヒープを 1 GB に設定していますが、
ES_JAVA_OPTS で設定した任意の値はそれを上書きすることに注意してください。

> [補足]Xmsはminimum heap sizeであり、Xmxはmaximum heap sizeを示す
> [参考]https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html

# 動作確認
起動してログを確認し、kibanaの接続待受け開始のログが表示されたらアクセスする。
ユーザー名は「elastic」であり、パスワードはELASTICSEARCH_PASSWORDで指定したものである。

```shell
strike:elastic marseille$ docker-compose up -d
Creating network "elastic_default" with the default driver
Creating elastic_elasticsearch_1 ... done
Creating elastic_kibana_1        ... done
Creating elastic_logstash_1      ... done
strike:elastic marseille$ 
strike:elastic marseille$ docker-compose ps
         Name                        Command               State          Ports        
---------------------------------------------------------------------------------------
elastic_elasticsearch_1   /usr/local/bin/docker-entr ...   Up      9200/tcp, 9300/tcp  
elastic_kibana_1          /usr/local/bin/dumb-init - ...   Up      0.0.0.0:80->5601/tcp
elastic_logstash_1        /usr/local/bin/docker-entr ...   Up      5044/tcp, 9600/tcp  
strike:elastic marseille$ docker-compose logs -f
〜〜略〜〜
# このログはkibanaが接続待受開始を示すログ
kibana_1         | {"type":"log","@timestamp":"2020-06-14T14:04:54Z","tags":["listening","info"],"pid":6,"message":"Server running at http://0:5601"}
kibana_1         | {"type":"log","@timestamp":"2020-06-14T14:04:55Z","tags":["info","http","server","Kibana"],"pid":6,"message":"http server running at http://0:5601"}

# このログはlogstashがelasticsearchにうまく接続できた意味を示すログ（認証がうまく通っている）
logstash_1       | [2020-06-14T14:04:50,416][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}
```

# 初期設定
ダークモードの有効化と、統計情報収集をOFFをにする。

## ダークモードの有効化
management -> kibana -> 高度な設定 -> Dark modeのボタンをクリックして、有効化

## 統計情報収集をOFF
management -> kibana -> 高度な設定 -> 使用データを無効化