Elasticsearch 7.6 と Kibana 7.6 に Security を有効化してDockerで起動する(コピペ)


やりたいこと

ログの集計・可視化をElasticsearchとKibanaを使って行いたいと思い、色々調べてみたところ、どうやらAmazon Lightsailで動かすのが安そうということで、環境構築について検討した。
Elastic Cloudだと手軽に始められる反面、インスタンスコストが割高で、最小構成だとリサイズに失敗したりしてほとんど何もできなかった。
Lightsailの場合、4GB RAMのインスタンスが$20/月なので、2GBをElasticsearchに、1GBをKibanaに、という構成ができそう。
そして、比較的最近、無償ライセンスのBasicプランでもX-Pack Securityが使えるようになっているので、しっかり認証も付けておきたい。(Lightsailはポート制限しかできない)
開発はMacで行うので、できればローカルの開発環境と本番を同じように構成したい。

2020.2.12 更新:公式ドキュメントですんなりいかなかったので、TLSの有効化を追記した。
2020.2.12 更新:ElasticsearchとKibanaの7.6.0が出たのでバージョンアップした
2020.2.13 更新:より簡単で確実なElasticsearch & Kibana をLet's EncryptでTLS対応させる を投稿した。

要点

  • Elasticsearch & Kibana を使う
  • X-Pack Securityを有効化する
  • なるべく安くそこそこの環境を整えたい
  • MacとLightsailで同じ環境を作りたい

前提

  • Dockerが使える状態
  • ホスト側がRAM 4GB以上で、Elasticsearchに2GB、Kibanaに1GBを割当てられる
  • 直近ではSSLオプション使わない ElasticsearchとクライアントをTLS、Kibanaにhttpsで接続するようにする

以下をコピペしとけば動く

1. データの保存先を作成

  • 必要に応じて権限を変える
mkdir -p ~/Development/Docker/Elasticsearch/data ~/Development/Docker/Elasticsearch/cert

2. まず、作業用にデフォルト状態のElasticsearchを起動

  • 環境変数 ELASTIC_PASSWORDelastic ユーザーのパスワードなので変更する
docker run --name Elasticsearch -d \
-m 2048m \
-p 9200:9200 \
-p 9300:9300 \
-e cluster.name=ES \
-e discovery.type=single-node \
-e network.host=0.0.0.0 \
-e bootstrap.memory_lock=true \
-e xpack.security.enabled=true \
-e xpack.monitoring.collection.enabled=true \
-e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" \
-e "ELASTIC_PASSWORD=iY69DxipKifV7utYA4t6jgxT" \
-v ~/Development/Docker/Elasticsearch/data:/usr/share/elasticsearch/data \
-v ~/Development/Docker/Elasticsearch/cert:/usr/share/elasticsearch/cert \
--ulimit nproc=4096:4096 \
--ulimit memlock=256000:256000 \
--ulimit nofile=65536:65536 \
docker.elastic.co/elasticsearch/elasticsearch:7.6.0

3. kibanaユーザーのパスワードを設定する

  • BASIC認証のパスワードは2で指定したものを使う
  • password の値が kibana ユーザーのパスワード
curl -XPUT --user elastic:iY69DxipKifV7utYA4t6jgxT 'localhost:9200/_xpack/security/user/kibana/_password' -H "Content-Type: application/json" -d '{
  "password" : "6ezji8D5jvceXUsTsvg8mAY4"
}'

4. TLS周りの準備

基本的には公式の Encrypting communications in Elasticsearch | Elasticsearch Reference [7.6] | ElasticEncrypting communications in Kibana | Kibana Guide [7.6] | Elastic に沿ってはいる。

Elasticsearchコンテナに入る

docker exec -it Elasticsearch /bin/sh

opensslとunzipを使えるようにする

yum update
yum install openssl unzip

認証局を作成

  • ダイアログは何も入れずenterを押し続ける(お好みで入力してもいい)
bin/elasticsearch-certutil ca

秘密鍵を生成

  • ダイアログは何も入れずenterを押し続ける(お好みで入力してもいい)
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12

証明書を作成

openssl pkcs12 -in elastic-certificates.p12 -cacerts -nokeys -out elastic-stack-ca.pem

Kibanaをhttps化するのに必要なサーバ証明書と秘密鍵を生成

  • ダイアログは何も入れずenterを押し続ける(お好みで入力してもいい)
bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 --pem --name kibana-server
unzip certificate-bundle.zip

諸々をホスト側に移動してコンテナを抜ける

mv elastic-* ./cert/
mv kibana-server ./cert/
exit

5. TLS周りを組み込んだイメージをビルドする

