【Amazon Elasticsearch Service】 手動スナップショットからリストアする方法
Amazon ESでは自動スナップショットと手動スナップショットがありますが、自動スナップショットからは新しいAmazon ES ドメインにリストアすることはできません。 そのため新しいAmazon ES ドメインにリストアするには手動スナップショットからリストアする必要があります。
今回は手動スナップショットの作成方法と手動スナップショットからリストアする方法についてご紹介します。
Step1: S3バケットの作成、設定
手動スナップショットを保存するためのS3バケットを作成します。
S3コンソールでes-test-index-repo
という名前で作成しました。
バケットのARNは後ほど使用するのでメモしておきます。
- arn:aws:s3:::es-test-index-repo
Step2: IAM の設定
IAMコンソールで設定していきます。
Policies -> Create policy から以下ポリシーes-test-index-repo-policy
を作成します。
Resource
には先ほど作成したS3バケットのARNarn:aws:s3:::es-test-index-repo
を指定しています。
{ "Version":"2012-10-17", "Statement":[ { "Action":[ "s3:ListBucket" ], "Effect":"Allow", "Resource":[ "arn:aws:s3:::es-test-index-repo" ] }, { "Action":[ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Effect":"Allow", "Resource":[ "arn:aws:s3:::es-test-index-repo/*" ] } ] }
Roles
-> Create role
からIAM ロールes-test-index-repo-role
を作成します。
先ほど作成したポリシーを付与し、信頼関係を以下のようにします。
ロールの信頼関係
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "es.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
手動スナップショットレポジトリの登録のためにAPIキーを使用するユーザーに対して以下ポリシーを作成してアタッチします。
- es-backup-policy
{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::aws_account_id:role/es-test-index-repo-role" } }
Step3: 手動スナップショットレポジトリの登録
手動スナップショットを取得する前に、一度だけスナップショットレポジトリを登録する必要があります。
こちらはAWSリクエストに署名することが必要です。curl
ではAWSリクエスト署名をサポートしていません。
pythonのサンプルコードがありますのでこちらを参考に実施します。
register-repo.py
- AWS_ACCESS_KEY_ID = ''
- AWS_SECRET_ACCESS_KEY = ''
- host = '' # ES ドメインのエンドポイント
- region = 'us-west-2' # ES ドメインのリージョン
- path = '' # スナップショットリポジトリの名前
- bucket = '' # S3バケット名
- role_arn = '' # 先ほど作成したIAMロールのANR
import requests from requests_aws4auth import AWS4Auth AWS_ACCESS_KEY_ID ='' AWS_SECRET_ACCESS_KEY ='' region = 'us-west-2' service = 'es' awsauth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, region, service) host = 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/' path = '_snapshot/es-test-index-repo' url = host + path payload = { "type": "s3", "settings": { "bucket": "s3-bucket-name", "region": "us-west-2", "role_arn": "arn:aws:iam::aws_account_id:role/es-test-index-repo-role" } } headers = {"Content-Type": "application/json"} r = requests.put(url, auth=awsauth, json=payload, headers=headers) print(r.text)
実行
$ python register-repo.py {"acknowledged":true}
Step4: 手動スナップショットの取得
アクセスポリシーがIAMユーザーや、IAMロールの場合、リクエストに署名をする必要があります。サンプルコードがドキュメントにありますのでサンプルコードを参考に実施します。
署名リクエストを必要とする場合はpythonのコードを、署名リクエストを必要としない場合はcurlの実行例をご参照ください。
snapshot.py
- path # snapshot名を指定します。
import requests from requests_aws4auth import AWS4Auth AWS_ACCESS_KEY_ID='' AWS_SECRET_ACCESS_KEY='' region = 'us-west-2' service = 'es' awsauth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, region, service) host = 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/' path = '_snapshot/es-test-index-repo/my-snapshot-1' url = host + path r = requests.put(url, auth=awsauth) print(r.text)
実行
$ python snapshot.py {"accepted":true}
curl
$ curl -XPUT 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/_snapshot/es-test-index-repo/my-snapshot-2' {"accepted":true}
Step5: スナップショットのリポジトリ確認
check_repository.py
import requests from requests_aws4auth import AWS4Auth AWS_ACCESS_KEY_ID='' AWS_SECRET_ACCESS_KEY='' region = 'us-west-2' service = 'es' awsauth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, region, service) host = 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/' path = '_snapshot/?pretty' url = host + path r = requests.get(url, auth=awsauth) print(r.text)
実行結果
$ python repository.py { "es-test-index-repo" : { "type" : "s3", "settings" : { "bucket" : "es-test-index-repo", "region" : "us-west-2", "role_arn" : "arn:aws:iam::aws_account_id:role/es-test-index-repo" } }, "cs-automated" : { "type" : "s3" } }
curl
$ curl -XGET 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/_snapshot?pretty' { "es-test-index-repo" : { "type" : "s3", "settings" : { "bucket" : "es-test-index-repo", "region" : "us-west-2", "role_arn" : "arn:aws:iam::aws_account_id:role/es-test-index-repo-role" } } }
Step6: リポジトリからスナップショットの確認
スナップショットを確認します。
check_snapshot.py
import requests from requests_aws4auth import AWS4Auth AWS_ACCESS_KEY_ID='' AWS_SECRET_ACCESS_KEY='' region = 'us-west-2' service = 'es' awsauth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, region, service) host = 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/' path = '_snapshot/es-test-index-repo/_all?pretty' url = host + path r = requests.get(url, auth=awsauth) print(r.text)
実行結果
$ python check_snapshot.py { "snapshots" : [ { "snapshot" : "my-snapshot-1", "uuid" : "**********aixSzBQFI_2g", "version_id" : 6020299, "version" : "6.2.2", "indices" : [ "index1", "index2" ], "include_global_state" : true, "state" : "SUCCESS", "start_time" : "2018-05-25T02:12:52.086Z", "start_time_in_millis" : 1527214372086, "end_time" : "2018-05-25T02:12:55.745Z", "end_time_in_millis" : 1527214375745, "duration_in_millis" : 3659, "failures" : [ ], "shards" : { "total" : 10, "failed" : 0, "successful" : 10 } }, { "snapshot" : "my-snapshot-2", "uuid" : "**********Svf55AYG0QuQ", "version_id" : 6020299, "version" : "6.2.2", "indices" : [ "index1", "index2" ], "include_global_state" : true, "state" : "SUCCESS", "start_time" : "2018-05-25T02:13:36.289Z", "start_time_in_millis" : 1527214416289, "end_time" : "2018-05-25T02:13:38.326Z", "end_time_in_millis" : 1527214418326, "duration_in_millis" : 2037, "failures" : [ ], "shards" : { "total" : 10, "failed" : 0, "successful" : 10 } } ] }
curl
curl -XGET 'elasticsearch-domain.us-west-2.es.amazonaws.com/_snapshot/es-test-index-repo/_all?pretty' { "snapshots" : [ { "snapshot" : "my-snapshot-1", "uuid" : "**********aixSzBQFI_2g", "version_id" : 6020299, "version" : "6.2.2", "indices" : [ "index1", "index2" ], "include_global_state" : true, "state" : "SUCCESS", "start_time" : "2018-05-25T02:12:52.086Z", "start_time_in_millis" : 1527214372086, "end_time" : "2018-05-25T02:12:55.745Z", "end_time_in_millis" : 1527214375745, "duration_in_millis" : 3659, "failures" : [ ], "shards" : { "total" : 10, "failed" : 0, "successful" : 10 } }, { "snapshot" : "my-snapshot-2", "uuid" : "**********Svf55AYG0QuQ", "version_id" : 6020299, "version" : "6.2.2", "indices" : [ "index1", "index2" ], "include_global_state" : true, "state" : "SUCCESS", "start_time" : "2018-05-25T02:13:36.289Z", "start_time_in_millis" : 1527214416289, "end_time" : "2018-05-25T02:13:38.326Z", "end_time_in_millis" : 1527214418326, "duration_in_millis" : 2037, "failures" : [ ], "shards" : { "total" : 10, "failed" : 0, "successful" : 10 } } ] }
Step7: スナップショットのリストア
ここでは2つのパターンで実施します。
- 同じESドメインにリストアする
- 別のESドメインにリストアする
Step7-1 同じESドメインにリストアする
リストアの際に同じ名前のインデックスがある場合、リストアができないので一旦削除します。 ※ Amazon ES は Elasticsearch _close API をサポートしていないため。
delete_index.py
インデックスを削除します。
import requests from requests_aws4auth import AWS4Auth AWS_ACCESS_KEY_ID='' AWS_SECRET_ACCESS_KEY='' region = 'us-west-1' service = 'es' awsauth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, region, service) host = 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/' # DELETE INDEX path = 'my-index' url = host + path r = requests.delete(url, auth=awsauth) print(r.text)
$ python delete_index.py {"acknowledged":true}
curl
インデックスをすべて削除
curl -XDELETE'https://elasticsearch-domain.us-west-2.es.amazonaws.com/_all'
インデックスを指定して削除
$ curl -XDELETE 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/index-name'
restore-all.py
pathでスナップショット名を指定しています。
import requests from requests_aws4auth import AWS4Auth AWS_ACCESS_KEY_ID='' AWS_SECRET_ACCESS_KEY='' region = 'us-west-1' service = 'es' awsauth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, region, service) host = 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/' path = '_snapshot/es-test-index-repo/my-snapshot-1/_restore' url = host + path r = requests.post(url, auth=awsauth) print(r.text)
$ python restore.py {"accepted":true}
restore-one.py
特定のインデックスをリストア
こちらはpayload
で特定のインデックスを指定しています。
import requests from requests_aws4auth import AWS4Auth AWS_ACCESS_KEY_ID='' AWS_SECRET_ACCESS_KEY='' region = 'us-west-1' service = 'es' awsauth = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, region, service) host = 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/' path = '_snapshot/es-test-index-repo/my-snapshot-1/_restore' url = host + path payload = {"indices": "my-index"} headers = {"Content-Type": "application/json"} r = requests.post(url, auth=awsauth, json=payload, headers=headers) print(r.text)
$ python restore-one.py {"accepted":true}
curl
インデックスをすべてリストア
curl -XPOST 'elasticsearch-domain.us-west-2.es.amazonaws.com/_snapshot/es-test-index-repo/my-snapshot-1/_restore' {"accepted":true}
特定のインデックスをリストア
$ curl -XPOST 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/_snapshot/es-test-index-repo/_restore' -d '{"indices": "my-index"}' -H 'Content-Type: application/json'
Step7-2 別ドメインにリストアする
別ドメインに対してリストアする場合は、別ドメインも同じスナップショットレポジトリを登録する必要があります。
Step3: 手動スナップショットレポジトリの登録 を別ドメインで再度登録します。
※register-repo.pyのhost
を変更して実行します。
register-repo.py
$ python register-repo.py {"acknowledged":true}
その後、別ドメインに対してリストアを実行します。
host
を変更して実行します。
restore.py でリストアを実施
$ python restore-all.py {"accepted":true}
curl
curl -XPOST 'https://elasticsearch-domain.us-west-2.es.amazonaws.com/_snapshot/es-test-index-repo/my-snapshot-1/_restore'
まとめ
今回は手動スナップショットからAmazon ES ドメインをリストアする方法について以下ドキュメントを元に試してみました。 別ドメインにリストアする場合や、メンテナンスの前に手動スナップショットを取得しリストアするときに参考になれば幸いです。