長生村本郷Engineers'Blog

千葉県長生村本郷育ちのエンジニアが書いているブログ

Prometheus2.0 remote storage 検証

いよいよ出ました Prometheus 2.0 !

prometheus.io

先日モニタリング勉強会でも Paul Taylor さんの LT を拝聴させて頂き
パフォーマンス向上とストレージフォーマット変更による圧縮・バックアップがしやすくなった等、 良い話がたくさん出ていました。

www.slideshare.net

中でも最も期待していた機能が Remote Long-Term Storage、
長期保存機能には歓喜しました♪

1系以下では、短期間用と長期間用の Prometheus を別途用意する等、対策が必要で 冗長な作りを余儀なくされたところがありましたが 2.0 リリースでついに!

早速試してみたく使用感をまとめました。

今回やりたかったことまとめ

  • Prometheus 2.0 リリースに際して期待の長期保存機能 (Remote long-term storage) を早速試す!
  • 実際にローカル環境で構築してみて1系からの変更箇所を確認
  • DB 側にどんなデータが入るのか確認

システム概要

あくまで使用感の検証をしたかったので docker-compose でお手軽に作れる環境にしました。

Imgur

前提条件

以下を Vagrant にインストール

  • Ubuntu 16.04.3 LTS \n \l
  • Docker version 17.09.0-ce, build afdb6d4
  • docker-compose version 1.12.0, build b31ff33

起動する Docker Container

  • Prometheus 2.0.0
  • Node Exporter 0.15.1
  • AlertManager 0.9.1
  • cAdvisor 0.28.0
  • Prometheu Adapter
  • PostgreSQL 9.6.3
  • Grafana 4.6.1
  • Nginx 1.13.6
  • Adminer

使い方

以下手順通りです。
https://github.com/kenzo0107/vagrant-docker/tree/vagrant-docker-ubuntu16.04/docker/prometheus-grafana-on-ubuntu

macOS%$ git clone https://github.com/kenzo0107/vagrant-docker
macOS%$ cd vagrant-docker
macOS%$ vagrant up

// Install docker, docker-compose
macOS%$ vagrant provision
macOS%$ vagrant ssh
vagrant%$ cd /vagrant/prometheus-grafana-on-ubuntu
vagrant%$ sudo docker-compose up -d

Name                             Command                            State                             Ports
-------------------------------------------------------------------------------------------------------------------------------------
adapter                           /prometheus-postgresql-ada ...    Up
adminer                           entrypoint.sh docker-php-e ...    Up                                8080/tcp
alertmanager                      /bin/alertmanager -config. ...    Up                                9093/tcp
cadvisor                          /usr/bin/cadvisor -logtost ...    Up                                8080/tcp
grafana                           /run.sh                           Up                                3000/tcp
nginx                             nginx -g daemon off;              Up                                0.0.0.0:18080->18080/tcp,
                                                                                         0.0.0.0:3000->3000/tcp, 80/tcp,
                                                                                         0.0.0.0:8080->8080/tcp,
                                                                                         0.0.0.0:9090->9090/tcp
node-exporter                     /bin/node_exporter                Up                                9100/tcp
pgsql                             docker-entrypoint.sh -csyn ...    Up                                5432/tcp
prometheus                        /bin/prometheus --config.f ...    Up                                9090/tcp

アクセスしてみる

Prometheus

Imgur

Grafana

GF_SECURITY_ADMIN_USER=admin-user
GF_SECURITY_ADMIN_PASSWORD=admin-pass

Imgur

  • Datasource 設定

Imgur

Datasource 設定フォームに以下情報を入力し Add ボタンをクリックします。

Item Value
Name Prometheus
Type Prometheus
URL http://prometheus:9090
Access proxy

Imgur

Imgur

グラフが表示されます。

Imgur

cAdvisor

Imgur

Adminer

Imgur

ログインフォームに以下情報を入力します。

Item Value
Server pgsql
Username prometheus
Password password
Database postgres
  • PostgreSQL に保存されているメトリクス情報が確認できます。

PostgreSQL >> pgsql >> postgres >> prometheus >> Select: metrics

Imgur

AlertManager でアラート通知してみる

例として node-exporter を停止

vagrant%$ sudo docker-compose stop node-exporter

./alertmanager/config.yml で設定した Slack Channel にちゃんと通知がきました。 f:id:kenzo0107:20171113021331p:plain

