ElasticsearchをDockerコンテナで動かす方法


ElasticsearchをDockerコンテナで動かす方法:詳細解説

はじめに

Elasticsearchは、分散型のRESTful検索・分析エンジンであり、ログ分析、全文検索、アプリケーションモニタリングなど、幅広いユースケースで利用されています。その強力な機能とスケーラビリティから、多くの開発者や運用エンジニアにとって不可欠なツールとなっています。

Elasticsearchをローカル環境やサーバーに直接インストールして設定するのは、依存関係の管理や環境の汚染など、いくつか課題を伴う場合があります。そこで、コンテナ技術であるDockerを利用することで、これらの課題を克服し、より簡単かつ効率的にElasticsearch環境を構築・管理することが可能になります。

本記事では、ElasticsearchをDockerコンテナで動かすための詳細な手順と設定について解説します。単一ノードの基本的なセットアップから、Docker Composeを使った複数サービスの連携(Kibanaを含む)、重要な設定項目、データ永続化、トラブルシューティング、そして本番環境での考慮事項まで、幅広くカバーします。この記事を読むことで、読者はElasticsearchをDockerで自信を持って使い始めることができるでしょう。

Elasticsearchとは?

Elasticsearchは、Apache Luceneをベースにしたオープンソースの分散型検索・分析エンジンです。データの収集、インデックス作成、検索、分析をリアルタイムで行うことができます。特徴としては、RESTful APIによる操作、高いスケーラビリティ、分散型アーキテクチャによる可用性の高さ、そして豊富な機能(アグリゲーション、地理空間検索など)が挙げられます。

Dockerとは?

Dockerは、アプリケーションとその依存関係をコンテナと呼ばれる独立した環境にパッケージ化するためのプラットフォームです。コンテナは軽量かつポータブルであり、どの環境でも一貫した動作を保証します。これにより、「開発環境では動いたのに本番環境では動かない」といった問題を減らすことができます。

なぜElasticsearchをDockerで動かすのか?

ElasticsearchをDockerで動かすことには、以下のような多くのメリットがあります。

  • セットアップの簡略化: インストール手順が不要で、イメージをダウンロードして起動するだけです。依存ライブラリの衝突などを気にする必要がありません。
  • 環境の分離と汚染回避: ホストOSを汚染することなく、Elasticsearchとその依存関係をコンテナ内に閉じ込めることができます。
  • 移植性と一貫性: 同じDockerイメージを使えば、開発環境、ステージング環境、本番環境など、どの環境でも同じElasticsearchインスタンスを再現できます。
  • 複数バージョンの容易な管理: 異なるバージョンのElasticsearchを同時に、または切り替えながら簡単に起動できます。
  • 依存サービスの連携: Docker Composeを使うことで、Elasticsearchだけでなく、KibanaやLogstashといった関連サービスもまとめて定義し、連携させることが容易になります。
  • リソース管理: Dockerのリソース制限機能を使って、コンテナが使用するCPUやメモリを制御できます。

前提条件

本記事の手順を実行するためには、以下の準備が必要です。

  1. Dockerのインストール: ホストOS(Windows, macOS, Linux)にDocker Engineがインストールされ、実行できる状態であること。Docker Desktopを使うのが最も簡単です。
  2. Docker Composeのインストール: Docker Compose(またはDocker Desktopに同梱されている場合)がインストールされていること。これは複数コンテナを管理する際に非常に役立ちます。
  3. ターミナル/コマンドプロンプトの操作: 基本的なコマンドライン操作ができること。
  4. (オプション)Elasticsearchの基本的な知識: インデックス、ドキュメント、APIなどの基本的な概念を知っていると、より理解が深まります。

DockerとDocker Composeのインストール方法については、公式ドキュメントを参照してください。

基本的な起動方法:docker run

まずは、最もシンプルな方法として、docker runコマンドを使って単一のElasticsearchコンテナを起動してみましょう。この方法は、Elasticsearchを一時的に試したい場合や、開発環境で最小限のセットアップを行いたい場合に適しています。

Elasticsearch Dockerイメージの取得

まず、Docker HubからElasticsearchのイメージを取得します。特定のバージョンを指定することをお勧めします。ここでは例として、執筆時点での比較的新しいバージョンである8.x系の最新版を利用します。

bash
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.x

8.xの部分は、利用したい具体的なバージョン(例: 8.12.2)に置き換えても構いません。docker.elastic.coはElastic社が公式に提供するイメージのリポジトリです。

単一コンテナでの起動

イメージを取得したら、docker runコマンドでコンテナを起動します。ElasticsearchをDockerコンテナで動かす際には、いくつか重要な設定が必要です。

必須設定と考慮事項:

  1. メモリ制限: ElasticsearchはJavaで動作し、JVMヒープメモリを大量に使用します。Dockerコンテナで起動する場合、ホストOSのJVM設定やリソースと直接連携しないため、コンテナに割り当てるメモリやJVMヒープサイズを適切に設定する必要があります。特に開発以外の用途では、最低でも2GBのメモリをElasticsearchに割り当てるのが推奨されています。Dockerイメージはデフォルトでヒープサイズを自動調整しますが、明示的に設定することも可能です。
  2. ネットワーク設定: Elasticsearchはデフォルトでポート9200(HTTP)と9300(Transport)を使用します。これらのポートをホストOSに公開する必要があります。
  3. 開発モード vs 本番モード: Elasticsearchは起動時にいくつかのシステム設定(vm.max_map_countなど)をチェックします。これらのチェックは本番環境での安定稼働のために重要ですが、開発環境では緩やかになる「開発モード」で起動することも多いです。Dockerイメージは、デフォルトで開発モードで起動するように設定されていることが多いですが、特定の環境変数で制御できます。
  4. データの永続化: コンテナは一時的なものです。Elasticsearchのデータ(インデックスなど)をコンテナ停止・削除後も保持するためには、ホストOSのディレクトリやDockerボリュームにマッピングする必要があります。

