Docker+Amazon ECS+ElasticSearchでkibana用のElasticSearchクラスタ

[AWS][ECS][ElasticSearch][Docker] Docker+Amazon ECS+ElasticSearchでkibana用のElasticSearchクラスタを組んだ話


ElasticSearchクラスタをDockerでやろうと思った理由

  • chatopsでコンテナのデプロイをできる環境がある
    • 外出時に再起動だけならスマホでchatopsが可能
  • がっつりECSを利用している環境になっている
    • 本番環境もECSを利用
  • ElasticSearchはクラスタにジョインしたらデータをうまく分散してくれる
    • 手動リストアする必要がない
  • dockerhub にElasticSearchのDockerfileがある
    • そのまま使えるかも
      • 後述するが、少しいじった



上記理由からElasticSearchをDocker+ECSでやってみることにした

設計

1ECSクラスタ、1オートスケールのパターン(webサーバはこの構成)
  • ECSの1クラスタで全コンテナを立ち上げ直してしまう
    • 全台コンテナが再立ち上げされてしまうとElasticSearchへの接続がすべて止まってしまう
  • オートスケールで縮小する時レプリカ数と同じ台数が一気に落ちるとデータロストが起きてしまう


*** 上記理由から1ECSクラスタ、1オートスケールのパターンは無しにした


1ECSクラスタ、1インスタンス、複数Dockerコンテナのパターン
  • ECSの1クラスタで全コンテナを立ち上げ直してしまう
    • 先ほど同様ElasticSearchへの接続がすべて止まってしまう
    • コンテナからホストDiskをマウントすればデータロストは起きない
  • ホスト障害があった時にElasticSearchへの接続が止まる
    • EBSを利用していればOSを起動すればデータロストはない
      • AutoRecoveryも合わせて使うとよい


*** 分散型データストアなのに1台ホストが死んだら接続できなくなる時点でダメなので無しにした


1ECSクラスタ、1インスタンス、1Dockerコンテナのパターン
  • ECSでデプロイしても1コンテナが立ち上げ直されるだけ
    • なのでクラスタ内でリシャードは発生するが接続は瞬断がおきるレベルでほぼ影響なし
    • デプロイも1台ずつ順番に可能になる
  • ホスト障害があっても1コンテナが落ちるだけなのでクラスタ自体は壊れない
    • 複数ホストの同時障害は考えないものとする(Dockerとか関係ない部分)
    • EBSを利用してコンテナからホストDiskをマウントすればOSが再起動してもデータは残っているのでリシャード時間が短くなる
    • AutoRecoveryも使うと尚良
  • 手動でconfigはいじれないがconfigを変えたDocker imageを1台ずつ変更して設定できる
  • クラスタ分EC2を立てるのでお金はかかる
  • linkでのコンテナ間通信はできないのでホストに対して接続するようにしなければいけない


*** メリットも多いのでこの構成で行くことにした


ElasticSearch on Dockerでハマったポイント

  • dockerhubのDockerfileだとCLUSTER_NAMEやヒープサイズの指定ができない?
    • 調査不足感はあります
  • AWS自体でDocker関係なくあるのがMULTICASTは使えないのでUNICASTでクラスタを組む必要がある
    • UNICASTでホストを都度増やすなどconfig変更が大変
    • elasticsearch-cloud-aws MULTICASTができるができるだけVPC内通信でやりたかった
  • コンテナ内にelasticsearchユーザを作らないと起動できず
  • DockerからPublishするIPがコンテナのIPになってしまってクラスタが組めなかった


ハマったポイントの解決策
  • dockerhubのDockerfileをベースに起動スクリプトを自前で作成した
    • ECSで指定した環境変数もこの起動スクリプトで拾いconfigをsedで書き換えた
    • 環境変数を利用することで開発環境と本番環境のDockerfileは同じものを利用できる
  • config内のUNICAST先を増やす度にconfig再起動等したくないのでUNICAST先をELBにした
    • terraformを使っているのでホストを追加する度にELBにも追加して自動でクラスタのホスト追加ができるようにした

  • elasticsearchユーザを作ってもよかったがDocker imageを少しでも小さくするためrootで起動できるようにした
    • elasticsearchコマンドで起動オプションに-Des.insecure.allow.root=trueを付けた
  • publishIPがコンテナになってしまうのはホスト側のIPで出るようにした
    • elasticsearchコマンドで起動オプションに-Des.network.publish_host=${local_dns}を付けた
      • ${local_dns}はterraformでEC2を作る際にNAME_TAG.hoge.localと内部DNSをRoute53で設定しているものを指定するようにした


以上のハマったポイントを直したことでDocker+ECSのElasticSearchクラスタが構築できました。コンテナの再起動もchatopsでできるようになり簡単な再起動だけならパソコンを開く必要もなくなりました(*´ω`*)



kibanaからの接続

UNICASTでELBを作成したので、kibanaからも同じELBを指定しておくことでノードが増えてもkibana側の設定変更がいらなくなった

本番のアクセスログをkibanaにぶっこんだら問題が

  • 容量が多すぎてElasticSearchでOOMが発生
  • Disk容量も数日で7割近く利用している



ヒィィィ((((;゚Д゚))))ガクガクブルブル
やべーよ、ちょっと甘くみてたよ((((;゚Д゚))))ガクガクブルブル


対応
  • EC2のスペックアップをする
    • ついでにEBSの容量も大容量に・・・
  • terraformで1台ずつスペックとEBS容量を増やしてapplyした
    • 1台ずつEC2を再作成させ、chatopsでデプロイを行って、Diskのデータはなくなるがリシャードでクラスタがgreenになるのを待つ
  • これを繰り返してスペックアップを行えた


高速スケーラブル検索エンジン ElasticSearch Server (アスキー書籍)

高速スケーラブル検索エンジン ElasticSearch Server (アスキー書籍)

Amazon Web Services企業導入ガイドブック -企業担当者が知っておくべきAWSサービスの全貌から、セキュリティ概要、システム設計、導入プロセス、運用まで-

Amazon Web Services企業導入ガイドブック -企業担当者が知っておくべきAWSサービスの全貌から、セキュリティ概要、システム設計、導入プロセス、運用まで-