所感

  • 2.0 になって設定の仕方が諸々変わり、公式サイトじっくり見る必要あります。

  • 今回は Prometheus ×1 台構成ですが、2台以上で冗長化する構成も試してみたい。

余談

あとがき

Mackerel の様なマネージドな監視サービスで運用コストを削減する以上に
Prometheus をマネージドすれば、さらにトータルコストを抑えられる様になる、
と睨んでます。

ですが、Datadog は APM 付きプランも適度なコスト感で提供しておりマネージドサービスの魅力は尚大きいです。

モニタリングの棲み分けをできる様にするにも、
選択肢の一つにするにも Prometheus 挑戦しがいがあるのでは? と思っています。

Prometheus、今後さらに広まることを期待しています。

参考

iftop でネットワーク接続状況をリアルタイム監視

iftop 概要

CLI上で利用できるネットワークの接続状況をリアルモニタリングするツールです。
→ ネットワークのボトルネックを特定する為に利用します。

単にネットワークのモニタリングであれば、モニタリングツールで良いですが

具体的にどこ(ドメイン・IP・ポート)にどれくらい(データ転送量)がわかります。

インストール方法

$ sudo apt-get install -y iftop
$ sudo yum -y install epel-release
$ sudo yum -y install iftop

使い方

よく利用するのはこんな形です。
※eth0 がない場合は -i eth0 を除いてください。

$ sudo iftop -i eth0 -B -P -n -N
  • -i インターフェース指定
  • -B 表示単位を Byte にする
  • -P プロトコル or ポート表示
  • -n ドメインでなく ip で表示
  • -N プロトコルサービス名でなくポート番号で表示

表示項目

=> が送信、
<= が受信です

                           24.4kB                      48.8kB                      73.2kB                      97.7kB                 122kB
+--------------------------+---------------------------+---------------------------+---------------------------+---------------------------
ip-10-13-1-101.ap-northeast-1.compute.internal:http      => ip-10-13-100-41.ap-northeast-1.compute.internal:62635     559kB   121kB  67.1kB
                                                        <=                                                          3.60kB  1.90kB  1.05kB
ip-10-13-1-101.ap-northeast-1.compute.internal:35244     => ip-10-13-102-56.ap-northeast-1.compute.internal:mysql       0B   2.18kB  1.21kB
                                                        <=                                                             0B   23.1kB  12.8kB
ip-10-13-1-101.ap-northeast-1.compute.internal:35247     => ip-10-13-102-56.ap-northeast-1.compute.internal:mysql       0B   2.13kB  1.18kB
                                                        <=                                                             0B   23.0kB  12.8kB
ip-10-13-1-101.ap-northeast-1.compute.internal:http      => ip-10-13-0-231.ap-northeast-1.compute.internal:8239         0B   7.73kB  4.29kB
                                                        <=                                                             0B   1.16kB   658B
ip-10-13-1-101.ap-northeast-1.compute.internal:ssh       => ip-10-13-0-11.ap-northeast-1.compute.internal:56320       612B    576B    522B
                                                        <=                                                            26B     26B     32B
ip-10-13-1-101.ap-northeast-1.compute.internal:http      => ip-10-13-100-41.ap-northeast-1.compute.internal:62657       0B     49B     27B
                                                        <=                                                             0B     92B     51B
ip-10-13-1-101.ap-northeast-1.compute.internal:40069     => ip-10-13-103-247.ap-northeast-1.compute.internal:6379       0B     99B     55B
                                                        <=                                                             0B     34B     19B
ip-10-13-1-101.ap-northeast-1.compute.internal:40072     => ip-10-13-103-247.ap-northeast-1.compute.internal:6379       0B     99B     55B
                                                        <=                                                             0B     34B     19B
ip-10-13-1-101.ap-northeast-1.compute.internal:http      => ip-10-13-100-73.ap-northeast-1.compute.internal:27698       0B     44B     25B
                                                        <=                                                             0B     33B     18B
ip-10-13-1-101.ap-northeast-1.compute.internal:53696     => ip-10-13-0-2.ap-northeast-1.compute.internal:domain         0B     21B     12B
                                                        <=                                                             0B     31B     17B
ip-10-13-1-101.ap-northeast-1.compute.internal:41975     => ip-10-13-0-2.ap-northeast-1.compute.internal:domain         0B     21B     12B
                                                        <=                                                             0B     31B     17B