これらを踏まえて、基本的なdocker runコマンドは以下のようになります。

bash
docker run -d \
--name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-v elasticsearch_data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.x

上記のコマンドについて詳しく見ていきましょう。

  • -d: コンテナをデタッチドモード(バックグラウンド)で実行します。
  • --name elasticsearch: コンテナに elasticsearch という名前を付けます。これにより、コンテナIDの代わりに名前で操作できます。
  • -p 9200:9200: ホストOSのポート9200を、コンテナのポート9200にマッピングします。ElasticsearchのHTTP APIはこのポートで公開されます。
  • -p 9300:9300: ホストOSのポート9300を、コンテナのポート9300にマッピングします。ElasticsearchのTransport層はデフォルトでこのポートを使用し、ノード間通信に使われます(単一ノード構成では必須ではありませんが、慣例的に公開します)。
  • -e "discovery.type=single-node": 環境変数を設定します。discovery.type=single-node は、Elasticsearchを単一ノードのクラスタとして起動するための必須設定です。これを指定しないと、起動時にクラスタを形成しようとして待機することがあります。
  • -e "ES_JAVA_OPTS=-Xms512m -Xmx512m": JVMの起動オプションを設定する環境変数です。-Xmsは初期ヒープサイズ、-Xmxは最大ヒープサイズを指定します。ここでは例として512MBを設定していますが、実際には利用可能なメモリに応じて適切に設定してください。開発用途であれば1GB〜2GB、本番用途であればさらに多くのメモリが必要になることが一般的です。ホストOSの総メモリの半分以下に設定することが推奨されています。
  • -v elasticsearch_data:/usr/share/elasticsearch/data: ボリュームをマッピングします。elasticsearch_dataはDocker管理のボリューム名、/usr/share/elasticsearch/dataはコンテナ内のElasticsearchデータディレクトリのパスです。これにより、Elasticsearchのインデックスデータなどが永続化され、コンテナを削除してもデータが失われません。Docker管理のボリュームは、ホストOS上の特定の場所にDockerデーモンによって管理されます。代わりに、./data:/usr/share/elasticsearch/data のようにホストOS上の特定のディレクトリ(例: 現在のディレクトリ下のdataフォルダ)にマッピングする(バインドマウント)ことも可能ですが、Docker管理ボリュームの方が権限管理などの面で推奨されることが多いです。
  • docker.elastic.co/elasticsearch/elasticsearch:8.x: 使用するDockerイメージとそのバージョンを指定します。

起動確認

コンテナがバックグラウンドで起動したら、以下のコマンドで状態を確認できます。

bash
docker ps

STATUSUp ...となっていれば起動成功です。もし起動に失敗している場合は、docker logs elasticsearchコマンドでログを確認して原因を特定してください。

ElasticsearchのHTTP APIにアクセスして動作を確認することもできます。

bash
curl http://localhost:9200

Elasticsearch 8.x 以降のセキュリティ:

Elasticsearch 8.x 以降では、デフォルトでセキュリティ機能(Basic Authentication, TLS)が有効になります。docker runで起動した場合、初回起動時にランダムなパスワードとEnrollment Tokenが表示されます。上記のcurlコマンドでは、認証が必要なためエラーになるか、認証を促されるはずです。

簡易的な開発環境では、セキュリティを無効にするために以下の環境変数を追加することがあります(本番環境では推奨されません)。

bash
docker run -d \
--name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e "xpack.security.enabled=false" \ # セキュリティを無効化 (開発用)
-e "xpack.security.enrollment.enabled=false" \ # Enrollment Token を無効化
-v elasticsearch_data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.x

注意: xpack.security.enabled=false開発目的でのみ使用してください。本番環境では必ずセキュリティを有効にし、適切に設定する必要があります。

セキュリティを無効にした場合、curl http://localhost:9200 でElasticsearchのバージョン情報などが含まれるJSONレスポンスが得られるはずです。

セキュリティを有効にしたままアクセスする場合は、ユーザー名とパスワードを指定する必要があります。初回起動時に表示されるパスワードを確認し、curl -u elastic:<password> https://localhost:9200 --cacert <path_to_certs>/http_ca.crt のように実行します(自己署名証明書の場合)。Dockerコンテナの場合、証明書のパスはホストOSからの相対パスではなく、コンテナ内のパスを指定するか、ボリュームマウントする必要があります。

コンテナの停止と削除

起動したコンテナを停止するには:

bash
docker stop elasticsearch

停止したコンテナを削除するには:

bash
docker rm elasticsearch

-vオプションを付けて削除すると、コンテナに関連付けられたボリュームも削除されます(永続化データも失われます)。

bash
docker rm -v elasticsearch

ボリューム自体を明示的に削除するには:

bash
docker volume rm elasticsearch_data

より実用的な起動方法:Docker Compose

単一のコンテナを管理するだけならdocker runで十分ですが、ElasticsearchとKibanaを連携させたり、複数のElasticsearchノードでクラスタを組んだりする場合、docker runコマンドが複雑になり管理が難しくなります。ここでDocker Composeの出番です。

Docker Composeを使うと、複数のコンテナ(サービス)とその依存関係、ネットワーク、ボリュームなどをYAMLファイル(docker-compose.yml)に定義できます。このファイル一つで、サービス群をまとめて起動・停止・管理できるようになります。

なぜDocker Composeを使うのか?

  • 設定のコード化: コンテナの設定がdocker-compose.ymlというファイルに記述されるため、バージョン管理システムで管理しやすくなります。
  • 複数サービスの連携: Elasticsearch、Kibana、Logstashなどを一つの定義ファイルでまとめて扱えます。
  • ネットワークの自動設定: Docker Composeはデフォルトでカスタムネットワークを作成し、そのネットワーク内のコンテナはサービス名で互いに通信できます。
  • 可読性と再利用性: 複雑なdocker runコマンドよりも、YAMLファイルの方が設定内容を理解しやすく、再利用も容易です。

