概要
AWS Elasticsearch Service (ES) 2.3 → 5.5 へバージョンアップを実施に際して
以下記事をまとめました。
大まかな流れ
- ES バージョン 2.3 のドメインから Snapshot 取得
- ES バージョン 5.5 のドメイン作成
- アプリの fluentd の向け先を ES バージョン 5.5 へ変更
- ES バージョン 5.5 のドメインにデータリストア
- ES バージョン 2.3 のドメイン削除
現状バージョン確認
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ curl https://<Elasticsearch 2.3 Endpoint Domain>
{ "name" : "Jackdaw", "cluster_name" : "<Account ID>:xxxxxxxxxx", "version" : { "number" : "2.3.2", "build_hash" : "72aa8010df1a4fc849da359c9c58acba6c4d9518", "build_timestamp" : "2016-11-14T15:59:50Z", "build_snapshot" : false, "lucene_version" : "5.5.0" }, "tagline" : "You Know, for Search" }
|
その他、AWS console のクラスターの設定確認
その他クラスターへ設定している情報をメモ
AWS Elasticsearch Service スナップショットを S3 で管理する
IAM role 作成
- アクセス権限は特に設定せず 「次のステップ」ボタンクリック
- ロール名を es-index-backups とし作成
ロール ARN arn:aws:iam:::role/es-index-backups で作成されていることが確認できる
Service を es.amazonaws.com に編集
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "es.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
|
IAM User 作成
- ユーザ名
es-index-backup-user
とし プログラムによるアクセスにチェックを入れて 次のステップ
クリック
- 特にポリシーをアタッチせず
次のステップ
クリック
es-index-backup-user
を作成し独自ポリシーで先ほど作成した role へのアクセス許可設定をアタッチします。
1 2 3 4 5 6 7 8 9 10 11 12
| { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": "arn:aws:iam::<Account ID>:role/es-index-backups" } ] }
|
- 発行されたアクセスキー、シークレットアクセスキーをメモしておきます。
S3 バケット作成
S3 > バケットを作成する
でバケット作成してください。
Elasticsearch にてスナップショットリポジトリ作成
スナップショットを管理するリポジトリを Elasticsearch に作成する必要があります。
Elasticsearch へのアクセス可能なサーバにて以下スクリプト実行します。
- register_es_repository.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from boto.connection import AWSAuthConnection
class ESConnection(AWSAuthConnection):
def __init__(self, region, **kwargs): super(ESConnection, self).__init__(**kwargs) self._set_auth_region_name(region) self._set_auth_service_name("es")
def _required_auth_capability(self): return ['hmac-v4']
if __name__ == "__main__":
client = ESConnection( region='ap-northeast-1', host='<Elasticsearch 2.3 Endpoint Domain>', aws_access_key_id='<ACCESS KEY ID>', aws_secret_access_key='<SECRET ACCESS KEY>', is_secure=False)
resp = client.make_request( method='POST', path='/_snapshot/index-backups', data='{"type": "s3","settings": { "bucket": "<bucket name>","region": "ap-northeast-1","role_arn": "arn:aws:iam::<Account ID>:role/es-index-backups"}}' ) body = resp.read() print body
|
1 2 3 4 5 6
| $ chmod +x register_es_repository.py
$ python register_es_repository.py
// 成功 {"acknowledged":true}
|
リポジトリ登録完了しました。
Snapshot 取得
snapshot 名を 20170926
とします。
1 2 3 4
| $ curl -XPUT "https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926"
// 成功 {"accepted":true}
|
Snapshot 一覧
20170926
という snapshot 名で取得したことが確認できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| $ curl -s -XGET "https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/_all" | jq . { "snapshots": [ { "snapshot": "20170926", "version_id": 2030299, "version": "2.3.2", "indices": [ "nginx-access-2017.09.09", "nginx-access-2017.09.07", "nginx-access-2017.09.08", "nginx-error-2017.08.24", "nginx-error-2017.08.23", ".kibana-4", ... ], "state": "IN_PROGRESS", "start_time": "2017-09-26T03:58:51.040Z", "start_time_in_millis": 1506398331040, "failures": [], "shards": { "total": 0, "failed": 0, "successful": 0 } } ] }
|
Snapshot 削除
スナップショット 20170926
を削除する場合、DELETE メソッドを実行します。
1 2 3 4
| $ curl -XDELETE https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926
// 成功 {"acknowledged":true}
|
S3 確認
以下が作成されているのがわかります。
はじめ meta-_ が作成できたら完了なのかなと思いきや
snap-_ も作られるまで待つ必要がありました。
- CLI 上でスナップショット完了確認した方が確実です。
1 2 3 4 5 6
| $ curl -s -GET https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926
... "state": "SUCCESS", ... ...
|
Elasticsearch 5.5 Service 新規ドメイン作成
Elasticsearch 2.3 の設定に倣って作成します。
リポジトリ作成
- register_es55_repository.py
register_es_repository.py の host 部分を新規ドメインに修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| from boto.connection import AWSAuthConnection
class ESConnection(AWSAuthConnection):
def __init__(self, region, **kwargs): super(ESConnection, self).__init__(**kwargs) self._set_auth_region_name(region) self._set_auth_service_name("es")
def _required_auth_capability(self): return ['hmac-v4']
if __name__ == "__main__":
client = ESConnection( region='ap-northeast-1', host='<Elasticsearch 5.5 Endpoint Domain>', aws_access_key_id='<ACCESS KEY ID>', aws_secret_access_key='<SECRET ACCESS KEY>', is_secure=False)
print 'Registering Snapshot Repository' resp = client.make_request( method='POST', path='/_snapshot/index-backups', data='{"type": "s3","settings": { "bucket": "<bucket name>","region": "ap-northeast-1","role_arn": "arn:aws:iam::<Account ID>:role/es-index-backups"}}' ) body = resp.read() print body
|
1 2 3 4 5 6
| $ chmod +x register_es55_repository.py
$ python register_es55_repository.py
// 成功 {"acknowledged":true}
|
スナップショットからリストア
20170926
のスナップショットをリストアします。
1 2 3 4
| $ curl -XPOST "https://<Elasticsearch 5.5 Endpoint Domain>/_snapshot/index-backups/20170926/_restore"
// 成功 {"accepted": true}
|
リストア確認
1
| $ curl -XGET "https://<Elasticsearch 5.5 Endpoint Domain>/_cat/indices"
|
スナップショットに失敗するケース
- .kibana index が既に存在しており、リストアできない。
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "error":{ "root_cause":[ { "type":"snapshot_restore_exception", "reason":"[index-backups:20170926/Hc4rLIoARCWqpyJXeP7edw] cannot restore index [.kibana] because it's open" } ], "type":"snapshot_restore_exception", "reason":"[index-backups:20170926/Hc4rLIoARCWqpyJXeP7edw] cannot restore index [.kibana] because it's open" }, "status":500 }
|
対応策
1 2 3
| curl -XPOST https://<Elasticsearch 5.5 Endpoint Domain>/_snapshot/index-backups/20170926/_restore -d '{ "indices": "nginx-*" }' | jq .
|
indices
を用い、スナップショット内のインデックスの中からマッチする正規表現のみをリストアできます。
自身ではこの様な解決法を実施し回避できました。
その他良い方法があれば御指南いただけますと幸いです。
ちなみに
Terraform で ES 2.2 → 5.5 バージョンアップを実施した所
1 時間以上経過してようやくアップデートが完了しました。
1 2 3 4
| aws_elasticsearch_domain.elasticsearch: Still destroying... (ID: arn:aws:es:ap-northeast-1:xxxxxxxxxxxx:domain/***, 59m11s elapsed) aws_elasticsearch_domain.elasticsearch: Still destroying... (ID: arn:aws:es:ap-northeast-1:xxxxxxxxxxxx:domain/***, 59m21s elapsed) aws_elasticsearch_domain.elasticsearch: Still destroying... (ID: arn:aws:es:ap-northeast-1:xxxxxxxxxxxx:domain/***, 59m31s elapsed) aws_elasticsearch_domain.elasticsearch: Destruction complete after 59m41s
|
これは辛い (>_<)
Terraform で管理している場合、
スナップショットを取得したら aws console 上でドメイン削除した方が早い。
ブルーグリーン的に ES 5.5 作成して ES 2.2 から乗り換えて
しばらく運用して問題なければ ES 2.2 を削除する方法が一番確実だなと思いました。