🙆‍♀️

ECKのアップデート手順走り書き

に公開

今回は、開発環境・テスト環境・本番環境それぞれで使っている Elastic Cloud on Kubernetes(以下、ECK)のバージョンを 7.17 → 8.17 にアップデートしたので、その流れをざっとまとめてみました。

アップデート手順(ざっくり)

  1. 破壊的変更点の確認
  2. ローカル環境で動作確認
  3. Elasticsearch クラスタのバックアップをとる
  4. テスト環境をアップデート
  5. 本番環境をアップデート

ECKについて

ECK は Kubernetes 上で Elasticsearch や Kibana を効率よく運用できるツールです。Elastic Operator が CRD(Custom Resource Definitions)としてクラスタをいい感じに管理してくれます。

まずは他の人のブログや公式ドキュメントを見ながら、アップデート時に注意すべき「破壊的変更点」を確認しました。

🔗 Migrating to Elasticsearch 8.0

セキュリティまわりの変化について

8.17 ではセキュリティまわりがけっこう変わっています。
たとえば、xpack のデフォルト設定が変更されてたりします。

7.17の設定

📄 Elasticsearch 7.17 Security Settings

8.17の設定

📄 Elasticsearch 8.17 Security Settings

CI環境でセキュリティ機能を無効にして動かしてると、認証エラーでテストが落ちるかもしれません。

ディープリサーチに変更点まとめて貰ってみた

結構ちゃんとまとめてくれた印象です。
セキュリティ周りの変更についてもしっかりと言及してくれています。

ここから↓↓↓

Elasticsearch 8.x 系では 7.x 系から多くの変更が加えられており、アップデート時には注意すべき破壊的変更(ブレイキングチェンジ)が多数存在します。本資料では、7.17.5 から 8.17.3 への移行にあたり、特に注意すべき点を以下の主要カテゴリごとに整理しています。

※なお、Elasticsearch 8.0 以降は Java 17 以上が必須であり、CentOS 6 や Ubuntu 16.04 などのサポートが終了している OS には対応していません。アップグレード前にシステム要件も確認しておく必要があります。


削除された機能

  • TransportClient の削除: 7.x 系で非推奨となっていた Java の TransportClient が完全に削除され、すべてのクライアント通信は HTTP ベースの REST インターフェースに統一されました。今後は Java High Level REST Client あるいは新しい Elasticsearch Java クライアントへの移行が必要です。

  • マッピングタイプの廃止: インデックスに対する複数タイプのサポートは 7.x で非推奨となり、8.0 で完全に削除されました。すべての API エンドポイントが typeless(例: /<インデックス>/_doc/<ID>)に置き換わっています。

  • 古いバージョンのインデックス非対応: Elasticsearch 8.x ノードは 7.0 より前に作成されたインデックスを読み込むことができません。6.x 以前のインデックスが存在する場合、事前に Elasticsearch 7.x 上で再インデックスを実行しておく必要があります。

  • dangling index の自動取込み廃止: 既存クラスタに存在しないインデックスデータ(dangling index)を自動で検知・取り込む機能が削除されました。代替手段として dangling indices API による手動インポートが推奨されています。

  • ノードロール設定の変更: node.masternode.data など旧来のロール指定は削除され、今後は node.roles による一括指定が必要です。

  • Zen Discovery 設定の廃止: すべての discovery.zen.* 設定は非対応となり、クラスタ発見処理は新方式(Zen2)へ完全移行しました。

  • 一部スナップショットプラグインの統合: repository-s3 など一部のスナップショットリポジトリプラグインは Elasticsearch 本体に統合され、別途のプラグイン導入が不要となりました。


デフォルト設定の変更

  • 破壊的操作の明示化: action.destructive_requires_name のデフォルト値が false から true に変更されました。ワイルドカード指定(*)による削除は明示的に許可設定しない限り拒否されます。

  • トランスポート圧縮の有効化: ノード間通信での圧縮機能がデフォルトで有効化され、transport.compress の既定値は false から indexing_data に変更されました。

  • 圧縮アルゴリズムの変更: デフォルトの圧縮方式が DEFLATE から LZ4 に変更されました。圧縮率は若干下がるものの、CPU負荷が軽くなり高スループットが期待されます。

  • seccomp(システムコールフィルタ)の強制有効化: bootstrap.system_call_filter 設定が削除され、seccomp が常に有効となりました。

  • FIPS モード時のパスワードハッシュ方式の変更: デフォルトが bcrypt から PBKDF2_STRETCH に変更されました。設定なしの場合でも起動時にエラーにはなりません。

  • Kibana 内蔵ユーザー名の変更: デフォルトで使用されるユーザー名が kibana から kibana_system に変更されています。


非推奨から削除された API や動作

  • _xpack エンドポイントの削除: _xpack を含む全ての REST API エンドポイントが削除されました。該当 API を利用している場合は、新しいエンドポイントに修正が必要です。

  • type 名指定の API 廃止: _bulk_search などで /<タイプ名> を含む形式は利用不可となり、タイプレス API のみ有効です。

  • 代表的な削除済み設定項目:

    • cluster.routing.allocation.disk.include_relocations
    • cluster.join.timeout
    • search.remote.*cluster.remote.* に置き換え)
    • node.max_local_storage_nodes
    • http.content_type.required
    • xpack.security.authc.accept_default_password
    • index.translog.retention.size
    • gateway.auto_import_dangling_indices