docker-compose.yml ファイルの作成

まず、docker-compose.ymlという名前のファイルを作成します。このファイルに、ElasticsearchサービスとKibanaサービスを定義してみましょう。

“`yaml

docker-compose.yml

version: ‘3.8’

services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.x
container_name: elasticsearch
ports:
– “9200:9200”
– “9300:9300″
environment:
– discovery.type=single-node
– ES_JAVA_OPTS=”-Xms1g -Xmx1g” # 1GBに設定例 (必要に応じて調整)
# Elasticsearch 8.x 以降でセキュリティを無効にする場合 (開発用)
– xpack.security.enabled=false
– xpack.security.enrollment.enabled=false
# Elasticsearch 8.x 以降でセキュリティを有効にする場合 (推奨)
# 初回起動時にパスワードが生成される
# – ELASTIC_PASSWORD=changeme # パスワードを明示的に設定する場合 (非推奨, Docker Secrets等を使うべき)
volumes:
– elasticsearch_data:/usr/share/elasticsearch/data
# 本番環境向けの重要な設定: vm.max_map_count をホスト側で設定する必要がある
# sysctls:
# vm.max_map_count: 262144 # ホストOSの設定が必要なためコメントアウト
ulimits:
memlock:
soft: -1
hard: -1
# restart: always # 開発以外では設定推奨

kibana:
image: docker.elastic.co/kibana/kibana:8.x
container_name: kibana
ports:
– “5601:5601”
environment:
# Elasticsearch への接続設定
# Elasticsearch 8.x 以降でセキュリティ無効の場合
– ELASTICSEARCH_HOSTS=http://elasticsearch:9200 # サービス名とポート
# Elasticsearch 8.x 以降でセキュリティ有効の場合
# – ELASTICSEARCH_HOSTS=https://elasticsearch:9200 # HTTPS
# – ELASTICSEARCH_USERNAME=elastic
# – ELASTICSEARCH_PASSWORD=changeme # Docker Secrets等を使うべき
# – ELASTICSEARCH_SSL_VERIFICATION_MODE=none # 開発用 (本番では証明書検証必須)
depends_on:
– elasticsearch # elasticsearch サービスの起動を待つ
# restart: always # 開発以外では設定推奨

volumes:
elasticsearch_data: # Docker 管理ボリュームを定義
driver: local
“`

各設定項目の説明:

  • version: '3.8': Docker Compose ファイルのバージョンを指定します。
  • services:: 定義するサービス(コンテナ)をリストします。
  • elasticsearch:: elasticsearchという名前のサービスを定義します。サービス名はDocker Composeネットワーク内でホスト名として利用できます。
    • image: docker.elastic.co/elasticsearch/elasticsearch:8.x: 使用するDockerイメージを指定します。Kibanaも同じメジャーバージョン(例: 8.x)を使用することが推奨されます。
    • container_name: elasticsearch: コンテナに付ける名前です。指定しない場合はDocker Composeが自動的に生成します。
    • ports:: ポートマッピングです。ホストポート:コンテナポートの形式で指定します。
    • environment:: コンテナ内の環境変数を設定します。
      • discovery.type=single-node: 単一ノードで起動するための設定です。
      • ES_JAVA_OPTS="-Xms1g -Xmx1g": JVMヒープサイズを1GBに設定します。コンテナに割り当てるメモリに合わせて適切に調整してください。ホストの総メモリの50%を超えないように注意が必要です。
      • xpack.security.enabled=false, xpack.security.enrollment.enabled=false: Elasticsearch 8.x以降でデフォルト有効になったセキュリティ機能を無効化します(開発用)。本番環境では有効にする設定を記述するか、デフォルトの有効な状態で進めてください。セキュリティ有効時のKibana接続設定はコメントアウトしてあります。
    • volumes:: ボリュームマッピングです。ボリューム名:コンテナ内のパスの形式で指定します。elasticsearch_dataという名前付きボリュームをコンテナ内のデータディレクトリにマッピングし、データを永続化します。
    • sysctls:: コンテナに対してSysctlパラメータを設定します。vm.max_map_countはElasticsearchのメモリマッピングに関わる重要な設定ですが、多くの環境ではホストOS側で設定する必要があります。Docker Composeのsysctlsは、ホストOSの設定が許可されている場合にのみ機能します。推奨されるvm.max_map_countの値は262144以上です。ホスト側での設定方法は後述します。
    • ulimits:: コンテナのリソース制限を設定します。memlock-1は、メモリのスワップアウトを無効にします。Elasticsearchはスワップアウトを嫌うため、これも本番環境で推奨される設定です。これもホストOS側の設定(memlock ulimit)に依存することがあります。
  • kibana:: kibanaという名前のサービスを定義します。
    • image: docker.elastic.co/kibana/kibana:8.x: 使用するKibanaのDockerイメージを指定します。Elasticsearchと同じバージョンを使うのが最も互換性が高いです。
    • container_name: kibana: コンテナ名です。
    • ports:: ポートマッピングです。Kibanaのデフォルトポートは5601です。
    • environment:: 環境変数を設定します。
      • ELASTICSEARCH_HOSTS=http://elasticsearch:9200: Kibanaが接続するElasticsearchのエンドポイントを指定します。Docker Composeのデフォルトネットワーク内では、Elasticsearchコンテナはサービス名であるelasticsearchというホスト名でアクセスできます。セキュリティが無効な場合はHTTP、有効な場合はHTTPSでアクセスします。
      • セキュリティ有効時の認証情報やSSL設定はコメントアウトしてあります。本番環境ではこれらの設定が必要です。
    • depends_on: - elasticsearch: KibanaサービスはElasticsearchサービスが起動するまで待機するように設定します。
  • volumes:: Docker管理のボリュームを定義します。ここで定義したelasticsearch_dataが、上記サービス定義のvolumesセクションで参照されています。

