elastic-stackをkubernetesクラスタにインストールしてみた

February 09, 2019

クラウドから取得したデータの分析を行うために、elastic searchをkubernetes環境で使ってみることにしました。最初に、クラスタへのインストールのため下記のようにhelm を実行しました。今回は、kibana, logstashも含む、stable/elastic-stackを使用。

helm install --namespace elastic-stack -n elastic-stack stable/elastic-stack

たった1行でインストール、設定(デフォルトですが)終了です。楽ですね。しかし、一部のワーカーノードでpod(elasticsearach-client)の起動に失敗しており、ログを見ても原因がわかりませんでした。そのうち、ワーカーノードでのメモリ不足が原因であることに気づき(コンソールにエラーが出ていた)、ワーカーノードのメモリを増やしたり、ワーカーノード自体を増やすと全てのpodの起動に成功しました。ちなみにワーカーノードの数はこの時4つで、2つは8Gのメモリ、他の2つは2Gのメモリを搭載しています。ほとんどのpodは8G搭載したノードで実行されてましたので、2Gはやはり厳しいようです。

とりあえずインストール、デプロイは完了したので、kibanaにアクセスできるかを確認するため、helm実行時で出てきた下記のコマンドをローカルPC(クラスタ外にある)で実行し、ブラウザからアクセスしてみました。※kubectlのインストール方法はこちら

export POD_NAME=$(kubectl get pods --namespace elastic-stack -l "app=kibana,release=elastic-stack" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:5601 to use Kibana"
kubectl port-forward --namespace elastic-stack $POD_NAME 5601:5601

kibanaのページは表示されたのですが、elasticsearchに接続できない、というエラーが出てました。どうやらkibanaには環境変数(ELASTICSEARCH_URL)を正しく設定する必要があるようです。色々調べたり試行錯誤して、下記のコマンドで設定を変更することで、この問題が解決できました。kibana,elasticsearchは同一の名前空間ですので、URLにはelasticsearchのサービス名を指定しています。

helm upgrade --set kibana.env.ELASTICSEARCH_URL=“http://elastic-stack-elasticsearch-client:9200" elastic-stack stable/elastic-stack

これでようやくブラウザから、kibanaにアクセスし、dev toolからelasticsearchにデータを投入できるようになりました。

kibana,elasticsearchが動作するようになったので、次はlogstashの設定です。設定するのは、elasticsearchのアクセス先とlogstashのinput pluginに関する情報です。今回は列車が遅延している路線をjsonで返却してくれるサービスを利用させてもらいました。このサービスから、http_pollerプラグインで定期的に情報を取得するように設定しました。設定はhelmコマンドのオプションの–setでも可能ですが、長いので全ての設定内容をファイル(myvalues.yaml)に保存し、-fオプションで取り込むようにしました。設定内容は下記の通りです。

logstash:
  elasticsearch:
    host: elastic-stack-elasticsearch-client
  inputs:
    main: |-
      input {
        http_poller {
          urls => {
            train_delay => "https://rti-giken.jp/fhc/api/train_tetsudo/delay.json"
          }
          request_timeout => 60
          schedule => { every => "10m"}
          codec => "json"
          add_field => { "[@metadata][beat]" => "train_info" }
          add_field => { "[@metadata][type]" => "delay" } 
        }
      }
kibana:
  env:
    ELASTICSEARCH_URL: http://elastic-stack-elasticsearch-client:9200

このファイルを使って、

helm upgrade -f myvalues.yaml elastic-stack stable/elastic-stack

を実行すると、設定がアップデートされます。kibanaで確認したところ、ちゃんとデータが入っていました。

追記(2019/3/23)

理由はよくわかりませんが、以前からlogstashのpodが不安定だったのですが、最近は起動後、1分程度でクラッシュするようになってしまいました。原因を調べるため、下記のように、myvalues.yamlを変更し、デバッグ出力を有効にして見ました。

logstash:
  config:
    debug: true
    log.level: debug

これでデバッグログが見れるようになりましたが、結局原因と思われるような情報はログに出力されずに突然落ちてしまうので、お手上げ状態になってしまいました。現象としては、「[WARN ][logstash.runner ] SIGTERM received. Shutting down.」というメッセージがログに出て、runnerが突然落ちる、というものです。

jvmのヒープが足りないのかも、と思って変更方法を探しましたが、values.yamlからの変更方法がわからない(通常のdockerコンテナでは、環境変数LS_JAVA_OPTSに「-Xmx3g」のように設定すれば良いらしい(参考サイト)。ちなみにjvmの設定ファイルはlogstashのコンテナ内の/usr/share/logstash/config/jvm.optionsにあり、ヒープの設定としては「-Xms1g」、「-Xmx1g」になっている)ので、結局logstashを使用し続けるのは断念し、fluentdに乗り換えることにしました。

fluentdを導入する場合は、elastic-stackのチャートのvalues.yamlで下記のように設定するだけでインストールできました。logstashを無効化するとともに、fuluentdを有効にして、elasticsearchのホストを設定しています。ちなみに、fluentd-elasticsearchというchartもあったのですが、これはkubernetesのクラスタ内で稼働しているdockerコンテナのログを収集するためのもののようです。

logstash:
  enabled: false

fluentd:
  enabled: true
  output:
    host: 'elastic-stack-elasticsearch-client'

これで再度デプロイしてみたところ、無事fluentdが起動しました。試しにfluentdのpodにログインして下記のようなテストコマンドを実行したところ、kibanaでelasticsearchに送られていることが確認できました。

echo '{"json":"message"}' | fluent-cat debug.test