Google Compute Engine 入門 - Elasticsearch クラスタを10分で立ち上げよう

はじめに
------------

これは [Elasticsearch Advent Calendar](http://qiita.com/advent-calendar/2014/elasticsearch) 9日目の記事です。
分散環境を簡単に構築できる Google Compute Engine (GCE) を使って Elasticsearch クラスタを立ち上げる手順を紹介します。GCE は初回登録後から「60 日間有効な $300 分のクレジット」が利用できるので、まだ登録していない方はこの機にぜひお試しください。

対象読者

* Elasticsearch のセットアップをしたことがある
* Elasticsearch クラスタを作ったり壊したりして気軽に遊びたい
* ローカル PC の中で VM を何台も立ち上げるのはツライ
* Google Compute Engine なにそれおいしいの？

[Google Compute Engine](https://cloud.google.com/compute/) とは
------------------------------

「Google が利用しているインフラと同一のインフラをユーザ向けに提供」するGoogle Cloud Platform の 1 サービスで、Amazon EC2 のように仮想マシンを簡単に作ったり壊したりすることができます。

AWS、EC2 との違いは下記の記事等をご覧ください。
[よしづみぶろぐ: AWSよりGoogle Compute Engineを選びたくなる10の理由](http://yoshidumi.blogspot.jp/2014/01/awsgoogle-compute-engine10.html)

僕自身の AWS 使用経験はチュートリアルレベルですが、AWS に比べて GCE の UI は非常にシンプルで、英語のドキュメントしかない現状でもすんなり導入することができた印象があります。

用語
---------

今回出てくる用語の簡単な紹介。

* インスタンス (Instance)
 * GCE で動く仮想マシン。OS イメージやディスク、ネットワーク等を設定して作成する。使い終わったら削除する（インスタンスが生存していると課金対象となる）
* インスタンステンプレート (Instance Template)
 * インスタンス（グループ）を生成するひな形の設定
* インスタンスグループ (Instance Group)
 * インスタンステンプレートを元に任意の個数のインスタンスを一括管理（作成、削除）する
* タグ
 * ファイアウォールのルールをインスタンスに適用するための名前。ルールにタグ名を割り当て、インスタンスにそのタグを付与することで、ファイアウォールの設定（開放するポート）を適用することができる
* コンソール (Console)
 * GCE を含む Google Cloud Platform の Web UI
* プロジェクト (Project)
 * 関連するインスタンスやネットワーク設定を入れておく入れ物

構築の流れ
---------------

1. プロジェクトの作成
2. ファイアウォールのルール作成
3. インスタンステンプレートの作成
4. インスタンスグループの作成
5. elasticsearch-head の確認

プロジェクトの作成
---------------------

GCE の登録が完了すると、下図のようにプロジェクト管理画面が表示されるはずです。初期状態では空になっていると思うので、「プロジェクトを作成」ボタンを押してプロジェクトを作成しましょう。プロジェクトID は API や SDK から操作する際に使用するので、わかりやすい値にしましょう。ただし、全ユーザ・全プロジェクト間でユニークな文字列である必要があります。ここではデフォルトで用意された文字列にしました。

* プロジェクト名: `elasticsearch`
* プロジェクトID: `linen-setting-788`

![gce-create-project.png](https://qiita-image-store.s3.amazonaws.com/0/3284/94937dfe-bc58-4c9c-6c15-474b53108ab5.png)

ファイアウォールのルール追加
--------------------------

Elasticsearch サーバはデフォルトで 9200 番ポートでアクセスを待ち受けます。今回はグローバルネットワークから GCE 上にある Elasticsearch に直接アクセスするため、このポートを開放する必要があります。GCE では http (80番ポート) は簡単に開放できるようになっていますが、それ以外は特に用意されていないため、まずファイアウォールの設定を追加します。

![gce-network.png](https://qiita-image-store.s3.amazonaws.com/0/3284/46b3ee39-bac9-4c3a-c244-213fe12dc51c.png)

ここでは、ネットワーク内で利用可能なファイアウォールのルールを管理できます。`default-allow-http` という名前のルールはグローバルネットワークからの `tcp:80` に対するアクセスを許可しています。ルールにはタグを付けることもでき、このルールには `http-server` というタグが割り当てられています。インスタンスに `http-server` というタグを付与することで、ルールをインスタンスに適用することができます。
ここでは下記のようなルールを作成します。グローバルネットワークから `tcp:9200` へのアクセスを許可し、`elasticsearch-server` というタグを割り当てます。

* 名前
 * `allow-elasticsearch`
* ソースIPの範囲
 * `0.0.0.0/0`
* プロトコルとポート
 * `tcp:9200`
* ターゲットタグ
 * `elasticsearch-server`

![gce-create-firewall-rule.png](https://qiita-image-store.s3.amazonaws.com/0/3284/c49882dc-e17b-6427-5f49-9721502c7d95.png)


インスタンステンプレートの作成
----------------------------------

次に、今回 Elasticsearch をインストールするインスタンスのひな形になるテンプレートを作成していきます。

>テンプレートの作成の前に一度「VM インスタンス → 新しいインスタンス」の手順を踏んで 1 台だけのインスタンスを生成してみることをおすすめします。インスタンス生成とテンプレートの作成はどちらも設定できる項目がほぼ共通なので、その後の理解も深まるはずです。

![gce-template.png](https://qiita-image-store.s3.amazonaws.com/0/3284/cb661d3c-9bee-2979-04d2-42f1763d56cf.png)

設定項目の一覧を先に記載しておきます。

* テンプレート名
 * `elasticsearch-template-1`
* メタデータ（スタートアップスクリプト）
 * key: `startup-script-url`
 * value: `https://gist.githubusercontent.com/tomoemon/4f1042f8fccf02efd52a/raw/gistfile1.sh`
* タグ（ファイアウォール）
 * `elasticsearch-server`
* マシンタイプはお好みで
* ブートイメージ
 * `backports-debian-7 ...`
* プロジェクトへのアクセス（権限）
 * 計算処理：「読み取り/書き込み」

![gce-create-template-1.png](https://qiita-image-store.s3.amazonaws.com/0/3284/733e696c-3e8a-c241-0868-1408eea4c8bf.png)

1. 詳細の表示を行います
2. テンプレートの名前を指定します
3. インスタンス内からアクセスできるメタデータを設定します。ここでは特別な値である `startup-script-url` として gist にある elasticsearch 構築スクリプトを渡しています（構築スクリプトについては後述）。この URL 内のテキストをシェルスクリプトとして解釈して起動時に実行します

![gce-create-template-2.png](https://qiita-image-store.s3.amazonaws.com/0/3284/38be320f-3248-4103-c30b-da7b2c9dc413.png)

1. 先ほど作成したファイアウォールの設定を追加します。`elasticsearch-server` タグを付与することで、tcp:9200 番ポートを開放します
2. マシンタイプはお好みでどうぞ。スペックが高いほど単位時間あたりの金額は上がりますが、無料枠はそう簡単になくならないので最もハイスペックなものを選んでみるのもよいでしょう
3. OSのイメージを選択できます。Ubuntu、CentOS や RHEL 等を選ぶことができますが、ここでは debian を選択しましょう

![gce-create-template-3.png](https://qiita-image-store.s3.amazonaws.com/0/3284/fbf8c4bd-385c-3d29-687f-f7a39e8c7e33.png)

1. 最後に、Elasticsearch がクラスタ内のノードを発見するために、インスタンス内からプロジェクトの情報を取得するAPI の権限を付与します
2. 入力が完了したら「作成」ボタンを押しましょう

インスタンスグループの作成
--------------------------

ここまでくればあとはインスタンスをまとめて作るだけです。
インスタンスグループの管理画面を開きましょう。

![gce-instance-group.png](https://qiita-image-store.s3.amazonaws.com/0/3284/d24e4c6c-3f50-de9c-8fac-f85b7d80173c.png)

![gce-create-group.png](https://qiita-image-store.s3.amazonaws.com/0/3284/b74cd02d-ba3a-ad27-51b8-cce694f385e4.png)


設定項目は

* インスタンスグループの名前
* ゾーン（データセンターの場所）
 * 日本に住んでいる場合は `asia-east1-a` 等アジアが良いでしょう
* インスタンステンプレート
 * 先ほど作成した `elasticsearch-template-1` を選択します
* インスタンスの数
 * 大量に作りたいところですが、無料体験中はわりと厳しい上限があるので、3 インスタンス程度にしておきます

「作成」ボタンを押せば、インスタンスの構築とスタートアップスクリプトの実行（Elasticsearch のインストール）が開始されます。

elasticsearch-head
-----------------------

インスタンスグループの生成が完了すると、`elasticsearch-group` というグループを選択できるようになります。早速クリックしてグループの情報を見てみましょう。

![gce-instance.png](https://qiita-image-store.s3.amazonaws.com/0/3284/6cdae75b-f395-2075-7011-8484a891ced5.png)


画面上部には CPU 使用率等のグラフが、下にはグループ内のインスタンスの一覧が表示されています。どれか適当に一つの IP アドレスをコピーして、下記の URL でブラウザで開いてみましょう。

`http://<IP_ADDRESS>:9200/_plugin/head`

みなさんよくご存知の head が開けたはずです。
（開けなかった場合は、IP アドレスの右側にある SSH ボタンを押して、インスタンスの中で Elasticsearch が稼働しているか確認してみてください）

![gce-elasticsearch.png](https://qiita-image-store.s3.amazonaws.com/0/3284/1fe24c9e-be29-e5b3-43ee-32af707d2520.png)

以上で、Elasticsearch クラスタの構築は完了です。データが何も入っていませんが、ここから先は読者のみなさんの方が詳しいと思うのでお任せします。

スタートアップスクリプトについて
--------------------------------

https://gist.github.com/tomoemon/4f1042f8fccf02efd52a

スタートアップスクリプトはたかだか30行程度のシェルスクリプトで、前半は最低限の Elasticsearch セットアップ、後半は [GCE Cloud Plugin for Elasticsearch](https://github.com/elasticsearch/elasticsearch-cloud-gce) の Discovery （Elasticsearch ノード探索のための）設定です。
plugin のインストール手順でプロジェクトID と Zone を設定するようにと書いてありますが、ここでは API 経由で両者の値を取得して設定しています。インスタンス内からであれば認証無しで所属するプロジェクトやインスタンスに関する情報を取得できるので、今回のように構成が単純な場合はセットアップを自動化できます。

おしまい
-------------------

今回はかなり駆け足で Google Compute Engine を紹介しました。周りではまだ使っている方が多くないかもしれませんが、簡単に使うことができるのでぜひお試しください。

慣れてきたら Google Cloud SDK でさらなる自動化にもチャレンジしてみてください。

そして最後に忘れてはならないこと。

![gce-delete-instance-group.png](https://qiita-image-store.s3.amazonaws.com/0/3284/4d37cdac-ceb3-9d99-db66-4c94a1c005fd.png)

インスタンスグループを削除してから寝ましょう。