Docker Composeを使った起動

docker-compose.yml ファイルを作成したディレクトリで、以下のコマンドを実行します。

bash
docker compose up # または docker-compose up (古いバージョン)

このコマンドは、docker-compose.yml ファイルを読み込み、定義されているサービス(elasticsearchkibana)のコンテナを作成・起動します。初回実行時は、指定されたイメージがローカルに存在しない場合、Docker Hubからダウンロードされます。

デフォルトではフォアグラウンドで実行され、コンテナのログがターミナルに表示されます。バックグラウンドで実行するには、-dオプションを付けます。

bash
docker compose up -d

起動確認

docker compose up -d で起動した場合、以下のコマンドでコンテナの状態を確認できます。

bash
docker compose ps

StateUpとなっていれば起動成功です。

Kibanaは通常、Elasticsearchが完全に起動してHealthyになるまで接続を試みます。Kibanaのログ (docker compose logs kibana) を確認して、Elasticsearchへの接続が成功しているか確認してください。

Kibanaが起動したら、ブラウザで http://localhost:5601 にアクセスしてください。KibanaのUIが表示されるはずです。Elasticsearch 8.xでセキュリティを有効にしている場合は、ログイン画面が表示され、Elasticsearchのelasticユーザーとパスワードでログインする必要があります。

停止と削除

起動したサービス群を停止するには、docker-compose.yml ファイルがあるディレクトリで以下のコマンドを実行します。

bash
docker compose down # または docker-compose down

このコマンドは、定義されているサービスに関連するコンテナ、ネットワークを停止・削除します。デフォルトではボリュームは削除されません。ボリュームも削除したい場合は、-vオプションを付けます。

bash
docker compose down -v

注意: -vを付けてdownを実行すると、Elasticsearchのデータを含むelasticsearch_dataボリュームも削除されるため、データがすべて失われます

Elasticsearchの重要な設定 (Docker環境での適用)

DockerコンテナでElasticsearchを運用する際には、特に以下の設定が重要になります。これらはdocker-compose.ymlenvironmentセクションや、設定ファイル(elasticsearch.yml)をボリュームマウントして適用することが多いです。

メモリ設定 (ES_JAVA_OPTS)

ElasticsearchはJVM上で動作するため、ヒープサイズの設定はパフォーマンスと安定性に不可欠です。ES_JAVA_OPTS環境変数を使ってJVMオプションを設定します。

yaml
environment:
- ES_JAVA_OPTS="-Xms<size> -Xmx<size>"

  • <size>には、512m (512MB), 2g (2GB) のようにサイズを指定します。
  • -Xms-Xmx同じ値に設定することが推奨されます。これにより、実行中にヒープサイズを変更するオーバーヘッドがなくなります。
  • 割り当てるヒープサイズは、ホストOSの物理メモリの総量の50%以下に設定する必要があります。残りのメモリはOSやElasticsearchのファイルシステムキャッシュのために必要です。
  • コンテナに割り当てるメモリ量(Dockerのmem_limitオプション)と、ES_JAVA_OPTSで設定するヒープサイズは密接に関連します。通常、ヒープサイズ + OSキャッシュ + その他プロセスで使用するメモリの合計が、コンテナに割り当てられたメモリ制限を超えるべきではありません。

Elasticsearch 8.x以降では、コンテナ環境でのメモリ設定を容易にするために-XX:+UseContainerSupport JVMオプションがデフォルトで有効になっています。これは、コンテナに設定されたメモリ制限をJVMが認識し、ヒープサイズなどを自動調整するのに役立ちます。しかし、多くの場合は明示的に-Xms-Xmxを設定することが推奨されます。

ネットワーク設定 (network.host, network.publish_host)

Elasticsearchは通常、network.host設定でバインドするIPアドレスやホスト名を指定します。Dockerコンテナ内では、この設定を適切に行うことが重要です。

  • 開発モード (discovery.type=single-node): このモードでは、network.hostを明示的に設定しなくても、Elasticsearchは開発モードのデフォルト設定(例: _local_, _site_)を使用し、ローカルホストやプライベートIPアドレスにバインドされます。Docker Composeのデフォルトネットワーク内では、これで他のコンテナ(Kibanaなど)からのアクセスが可能です。
  • 本番環境 (複数ノードクラスタ): 複数ノードでクラスタを組む場合、各ノードが互いを検出できるように、公開可能なIPアドレスやホスト名を指定する必要があります。
    • network.host: 0.0.0.0: 全てのネットワークインターフェースにバインドします。
    • network.publish_host: <ホストOSのIPアドレス>: 他のノードに通知する自身のIPアドレスを指定します。Docker環境では、このIPアドレスはコンテナがホストOSのネットワークにどのように接続されているかによって異なります。Bridgeネットワークの場合、通常はコンテナ自身のIPアドレスになりますが、外部からアクセス可能なホストOSのIPアドレスを指定したい場合は、network.publish_hostを設定する必要がある場合があります。
    • Docker Composeのカスタムネットワークでは、コンテナはサービス名で互いに通信できるため、通常はnetwork.hostを特に設定しなくても、discovery.seed_hostsで他のノードのサービス名を指定すればクラスタが形成されます。

例 (docker-compose.yml):

yaml
environment:
- network.host=0.0.0.0 # 全てのインターフェースにバインド
# discovery.seed_hosts: クラスタノードのサービス名またはIPアドレスをリスト
# - discovery.seed_hosts=es01,es02,es03 # 複数ノードの場合

ディスカバリ設定 (discovery.type, discovery.seed_hosts)