-------------------------------------------------------------------------------------------------------------------------------------------
TX:             cum:   1.31MB   peak:    560kB                                                             rates:    560kB   134kB  74.7kB
RX:                     505kB            117kB                                                                      3.69kB  49.8kB  28.1kB
TOTAL:                 1.81MB            564kB                                                                       564kB   184kB   103kB
Item Value
TX (Transmitter) 送信量
RX (Receiver) 受信量
TOTAL iftop 起動からの総量
cum 総量
peak 最大
右端3列 (各トラフィック, rates含む) 2秒、10秒、40秒の転送量平均値

※TX,RX の 「X」 は省略しますよという意味

閲覧し続けると気になる処理があった時には
Shift + P で一旦停止させます。

もう一度開始したい場合は Shift + P です。

実際のCLI

以下見ていただくと白い帯グラフが左から伸びているのが見えるかと思います。
この横棒が一番上のバーの目盛りに相応してぱっと見でどの程度かわかるのが便利です。

f:id:kenzo0107:20171109011640p:plain

DB への接続を確かめる

DB (MySQL) のデフォルトポート 3306 への送受信を調べたいとき

$ sudo iftop -B -P -n -N -f "port 3306"

当然ながら受信の方が大きいです。 f:id:kenzo0107:20171109120917p:plain

補足

実際に負荷が高い時等、特定のインシデントがあった際に追記していこうと思います♪

Reference

toda-tocochan-bus flask on IBM Bluemix へ引っ越し

GCP から IBM Bluemix へ引っ越しました!

toco ちゃんバス あと何分? f:id:kenzo0107:20171029095513p:plain

概要

さくらVPS から GCP
そして今度は GCP から IBM Bluemix に引越ししました。

以前 GCP 運用時の話はコチラ kenzo0107.hatenablog.com

GCP は GKE に LB かましたら価格がバコッと上がってしまい
無料枠を逸脱してしまいました (>_<)

なんとか低価格で運用したいという目論見です。

何故 Heroku でなく IBM Bluemix ?

IBM Bluemix の良い所は機能が充実している所です。
無料・デフォルトで kibana が見れます。

f:id:kenzo0107:20171029101148p:plain

f:id:kenzo0107:20171029101853p:plain

その他 Git との連携も可です。

以下 Mac で作業することを前提に手順まとめました。

事前準備

  • IBM Bluemix に Sign Up しときます

Signup IBM Bluemix

  • clone
macOS%$ git clone https://github.com/kenzo0107/toda-tocochan-bus-on-ibmbluemix
macOS%$ cd toda-tocochan-bus-on-ibmbluemix
  • cloudfoundry の CLI インストール
macOS%$ brew tap cloudfoundry/tap
macOS%$ brew install cf-cli

デプロイ

macOS%$ cf api https://api.ng.bluemix.net
macOS%$ cf login
macOS%$ cf push <application name>
  • API は Region によって変わります。
Region API URL
米国南部 https://api.ng.bluemix.net
英国 https://api.eu-gb.bluemix.net

総評

Cloudfoundry の CLI のお陰で引っ越しも簡単でした♪

セキュリティとして特定 IP やドメインからアクセスさせないとか出来たら
商用のメソッドとして利用出来そうかなと思いました。

その点質問してみましたが2週間ほど連絡がないので再度連絡してみます。
↑質問は英語限定でした!

サポートが強化されると有難いなと思いました。

以上 ご参考になれば幸いです。

CasperJS+PhantomJS で Github Organization 移行

f:id:kenzo0107:20171025214738p:plain

概要

Github Enterprise の Organization 移行を実施した際に CasperJS と PhantomJS でヘッドレスブラウザより操作し移行しました。
Github 上で API がない(はず?)為、この様な対応をしました。

どちらかというと CasperJS+PhantomJS でブラウザ上の試験作りを楽しんでいたこともあり
試してみてすんなりできたので採用した経緯になります。

ヘッドレスブラウザとは?

GUI なしのブラウザを CLI で利用するというもの。
ページ描画や画像ロード、ログインしたりとフロントの試験で期待される機能を持っています。

三行まとめ

  • CasperJS + PhantomJS でログイン認証はじめブラウザ操作で Transfer する工程を実行
  • 移行後、元の URL が移行先にリダイレクトされるか確認
  • 期待する要素が時間内に取得できないときはページをキャプチャ

やってみる

Get Started ご参照ください。

github.com