セキュリティ要件の強化

  • X-Pack Security のデフォルト有効化: 認証・権限管理、ノード間の TLS 暗号化がデフォルトで有効になります。

  • Kibana ユーザーの変更: kibana_system に名称変更され、設定ファイル内での修正とパスワードの再設定が必要です。

  • elastic ユーザーの初期パスワード生成: 初回起動時に自動生成され、画面に表示されます。

  • 匿名アクセスの禁止: デフォルトで無効となり、認証なしのアクセスは拒否されます。

  • Realm の order 指定が必須: すべての Realm に xpack.security.authc.realms.<type>.<name>.order を明示する必要があります。

  • SSL/TLS 設定の厳格化:

    • .enabled を明示しないと起動時エラー
    • 証明書と秘密鍵の設定が必須

クライアント・プロトコルレベルの変更

  • TransportClient の削除と移行: 9300 番ポート通信は非対応となり、HTTP(S)(9200 番)を使用した REST クライアントへの移行が必要です。

  • REST API の仕様変更:

    • URL における + の扱いが厳密化
    • Content-TypeAccept の明示が必須
  • クロスクラスタ検索(CCS)の互換性制限:

    • 8.x クラスタからの検索は、リモートが 7.17 以降のみ対応
    • cluster.remote.connect は削除され、代替として node.remote_cluster_client を使用
  • ノード間通信プロトコルの変更:

    • TLS がデフォルトで有効(セキュリティ有効時)
    • 混在環境でのアップグレードには TLS 対応の準備が必要

以上が、Elasticsearch 7.17.5 から 8.17.3 へアップグレードする際に押さえておくべき主要な変更点です。設定ファイルの見直し、クライアントコードの移行、セキュリティ対応など、事前準備を十分に行い、段階的な移行を計画することを強くおすすめします。

公式ドキュメント(Migrating to 8.0)やリリースノートも併せてご確認ください。

ローカル環境で動作確認してみる

まずは Docker Compose で立てたローカルの Elasticsearch をアップデートして、下記の項目を中心に色々と動作確認を行いました。

  • 検索できるか
  • インデックスの再生成や同期ができるか
  • テストが通るか
  • 並び順(ソート)が変わってないか
  • ヘルスチェックに異常がないか

確認コマンド例

curl localhost:9200/coeteco_development_hoge/_mapping?pretty=true
curl localhost:9200/coeteco_development_hoge/_cluster/health?pretty=true

スナップショットでバックアップをとる

Elasticsearch には「スナップショット」というバックアップ機能があるので、それを使って事前にバックアップを取ります。

📄 Snapshot and Restore

GCP 上で動かしているので、GCS をバックアップ先に設定しました。
作業ログを残したかったので、Kibana よりも CLI で設定してます。

スナップショット設定の確認

curl -k https://elastic:XXX@hogehoge-http:9200/_snapshot?pretty

出力例

{
  "snapshot" : {
    "type" : "gcs",
    "uuid" : "XXX",
    "settings" : {
      "bucket" : "gcs-bucket"
    }
  }
}

バックアップ取得コマンド

curl -X PUT "https://elastic:XXX@hogehoge-http:9200/_snapshot/snapshot/full_backup_$(date +%Y%m%d_%H%M%S)" -H 'Content-Type: application/json' -d '{
  "indices": "*",
  "ignore_unavailable": true,
  "include_global_state": true
}'

テスト環境をアップデートしてみる

アップデート前に、下記 API を使って非推奨設定のチェックをします。

📄 Migration API - Deprecation Check

curl -X GET "https://elastic:XXX@hogehoge-http:9200/_migration/deprecations?pretty"

Kibana に「アップグレードアシスタント」が使える状態なら、そっちを使うのもアリです。
📄 Kibana Upgrade Assistant API

チェックしてくれるのはこんな項目です:

  • クラスタ設定
  • ノード設定
  • インデックス設定
  • 機械学習設定
  • CCR自動フォロー設定

実際のアップデート作業

やることはとってもシンプルで、CRD の version を目的のバージョンに変えるだけです。

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elasticsearch-test
spec:
  version: 8.17.3

これを kubectl apply すると、Elastic Operator が順番にアップデートしてくれます(ダウンタイムなし!)。

バージョン確認

curl -X GET "https://elastic:XXX@hogehoge-http:9200"

本番環境でのアップデート

基本的にはテスト環境と同じ流れです。
ただ、アップデートチェックをかけたら warningcritical がいくつか出ました。

例)

{
  "message": "Setting [xpack.monitoring.collection.enabled] is deprecated"
}

不要なクラスタ設定を削除

curl -X PUT "https://elastic:XXX@elasticsearch-http:9200/_cluster/settings" -H 'Content-Type: application/json' -d '{
  "persistent": {
    "discovery.zen.minimum_master_nodes": null,
    "xpack.monitoring.collection.enabled": null
  }
}'

古いインデックスのリインデックス

ざっくり言うと:

  1. 元のインデックスをコピー(=リインデックス)
  2. エイリアスを新しいインデックスに張り替え
  3. 動作確認
  4. 古いインデックスを削除

エイリアスの張り替えコマンド

curl -X POST "https://elastic:XXX@elasticsearch-es-http:9200/_aliases" -H 'Content-Type: application/json' -d '{
  "actions": [
    { "remove": { "index": ".index-6", "alias": ".index" } },
    { "add": { "index": ".index_reindexed", "alias": ".index" } }
  ]
}'

最後に

本番環境のバージョンアップも無事完了しました!
クラスタのステータスも問題なさそうで、ログや動作もOKです。

アップデート作業自体はすごくシンプルですが、事前の調査や確認はかなり大事です。
スナップショットの取得や動作確認、リインデックス作業も含めて、慎重に進めるのがポイントかなと思います。

Discussion