Elasticsearchクラスタのノードは、ディスカバリメカニズムを使って互いを認識し、クラスタを形成します。

  • discovery.type=single-node: 前述の通り、単一ノード構成で起動するための設定です。これにより、ノードは自身以外のノードを探さず、単独でマスターノードとして振る舞います。
  • discovery.seed_hosts: 複数ノードでクラスタを組む場合、初期のディスカバリに使用する他のノードのリストを指定します。Elasticsearch 8.x以降では、この設定が推奨されるクラスタリング方法です。Docker Composeのネットワークでは、他のコンテナのサービス名を使って指定できます。
  • cluster.initial_master_nodes: 新しいクラスタを初期化する際に、最初のマスターノードとなるノードのリストを指定します。通常、discovery.seed_hostsで指定したノードの一部をここにも指定します。

例 (複数ノードクラスタ, docker-compose.yml):

“`yaml

一部の設定を抜粋

services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:8.x
container_name: es01
environment:
– cluster.name=my-elasticsearch-cluster # クラスタ名
– node.name=es01 # ノード名
– discovery.seed_hosts=es00,es01,es02 # クラスタ内の他のノードのサービス名
– cluster.initial_master_nodes=es01,es02 # 初回マスターノード候補リスト
– ES_JAVA_OPTS=”-Xms1g -Xmx1g”
# … 他の設定 (ports, volumes, sysctls, ulimitsなど)

es02:
image: docker.elastic.co/elasticsearch/elasticsearch:8.x
container_name: es02
environment:
– cluster.name=my-elasticsearch-cluster
– node.name=es02
– discovery.seed_hosts=es00,es01,es02
– cluster.initial_master_nodes=es01,es02
– ES_JAVA_OPTS=”-Xms1g -Xmx1g”
# … 他の設定

es00: # マスター専用ノード、またはデータ/マスターノード
image: docker.elastic.co/elasticsearch/elasticsearch:8.x
container_name: es00
environment:
– cluster.name=my-elasticsearch-cluster
– node.name=es00
– node.roles=master # このノードをマスター専用にする場合
– discovery.seed_hosts=es00,es01,es02
– cluster.initial_master_nodes=es01,es02 # es00 も含めるか検討
– ES_JAVA_OPTS=”-Xms1g -Xmx1g”
# … 他の設定

Kibanaも必要に応じて追加

kibana:
# … 設定
environment:
– ELASTICSEARCH_HOSTS=http://es01:9200,http://es02:9200,http://es00:9200 # クラスタ内のノードを指定
depends_on:
– es00
– es01
– es02
“`

実際の複数ノードクラスタ構成では、マスターノード、データノードなどの役割分担(node.roles)や、アベイラビリティゾーンを考慮した設定などがさらに必要になります。

パス設定 (path.data, path.logs)

Elasticsearchのデータとログはデフォルトで特定のディレクトリに保存されます。これらのディレクトリをボリュームマウントすることで、コンテナのライフサイクルから独立してデータを保持できます。

  • path.data: インデックスデータ、クラスタ状態、設定などが保存される重要なディレクトリです。必ずボリュームマウントする必要があります。 Dockerイメージのデフォルトパスは /usr/share/elasticsearch/data です。
  • path.logs: ログファイルが保存されるディレクトリです。ログを収集・分析するために、これもボリュームマウントすることが推奨されます。Dockerイメージのデフォルトパスは /usr/share/elasticsearch/logs です。

例 (docker-compose.yml):

“`yaml
volumes:
– elasticsearch_data:/usr/share/elasticsearch/data
– elasticsearch_logs:/usr/share/elasticsearch/logs # ログ用のボリュームも追加

volumes:
elasticsearch_data:
elasticsearch_logs:
“`

セキュリティ設定 (X-Pack Security)

Elasticsearch 8.x以降では、X-Pack Securityが無償で提供され、デフォルトで有効になっています。これにより、TLS暗号化、Basic認証、ロールベースのアクセス制御などが利用できます。

Dockerコンテナでセキュリティを有効にする場合、以下の点に注意が必要です。

  • 初回起動: セキュリティが有効な状態でコンテナを初回起動すると、自動的にTLS証明書が生成され、elasticユーザーなどの組み込みユーザーのパスワードが生成されます。これらの情報はコンテナのログに出力されます。このログからパスワードなどを控えておく必要があります。
  • パスワード: デフォルトで生成されたパスワードを使うか、ELASTIC_PASSWORD環境変数で初回起動時にパスワードを設定できます(ELASTIC_PASSWORDは初回起動時のみ有効)。本番環境では、環境変数でのパスワード指定は非推奨です。 Docker SecretsやKubernetes Secretsなど、より安全な方法で管理すべきです。
  • TLS証明書: 生成された証明書はコンテナ内の /usr/share/elasticsearch/config/certs ディレクトリに保存されます。Kibanaなど他のサービスからHTTPSで接続する場合、これらの証明書(特にCA証明書)を共有する必要があります。これを実現するためには、証明書ディレクトリをホストのディレクトリにバインドマウントするか、共有ボリュームを使用する方法があります。
  • Kibanaからの接続: KibanaはHTTPSでElasticsearchに接続する必要があります。また、認証情報(ユーザー名とパスワード)も必要です。これらの設定はKibanaの環境変数(ELASTICSEARCH_HOSTS, ELASTICSEARCH_USERNAME, ELASTICSEARCH_PASSWORD)で行います。自己署名証明書を使用する場合、Kibana側で証明書の検証を無効にする設定(ELASTICSEARCH_SSL_VERIFICATION_MODE=none)を一時的に行うこともできますが、本番環境では必ず正規の証明書を使用し、検証を有効にしてください。

例 (セキュリティ有効, docker-compose.yml – 一部抜粋):