以下にも手順まとめてます。

Clone

macOS%$ git clone https://github.com/kenzo0107/ghe-org-transfer
macOS%$ cd ghe-org-transfer

scripts/ghe-org-transfer.js の 編集

var config = {
  // site root.
  siteRoot: 'https://<your github domain>',
  // Github Login path
  loginPath: '/login',
  // Github Login Account
  loginParams: {
    email: '<your email>',
    password:  '<your password>'
  },
  viewportSize: {
    width: 3000,
    height: 2500
  },
  paths: [
    "<your owner>/<your repository>"
  ],
  destOrganization: '<your destination of organization>',
  reason: 'transfer this repository to new oragnization',
};

移行イメージ

  • ex) hoge/mywonderfulrepo ---> moge/mywonderfulrepo
paths: [
  "hoge/mywonderfulrepo"
],
destOrganization: 'moge',

paths は複数指定しても問題ありません。

移行実施

macOS%$ make run
  • 実行結果

※ 移行後に元の URL でリダイレクトされるか試験しています。

[url] https://github.aiueo.com/hoge/mywonderfulrepo/settings
[step] fill '#transfer_confirm > form'
[step] input checkbox #team-59
[step] click the button labeled "Transfer"
(^-^) redirect ok:https://github.aiueo.co.jp/hoge/mywonderfulrepo to https://github.aiueo.co.jp/moge/mywonderfulrepo

総評

以前 Grafana のグラフのスナップショットを撮る Grafana API がうまく動作しなかったのも
CasperJS+PhantomJS で取得する様にできました。

いやはや便利♪

全然別件ですが、サイトの認証に利用される reCAPTCHA の突破など挑戦してましたがうまく行かず...
うまくいったぜ!という方、是非教えてください m( )m

WAF+CloudFront でリファラチェック (直リンク禁止)

概要

AWS WAF (Web Application Firewall) を利用し Cloudfront でのリファラ制御を実装しましたのでそのまとめです。

私は直リンク禁止対策として導入しました。

f:id:kenzo0107:20171005180531p:plain

以下手順になります。

Go to AWS WAF ボタンクリック

サービス > WAF & Shield と辿り Go to AWS WAF クリック

f:id:kenzo0107:20171005174955p:plain

Configure Web ACL ボタンクリック

ACL (Access Control List) を設定していきます。

f:id:kenzo0107:20171005180856p:plain

概要確認

特にチェックせず Next ボタンクリック

f:id:kenzo0107:20171005181044p:plain

web ACL 設定

f:id:kenzo0107:20171005181315p:plain

以下、設定項目を設定し、Next ボタンクリック

Item Value
Web ACL name (任意) 例ではCloudfront の CNAME を設定しています。
CloudWatch metric name Web ACL name を入力すると自動で入力される。変更したい場合のみ変更
Region Global(CloudFront) 選択
AWS resource to associate 対象となるCloudfrontを選択する箇所。運用中の Cloudfront を対象とすると場合は後々設定。

条件作成

今回は文字列一致を条件とする為、 String match conditions にて Create condition ボタンクリック

f:id:kenzo0107:20171005181800p:plain

string match condition 作成

f:id:kenzo0107:20171005181926p:plain

以下設定し Add filter ボタンクリック。
複数 filter がある場合、Add filter を繰り返します。

Item Value
Name (任意)
Part of the request to filter on Header
Header Referer
Match type Contains
Transformation Convert to lowercase
Value to match 対象となるドメイン設定


Add filter 後、 Create ボタンクリック。

f:id:kenzo0107:20171005182327p:plain

Next ボタンクリック

追加したもののすぐに反映されていない。 そのまま Next ボタンクリック

f:id:kenzo0107:20171005182446p:plain

ルール作成

Create rule ボタンクリック。

f:id:kenzo0107:20171005182608p:plain

ルールに条件を紐付け

Name, Cloudwatch metric name を設定し
Add conditions で条件を追加します。

その後、Create ボタンクリック。

f:id:kenzo0107:20171005182641p:plain

ルール以外のリクエストのアクセス禁止

やはり Rule は反映されていない。ですが、続けて
Block all requests that don't match any rules をチェックし Review and create ボタンクリック。

※対象のCloudfront に反映させたくない場合は、Cloudfront を選択したリソースを解除する必要があります。
※最後に関連付けができるのでここではするべきではないと思います。

f:id:kenzo0107:20171005182806p:plain