生成しておいた諸々があるディレクトリへ移動


cd ~/Development/Docker/Elasticsearch/cert

Elasticsearchイメージをビルドする

  • 以下の内容で dockerfile-es を作成
FROM docker.elastic.co/elasticsearch/elasticsearch:7.6.0

RUN \
elasticsearch-plugin install --batch analysis-icu && \
elasticsearch-plugin install --batch analysis-kuromoji

RUN mkdir /usr/share/elasticsearch/config/cert
ADD elastic-certificates.p12 /usr/share/elasticsearch/config/cert/elastic-certificates.p12
ADD elastic-stack-ca.p12 /usr/share/elasticsearch/config/cert/elastic-stack-ca.p12
RUN chown -R elasticsearch /usr/share/elasticsearch/config/cert
RUN chgrp -R root /usr/share/elasticsearch/config/cert
RUN chmod o-rx /usr/share/elasticsearch/config/cert
RUN chmod 640 /usr/share/elasticsearch/config/cert/elastic-stack-ca.p12
RUN chmod 640 /usr/share/elasticsearch/config/cert/elastic-certificates.p12
  • ビルドする
docker build -f dockerfile-es -t elasticsearch-tls .

Kibanaイメージをビルドする

  • 以下の内容で dockerfile-kibana を作成
FROM docker.elastic.co/kibana/kibana:7.6.0

ADD elastic-stack-ca.pem /etc/kibana/elastic-stack-ca.pem
ADD kibana-server/kibana-server.crt /etc/kibana/kibana-server.crt
ADD kibana-server/kibana-server.key /etc/kibana/kibana-server.key
  • ビルドする
docker build -f dockerfile-kibana -t kibana-tls .

6. ビルドしたElasticsearchイメージを起動する

  • まずは作業に使ったデフォルトのコンテナを破棄する
docker stop Elasticsearch
docker rm Elasticsearch
  • Elasticsearchを起動する
docker run --name Elasticsearch -d \
-m 2048m \
-p 9200:9200 \
-p 9300:9300 \
-e cluster.name=ES \
-e discovery.type=single-node \
-e network.host=0.0.0.0 \
-e bootstrap.memory_lock=true \
-e xpack.security.enabled=true \
-e xpack.monitoring.collection.enabled=true \
-e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" \
-e "ELASTIC_PASSWORD=iY69DxipKifV7utYA4t6jgxT" \
-e xpack.security.transport.ssl.enabled=true \
-e xpack.security.transport.ssl.verification_mode=certificate \
-e xpack.security.transport.ssl.keystore.path=/usr/share/elasticsearch/config/cert/elastic-stack-ca.p12 \
-e xpack.security.transport.ssl.truststore.path=/usr/share/elasticsearch/config/cert/elastic-certificates.p12 \
-e xpack.security.http.ssl.enabled=true \
-e xpack.security.http.ssl.keystore.path=/usr/share/elasticsearch/config/cert/elastic-certificates.p12 \
-e xpack.security.http.ssl.truststore.path=/usr/share/elasticsearch/config/cert/elastic-certificates.p12 \
-v ~/Development/Docker/Elasticsearch/data:/usr/share/elasticsearch/data \
--ulimit nproc=4096:4096 \
--ulimit memlock=256000:256000 \
--ulimit nofile=65536:65536 \
elasticsearch-tls

7. ビルドしたKibanaイメージを起動する

  • ELASTICSEARCH_PASSWORD3で設定した kibana ユーザーのパスワードを指定する
docker run --name Kibana -d \
--link Elasticsearch:elasticsearch \
-m 1280m \
-p 443:5601 \
-e "ELASTICSEARCH_HOSTS=https://elasticsearch:9200" \
-e "ELASTICSEARCH_USERNAME=kibana" \
-e "ELASTICSEARCH_PASSWORD=L5eDLkx9EzswECECAsabJauV" \
-e "ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=[\"/etc/kibana/elastic-stack-ca.pem\"]" \
-e "ELASTICSEARCH_SSL_VERIFICATIONMODE=certificate" \
-e "SERVER_SSL_ENABLED=true" \
-e "SERVER_SSL_CERTIFICATE=/etc/kibana/kibana-server.crt" \
-e "SERVER_SSL_KEY=/etc/kibana/kibana-server.key" \
--ulimit nproc=4096:4096 \
--ulimit memlock=256000:256000 \
--ulimit nofile=65536:65536 \
kibana-tls

8. 諸々設定する

  • ブラウザでホストの https://{ホスト名}/ に接続(自己証明書だとブラウザに警告される)
  • elastic ユーザーとしてログイン
  • グループやユーザーを作成