“`yaml
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.x
# environment: (セキュリティ無効の設定は削除またはコメントアウト)
# ELASTIC_PASSWORD: 初回起動時にパスワードを設定する場合 (非推奨)
# – ELASTIC_PASSWORD=mysecretpassword
volumes:
– elasticsearch_data:/usr/share/elasticsearch/data
# 証明書ディレクトリをホストにマウントして共有する場合
# – ./certs:/usr/share/elasticsearch/config/certs

kibana:
image: docker.elastic.co/kibana/kibana:8.x
# environment:
# Elasticsearch への接続設定 (HTTPS)
– ELASTICSEARCH_HOSTS=https://elasticsearch:9200
# 認証情報 (安全な方法で渡すこと)
# – ELASTICSEARCH_USERNAME=elastic
# – ELASTICSEARCH_PASSWORD=generated_password_from_logs # 初回起動ログを確認
# 自己署名証明書の場合 (開発用, 本番NG)
# – ELASTICSEARCH_SSL_VERIFICATION_MODE=none
# CA証明書を Kibana コンテナにマウントする場合
# – ELASTICSEARCH_SSL_CERTIFICATE_AUTHORITIES=/usr/share/kibana/config/certs/http_ca.crt
volumes:
# Elasticsearch から証明書を共有する場合
# – ./certs:/usr/share/kibana/config/certs
depends_on:
– elasticsearch
“`

セキュリティ有効時の設定は複雑になるため、Elasticsearch公式ドキュメントのDockerに関するセキュリティセクションを必ず参照してください。

vm.max_map_countulimits

Elasticsearchは多くのファイルディスクリプタやメモリマップ領域を使用するため、ホストOSで特定のカーネルパラメータを設定する必要があります。

  • vm.max_map_count: メモリマップ領域の最大数を指定します。Elasticsearchでは最低でも262144が必要です。これは通常、DockerホストOS側で設定する必要があります。

    • Linuxの場合、以下のコマンドで一時的に設定できます(再起動で元に戻ります):
      bash
      sudo sysctl -w vm.max_map_count=262144
    • 永続的に設定するには、/etc/sysctl.d/99-elasticsearch.conf のようなファイルを作成し、vm.max_map_count=262144 を記述して、sudo sysctl -p またはシステム再起動で適用します。
    • Docker Desktop (Windows/macOS) の場合は、内部のVM設定で自動的に設定されていることが多いですが、確認が必要です。
    • docker-compose.ymlsysctls を使う方法もありますが、これはDockerデーモンの権限やOSの設定に依存するため、ホスト側で設定するのが最も確実です。
  • ulimits: ファイルディスクリプタの上限やメモリロック(memlock)の上限などを設定します。

    • ファイルディスクリプタの上限はデフォルトで十分なことが多いですが、大量のインデックスやシャードを扱う場合は増やす必要があるかもしれません。
    • memlock を無制限 (-1) に設定することで、ElasticsearchのJVMヒープがスワップアウトされるのを防ぎます。これも本番環境では重要です。Docker Composeではulimitsセクションで設定できます。

例 (docker-compose.yml):

yaml
ulimits:
memlock:
soft: -1
hard: -1
# nofile: # ファイルディスクリプタの上限 (必要に応じて)
# soft: 65536
# hard: 65536

これらの設定(特にvm.max_map_countmemlock)が不足していると、Elasticsearchコンテナが起動時にエラーを出すか、不安定になる可能性があります。ログを確認して、これらの設定に関する警告やエラーがないか確認してください。

ボリュームとデータの永続化

Elasticsearchのデータディレクトリ(path.data)には、インデックスデータ、トランザクションログ、クラスタの状態などが含まれます。コンテナは一時的なものであるため、このデータを永続化しないと、コンテナを削除したり再作成したりするたびにデータが失われてしまいます。

Dockerでは、データ永続化のために主に以下の2つの方法があります。

  1. Docker管理ボリューム (Named Volumes): DockerデーモンがホストOS上の特定の場所にデータを管理します。ボリュームの作成、管理、削除はDockerコマンドで行います。推奨される方法です。
  2. バインドマウント (Bind Mounts): ホストOS上の任意のディレクトリを、コンテナ内のディレクトリにマッピングします。ホスト側のファイルシステムを直接操作できます。設定ファイルやログディレクトリのマウントに適しています。

Docker管理ボリューム (docker run および docker-compose.yml)

docker runでの例:

bash
docker run -d \
# ... その他のオプション ...
-v elasticsearch_data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.x

docker-compose.ymlでの例:

“`yaml
services:
elasticsearch:
# … その他の設定 …
volumes:
– elasticsearch_data:/usr/share/elasticsearch/data

volumes:
elasticsearch_data: # ボリュームの定義
driver: local # ローカルホストのストレージを使用
“`

Docker管理ボリュームは、Dockerがデータディレクトリの所有権やパーミッションを適切に管理してくれるため、権限の問題が起こりにくいというメリットがあります。

バインドマウント (docker run および docker-compose.yml)

docker runでの例:

bash
docker run -d \
# ... その他のオプション ...
-v /path/to/your/local/data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.x

docker-compose.ymlでの例:

yaml
services:
elasticsearch:
# ... その他の設定 ...
volumes:
- ./data:/usr/share/elasticsearch/data # docker-compose.yml からの相対パス

バインドマウントを使用する場合、ホスト側のディレクトリの所有権とパーミッションが重要になります。Elasticsearchコンテナ内のプロセスは、特定のユーザー(通常は elasticsearch ユーザー、ID 1000)で実行されます。ホスト側のマウント先ディレクトリが、このユーザーIDで書き込み可能である必要があります。パーミッションが正しくないと、Elasticsearchがデータディレクトリに書き込めず、コンテナが起動に失敗することがあります。

どちらの方法を選ぶかはユースケースによりますが、データの永続化という目的においては、特別な理由がなければDocker管理ボリュームを使用するのが一般的です。設定ファイル(elasticsearch.yml)やカスタム辞書ファイルなどをコンテナにマウントしたい場合は、バインドマウントが便利です。

例 (docker-compose.yml で設定ファイルをマウント):

yaml
services:
elasticsearch:
# ...
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
- ./config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro # ホストの設定ファイルを読み取り専用でマウント

Kibana と連携させる

KibanaはElasticsearchのデータを可視化・分析するための強力なツールです。Docker Composeを使えば、ElasticsearchとKibanaを簡単に連携させて起動できます。