確認ページで入力内容確認後作成

Confirm and create ボタンクリック。

f:id:kenzo0107:20171005183423p:plain

対象の web ACL を編集

WEB ACLs より選択し Edit web ACL ボタンクリック

f:id:kenzo0107:20171005183628p:plain

web ACL 編集

  1. 作成したルールを選択
  2. Add rule to web ACL ボタンクリック
  3. Allow 選択
  4. Update ボタンクリック

f:id:kenzo0107:20171005183720p:plain

Cloudfront 関連付け

Add association ボタンクリック

f:id:kenzo0107:20171005184119p:plain

Web ACL に Cloudfront を関連付け

Resource で 対象の Cloudfront を選択し Add ボタンクリック

f:id:kenzo0107:20171005184153p:plain

以上で数分後 WAF+CloudFront によるリファラチェックが確認できる状態になります。

アクセス確認

自環境では
ローカルの /etc/hosts 修正し対象ドメインから Cloudfront CNAME へのリンクを貼って確認しました。

Cloudfront CNAME ドメインでのリソースを直接アクセスすると
以下の様な エラーページが表示されることが確認できました。

f:id:kenzo0107:20171005184505p:plain

もう少しユーザフレンドリーに

上記のエラーページは Cloudfront > Error Pages で Create Custom Error Response で S3 上のパスを指定することでカスタマイズが可能です。

是非サイトコンセプトに合ったエラーページをご用意されるとよりユーザフレンドリーな配信になるかと思います。

以上
ご参考になれば幸いです。

AWS Elasticsearch Service バージョンアップ 2.2 → 5.5

f:id:kenzo0107:20170924222936p:plain

概要

AWS Elasticsearch Service (ES) 2.3 → 5.5 へバージョンアップを実施に際して
以下記事をまとめました。

大まかな流れ

  1. ESバージョン2.3のドメインからSnapshot取得
  2. ESバージョン5.5のドメイン作成
  3. アプリの fluentd の向け先をESバージョン5.5へ変更
  4. ESバージョン5.5のドメインにデータリストア
  5. ESバージョン2.3のドメイン削除

現状バージョン確認

$ 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 作成

  • ec2 タイプで作成

f:id:kenzo0107:20170924221853p:plain

  • アクセス権限は特に設定せず 「次のステップ」ボタンクリック

f:id:kenzo0107:20170925113614p:plain

  • ロール名を es-index-backups とし作成

f:id:kenzo0107:20170925113908p:plain

ロールARN arn:aws:iam:::role/es-index-backups で作成されていることが確認できる

f:id:kenzo0107:20170925114402p:plain

  • 信頼関係の編集

f:id:kenzo0107:20170925114635p:plain

Service を es.amazonaws.com に編集

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "es.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

IAM User 作成

  • ユーザ > ユーザ追加 選択

f:id:kenzo0107:20170925114822p:plain



  • ユーザ名 es-index-backup-user とし プログラムによるアクセスにチェックを入れて 次のステップ クリック

f:id:kenzo0107:20170925115200p:plain



  • 特にポリシーをアタッチせず 次のステップ クリック

f:id:kenzo0107:20170925115357p:plain

  • es-index-backup-user を作成し独自ポリシーで先ほど作成した role へのアクセス許可設定をアタッチします。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:PassRole"
            ],
            "Resource": "arn:aws:iam::<Account ID>:role/es-index-backups"
        }
    ]
}


  • 発行されたアクセスキー、シークレットアクセスキーをメモしておきます。

f:id:kenzo0107:20170925120635p:plain

S3 バケット作成

S3 > バケットを作成する でバケット作成してください。

Elasticsearch にてスナップショットリポジトリ作成

スナップショットを管理するリポジトリを Elasticsearch に作成する必要があります。

Elasticsearch へのアクセス可能なサーバにて以下スクリプト実行します。

  • register_es_repository.py
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
$ chmod +x register_es_repository.py

$ python register_es_repository.py

// 成功
{"acknowledged":true}

リポジトリ登録完了しました。

Snapshot 取得

snapshot 名を 20170926 とします。

$ curl -XPUT "https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926"

// 成功
{"accepted":true}

Snapshot 一覧

20170926 という snapshot 名で取得したことが確認できます。

$ 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 メソッドを実行します。

$ curl -XDELETE https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926

// 成功
{"acknowledged":true}

S3 確認