前のセクションで示したdocker-compose.ymlの例にKibanaサービスが含まれています。重要なのは以下の点です。

  1. イメージのバージョン: KibanaのDockerイメージは、接続するElasticsearchと同じメジャーバージョンを使用する必要があります(例: Elasticsearch 8.xにはKibana 8.x)。
  2. Elasticsearchへの接続設定: KibanaがElasticsearchを見つけられるように設定が必要です。これはKibanaコンテナの環境変数 ELASTICSEARCH_HOSTS で行います。
    • Docker Composeのネットワーク内では、サービス名(例: elasticsearch)がホスト名として解決されます。
    • 複数のElasticsearchノードがある場合は、コンマ区切りで複数のエンドポイントを指定できます。
    • セキュリティが有効な場合は、httpsスキームを使用し、必要に応じて認証情報 (ELASTICSEARCH_USERNAME, ELASTICSEARCH_PASSWORD) と証明書関連の設定を行います。
  3. 依存関係: KibanaがElasticsearchよりも先に起動して接続に失敗するのを防ぐため、depends_on: - elasticsearch を設定します。

Kibanaの環境変数例

セキュリティ無効時:

yaml
kibana:
# ...
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200

セキュリティ有効時 (パスワードは初回起動ログを確認):

yaml
kibana:
# ...
environment:
- ELASTICSEARCH_HOSTS=https://elasticsearch:9200
# パスワードは Docker Secrets などで安全に管理すべき
# - ELASTICSEARCH_USERNAME=elastic
# - ELASTICSEARCH_PASSWORD=your_generated_password
# 自己署名証明書の場合の例 (開発用)
# - ELASTICSEARCH_SSL_VERIFICATION_MODE=none

Kibanaを起動したら、ブラウザで http://localhost:5601 にアクセスし、UIが表示されるか確認してください。セキュリティが有効な場合はログインが必要です。

トラブルシューティング

DockerでElasticsearchを動かす際に遭遇しがちな問題と、その対処法をいくつか紹介します。

コンテナが起動しない

  • ログを確認する: これが最初に行うべきことです。docker logs <container_name or id> (Docker Composeなら docker compose logs <service_name>)コマンドで、コンテナの標準出力/標準エラー出力を確認します。エラーメッセージから原因を特定できることが多いです。
  • 環境変数設定ミス: docker-compose.ymlenvironment セクションの設定値が間違っていないか確認します。特にElasticsearch 8.xのセキュリティ関連設定(xpack.security.enabledなど)や、discovery.typeES_JAVA_OPTSはよく確認が必要です。
  • リソース不足: 特にメモリ不足はElasticsearchでよくある問題です。ES_JAVA_OPTSでヒープサイズを適切に設定しているか、Dockerホストに十分なメモリがあるか確認します。JVMのエラーログが出ていないか確認してください。
  • vm.max_map_count: Elasticsearchが起動時にこの設定をチェックし、不足しているとエラーで終了することがあります。「max virtual memory areas vm.max_map_count [xxx] is too low, increase to at least [262144]」のようなエラーがログに出ていないか確認し、ホストOS側の設定を行います。
  • ポートの競合: Elasticsearchが使用するポート(デフォルト9200, 9300)やKibanaのポート(デフォルト5601)が、ホストOS上の他のプロセスによって使用されていないか確認します。netstat -tulnp (Linux) や lsof -i :<port> などのコマンドで確認できます。

Elasticsearchクラスタが形成されない (複数ノードの場合)

  • ログを確認: 各ノードのログをチェックし、ディスカバリに関するエラーや警告が出ていないか確認します。
  • discovery.seed_hosts: 各ノードの設定で、クラスタ内の他のノードのホスト名(Docker Composeならサービス名)が正しく指定されているか確認します。
  • cluster.initial_master_nodes: 新しいクラスタの場合、初期マスターノード候補リストが正しく設定されているか確認します。
  • ネットワーク: Docker Composeネットワーク内でノード間通信ができているか確認します。コンテナ内に入って (docker exec -it <container_name> /bin/bash)、curlなどで他のノードのTransportポート(9300)にアクセスできるか試すことも有効です。ファイアウォールがコンテナ間の通信をブロックしていないか確認します。

KibanaがElasticsearchに接続できない

  • Kibanaのログを確認: KibanaのログにElasticsearchへの接続エラーが出ていないか確認します。
  • ELASTICSEARCH_HOSTS: Kibanaの環境変数 ELASTICSEARCH_HOSTS で指定されているElasticsearchのエンドポイント(ホスト名とポート)が正しいか確認します。Docker Compose環境では、Elasticsearchサービスのサービス名(例: elasticsearch)とポート(9200)を指定するのが一般的です。
  • ネットワーク: KibanaコンテナからElasticsearchコンテナにネットワーク的にアクセスできるか確認します。
  • セキュリティ設定: Elasticsearchでセキュリティが有効になっている場合、Kibanaの設定でHTTPSを使用しているか、認証情報(ユーザー名、パスワード)が正しく設定されているか、証明書関連の設定(ELASTICSEARCH_SSL_VERIFICATION_MODE, ELASTICSEARCH_SSL_CERTIFICATE_AUTHORITIESなど)が適切に行われているか確認します。パスワード間違いや証明書検証失敗が原因で接続できないことが多いです。

メモリ不足 (OutOfMemoryError)

  • Elasticsearchのログで OutOfMemoryError や関連する警告(「circuit breaker triggered」など)が出ていないか確認します。
  • ES_JAVA_OPTS-Xms, -Xmx の設定値を増やします。ただし、ホストOSの総メモリの50%を超えないように注意してください。
  • Dockerコンテナに割り当てるメモリ制限(mem_limit)が、ヒープサイズを含むElasticsearchが必要とする総メモリ量に対して十分か確認します。
  • ホストOSに十分な物理メモリがあるか確認します。