以下が作成されているのがわかります。

  • indices/*
  • meta-*
  • snap-*

はじめ meta- が作成できたら完了なのかなと思いきや
snap-
も作られるまで待つ必要がありました。

  • CLI 上でスナップショット完了確認した方が確実です。
$ 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 部分を新規ドメインに修正します。

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
$ chmod +x register_es55_repository.py

$ python register_es55_repository.py

// 成功
{"acknowledged":true}

スナップショットからリストア

20170926 のスナップショットをリストアします。

$ curl -XPOST "https://<Elasticsearch 5.5 Endpoint Domain>/_snapshot/index-backups/20170926/_restore"

// 成功
{"accepted": true}

リストア確認

$ curl -XGET "https://<Elasticsearch 5.5 Endpoint Domain>/_cat/indices"

スナップショットに失敗するケース

  • .kibana index が既に存在しており、リストアできない。
{
    "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
}

対応策

curl -XPOST https://<Elasticsearch 5.5 Endpoint Domain>/_snapshot/index-backups/20170926/_restore -d '{
    "indices": "nginx-*"
}' | jq .

indices を用い、スナップショット内のインデックスの中からマッチする正規表現のみをリストアできます。

自身ではこの様な解決法を実施し回避できました。
その他良い方法があれば御指南いただけますと幸いです。

ちなみに

f:id:kenzo0107:20171002144856p:plain

Terraform で ES 2.2 → 5.5 バージョンアップを実施した所
1時間以上経過してようやくアップデートが完了しました。

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 を削除する方法が一番確実だなと思いました。

データ分析基盤構築入門[Fluentd,Elasticsearch,Kibanaによるログ収集と可視化]

データ分析基盤構築入門[Fluentd,Elasticsearch,Kibanaによるログ収集と可視化]

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

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

  • 作者: Rafal Kuc (lにストローク符号、cにアクサン・テギュ付く),Marek Rogozinski (nにアクサン・テギュ付く)
  • 出版社/メーカー: KADOKAWA / アスキー・メディアワークス
  • 発売日: 2014/03/25
  • メディア: Kindle版
  • この商品を含むブログ (3件) を見る

docker-comopse で Rails 5 (Puma) + Nginx + Mysql 構築 on Vagrant(Ubuntu)

f:id:kenzo0107:20170708204516p:plain

自身の Rails 開発環境の雛形として利用している docker-compose です。

github.com

以下設定手順です。

Vagrant 起動

macOS%$ git clone https://github.com/kenzo0107/vagrant-docker
macOS%$ cd ./vagrant-docker/
macOS%$ vagrant up
macOS%$ vagrant ssh

Rails プロジェクト作成

// on vagrant
vagrant%$ cd /vagrant/rails-puma-nginx-mysql
vagrant%$ docker-compose run --rm web rails new . --force --database=mysql --skip-bundle

puma 設定ファイルセット

vagrant%$ cp puma.rb ./rails/config/
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port        ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart

app_root = File.expand_path("../..", __FILE__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"

データベース設定ファイルセット

vagrant%$ cp database.yml ./rails/config/
  • ./rails/config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>  # <--- MYSQL_ROOT_PASSWORD
  host: db # <--- service name

データベース作成

vagrant%$ docker-compose run --rm web rails db:create
Created database 'app_development'
Created database 'app_test'

vagrant%$ docker-compose exec db mysql -u root -p -e'show databases;'
Enter password: (password)
+--------------------+
| Database           |
+--------------------+
| information_schema |
| app_development    | <--- add !
| app_test           | <--- add !
| mysql              |
| performance_schema |
| sys                |
+--------------------+

以上で必要最低限の Rails プロジェクトの準備ができました!

Rails, Nginx, MySQL 全コンテナ起動

vagrant%$ docker-compose up -d

ブラウザより http://192.168.35.101 へアクセスし
Rails トップページが表示されることが確認できます。

f:id:kenzo0107:20170913132149p:plain

総評

docker でコンテナ化しているので Nginx, MySQL 等、
バージョンアップしたい時でもコンテナを置き換えるだけで簡単に使用感を確認できたり
機能を確認できたりと便利です。

これに Elasticsearch + Kibana でログを可視化したり
Mailcatcher でメール送信を確認できるようにしたりと
開発するには十分な状況が用意できます。

是非開発の一助になれば幸いです。

パーフェクト Ruby on Rails

パーフェクト Ruby on Rails