データが永続化されない

  • docker rundocker-compose.ymlvolumes 設定が正しく、コンテナ内のデータディレクトリ(/usr/share/elasticsearch/data)にマッピングされているか確認します。
  • バインドマウントを使用している場合、ホスト側のマウント先ディレクトリに対するコンテナ内のユーザー(デフォルトID 1000)の書き込み権限があるか確認します。権限問題はよくある原因です。ホスト側のディレクトリの所有者をElasticsearchコンテナ内のユーザーID(1000)に合わせるか、Dockerボリュームを使用することを検討してください。

セキュリティに関する考慮事項

ElasticsearchをDockerで運用する際、特に本番環境ではセキュリティが極めて重要です。

  • X-Pack Securityの有効化: Elasticsearch 8.x以降ではデフォルトで有効になっていますが、意図的に無効にしていないか確認し、必ず有効な状態で運用してください。
  • パスワード管理: 初回起動時に生成されるパスワードは安全な場所に保管してください。ELASTIC_PASSWORD環境変数でパスワードを設定する場合、docker-compose.ymlファイルやコマンド履歴に残らないよう、Docker SecretsやKubernetes Secretsのような機密情報管理ツールを使用することを強く推奨します。
  • TLS/SSL: ノード間通信およびクライアント(Kibana, アプリケーションなど)とElasticsearch間の通信には、必ずTLS/SSLを使用して暗号化を行ってください。自己署名証明書ではなく、適切な認証局(CA)によって署名された証明書を使用することが理想です。
  • ネットワーク隔離: Elasticsearchインスタンスやクラスタは、信頼できるクライアントからのみアクセスできるように、ファイアウォールやVPC/サブネット設定でネットワーク的に隔離してください。特にTransportポート(9300)はクラスタ内部通信用であり、外部に公開すべきではありません。HTTPポート(9200)も、必要最小限のソースIPアドレスからのみアクセスを許可すべきです。
  • アクセス制御: KibanaのSecurity機能やElasticsearchのロールベースのアクセス制御(RBAC)を使用して、ユーザーやアプリケーションが必要最低限の権限でしかデータにアクセスできないように設定してください。
  • イメージの信頼性: Docker Hub上の公式イメージ (docker.elastic.co/elasticsearch/...) を使用し、不明なソースから提供されたイメージは使用しないでください。

本番環境での考慮事項

開発環境のセットアップは比較的容易ですが、本番環境でElasticsearchをDockerで運用するには、さらに多くの考慮事項があります。

  • リソース管理: CPU、メモリ、ディスクI/OはElasticsearchのパフォーマンスに直結します。Dockerのリソース制限機能(cpu_shares, cpu_quota, mem_limit, memswap_limitなど)を適切に設定し、ホストOSのリソースも十分に確保してください。特にディスクI/Oは重要で、高速なSSDストレージの使用が強く推奨されます。
  • クラスタリング: 高可用性やスケーラビリティが必要な場合、単一ノードではなく複数ノードでクラスタを構成します。マスターノード、データノードなどの役割分担を考慮し、ノード数を決定します。Docker Composeでも複数ノードを定義できますが、本番環境ではDocker SwarmやKubernetesといったコンテナオーケストレーションプラットフォーム上で運用するのが一般的です。
  • モニタリングとロギング: Elasticsearchクラスタ、各ノード、コンテナのリソース使用率やヘルス状態を継続的に監視することが不可欠です。Elastic StackのMetricbeatやAPMエージェント、またはPrometheusなどの外部ツールを利用します。コンテナのログは集中ロギングシステム(例: ELK Stack自身、Splunk, Fluentdなど)に転送して管理します。
  • バックアップとリストア: データの損失を防ぐために、スナップショット機能を利用して定期的にデータのバックアップを取得し、外部ストレージに安全に保管します。リストア手順も確立しておきます。スナップショットはDockerボリュームではなく、共有ファイルシステムやS3互換ストレージなどのリポジトリに保存するのが一般的です。
  • SysctlとUlimits: vm.max_map_countやファイルディスクリプタ、memlockなどの重要なカーネルパラメータが、DockerホストOSレベルで適切に設定されていることを再確認してください。
  • ホストOSの最適化: スワップの無効化、ファイルディスクリプタ数の上限引き上げなど、Elasticsearchの動作に適したホストOSの設定を行います。
  • Docker Swarm / Kubernetes: より高度なオーケストレーション、自動復旧、スケーリング機能を利用するために、本番環境ではDocker SwarmモードやKubernetes上でElasticsearchクラスタを運用することが多いです。Elastic社はKubernetes上でElastic Stackをデプロイ・管理するためのOperator (Elastic Cloud on Kubernetes – ECK) を提供しています。

まとめ

本記事では、ElasticsearchをDockerコンテナで動かす方法について、基本的な単一ノードの起動から、Docker Composeを使ったより実践的なセットアップ、重要な設定項目、データ永続化、トラブルシューティング、そして本番環境での考慮事項まで、詳細に解説しました。

Dockerを使うことで、Elasticsearchの環境構築は劇的に簡略化され、移植性、一貫性、管理性が向上します。開発環境での手軽な利用から、Docker Composeを使った複数サービスの連携、さらにはコンテナオーケストレーションツールを活用した本番環境でのスケーラブルな運用まで、DockerはElasticsearchの導入・運用において強力なツールとなります。

Elasticsearchにはこの記事で触れられなかった多くの機能(インジェストパイプライン、アグリゲーション、マッピング設定、シャード・レプリカ設定など)や、関連プロダクト(Logstash, Beats)との連携、監視・アラート機能などがあります。これらの機能を活用することで、Elasticsearchをより深く使いこなすことができます。

本記事が、皆様がElasticsearchをDockerで活用する上での一助となれば幸いです。実際の運用においては、公式ドキュメントやコミュニティリソースを参照しながら、常に最新の情報に基づいた適切な設定を行うことをお勧めします。


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール