Running Kubernetes Cluster on AWS

Following this guide https://kubernetes.io/docs/getting-started-guides/kops/, set up Kubernetes cluster on AWS using kops.

1. Install kops

According to the guide, kops is:

kops helps you create, destroy, upgrade and maintain production-grade, hig… 続きを読む

ElasticseharchのEC2 Discovery Pluginでクラスタ組むのが捗るはなし

こんばんはー

今回、ElasticsearchのクラスタをAWS上に組む際に便利なブラグインを使ってみたいと思いますー
その名も「EC2 Discovery Plugin」☆彡

調べているとAWS Cloud Pluginの使い方を書いている人は結構いるのですが、5系から提供されているEC2 Discovery Pluginはあんまいないのかなーって思いました。
なので、EC2 Discovery Pluginについてつらつら書きたいと思います( ゚Д゚)ゞビシッ

そもそもEC2 Discovery Pluginは何が便利なん?

Elasticsearchのデフォルトで用意されているZen Discoveryを利用してクラスタを組む際は、Unicastでホスト名やIPアドレス指定で組みます。
ただ、クラウド上の運用を考えるとUnicastはつらい。。
そこで、EC2 Discovery Pluginを使うとSecurityGroupを元にクラスタが組まれるのですー(d゚ω゚d)オゥイェー
Multicast Discovery pluginというのもあったのですが、5系から廃止されました

早速ですが、構成の説明したら実装方法を説明したいと思いますー

インスタンス構成

  • InstanceType:t2.medium
  • OS:Amazon Linux AMI release 2017.03
  • Node: 3台
  • ClusterName: es-cluster

こんな感じの流れで書いちゃいますー

  1. AWS準備

  2. Install Oracle JDK 1.8

  3. Install Elasticsearch

  4. Install Kibana(1台のみ)

  5. Install X-pack Elasticsearch & kibana(1台のみ)

  6. Install EC2 Discovery Plugin

  7. 動作確認

AWS準備

SecurityGroup

ElasticsearchをインストールするインスタンスにアタッチするSecurityGroupです。
ソースは、環境に合わせて設定してください。

Type Protocol Port Source Description
Custom TCP 9200 xx Elasticsearchアクセスポート
Custom TCP 9300 xx ノード間のコミュニケーションポート
Custom TCP 5601 xx KibanaのHTTP用ポート
Custom TCP 22 xx SSH用ポート

IAM Role

以下のPolicyを作成し、インスタンスにアタッチしているIAM RoleにPolicyをアタッチしてください。

{
    "Statement": [
        {
            "Action": [
                "ec2:DescribeInstances"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ]
        }
    ],
    "Version": "2012-10-17"
}

AWS Configure

サーバにログインしたらAWS Configureの実行をします。
Access KeyとSecret keyは利用しないため、何も入力しません。

$ aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]: json

下準備が終わったので、ここからElasticsearch周りを進めたいと思いますー

Install Oracle JDK 1.8

$ java -version
java version "1.7.0_141"
OpenJDK Runtime Environment (amzn-2.6.10.1.73.amzn1-x86_64 u141-b02)
OpenJDK 64-Bit Server VM (build 24.141-b02, mixed mode)

### Install Java1.8
$ sudo yum -y install java-1.8.0-openjdk-devel

### alternativesコマンドでJavaのバージョンを切り替える
$ sudo alternatives --config java

There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java

Enter to keep the current selection[+], or type selection number: 2

### バージョン確認
$ java -version
openjdk version "1.8.0_141"
OpenJDK Runtime Environment (build 1.8.0_141-b16)
OpenJDK 64-Bit Server VM (build 25.141-b16, mixed mode)

Install Elasticsearch

Elasticsearch5.5.1を入れちゃいたいと思いますー

Install Elasticsearch

### PGP Keyをダウンロード&インストール
$ sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch

### リポジトリの登録
$ sudo vim /etc/yum.repos.d/elastic.repo
[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

### Elasticsearchインストール
$ sudo yum -y install elasticsearch

### サービス起動登録
$ sudo chkconfig --add elasticsearch

### 確認
$ sudo chkconfig --list | grep elasticsearch
elasticsearch   0:off   1:off   2:on    3:on    4:on    5:on    6:off

### elasticsearch.yml設定変更
$ sudo vim /etc/elasticsearch/elasticsearch.yml
+ cluster.name: es-cluster
+ network.host: 0.0.0.0
+ http.port: 9200

### サービス起動
$ sudo service elasticsearch start
Starting elasticsearch:                                    [  OK  ]

### 起動確認
$ curl http://localhost:9200
{
  "name" : "fDpNQ4m",
  "cluster_name" : "es",
  "cluster_uuid" : "mayxoDENThSmrUltkXyRWg",
  "version" : {
    "number" : "5.5.1",
    "build_hash" : "19c13d0",
    "build_date" : "2017-07-18T20:44:24.823Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.0"
  },
  "tagline" : "You Know, for Search"
}

Install Kibana

モニタリングしたいのでKibana5.5.1をインストールします。

### Install Kibana
$ sudo yum install -y kibana
### サービス登録
$ sudo chkconfig --add kibana
$ chkconfig --list | grep kibana
kibana          0:off   1:off   2:on    3:on    4:on    5:on    6:off
### Kibana設定
$ sudo vim /etc/kibana/kibana.yml
+ server.host: 0.0.0.0
+ elasticsearch.url: "http://ES_IP_ADDR"
### サービス停止状態のままにしておきます(X-Pack入れたあとに設定変更後に起動します)
$ service kibana status
kibana is not running

Install X-Pack on Elasticsearch

Elasticsearchのノード状態などをモニタリングしたいため、X-Pack5.5をインストールします。

Install X-Pack on Elasticsearch

$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install x-pack
-> Downloading x-pack from elastic
[=================================================] 100%  
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.io.FilePermission \.pipe* read,write
* java.lang.RuntimePermission accessClassInPackage.com.sun.activation.registries
* java.lang.RuntimePermission getClassLoader
* java.lang.RuntimePermission setContextClassLoader
* java.lang.RuntimePermission setFactory
* java.security.SecurityPermission createPolicy.JavaPolicy
* java.security.SecurityPermission getPolicy
* java.security.SecurityPermission putProviderProperty.BC
* java.security.SecurityPermission setPolicy
* java.util.PropertyPermission * read,write
* java.util.PropertyPermission sun.nio.ch.bugLevel write
* javax.net.ssl.SSLPermission setHostnameVerifier
See http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
for descriptions of what these permissions allow and the associated risks.

Continue with installation? [y/N]y
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@        WARNING: plugin forks a native controller        @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
This plugin launches a native controller that is not subject to the Java
security manager nor to system call filters.

Continue with installation? [y/N]y
-> Installed x-pack

動作確認するのですが、Securityが有効になったため、エラーが返ってきます。
なので、今回は、Securityを無効にします。
(モニタリング用途で使いたいだけなので―)

ちなみに、X-Packについては、クラスメソッドさんが詳しく書いてますー
クラスメソッド:Elastic Stack X-Pack

X-Pack Security無効化

無効化することで、レスポンスが返ってきます。

### Security無効化
$ vim /etc/elasticsearch/elasticsearch.yml
+ xpack.security.enabled: false

### 動作確認
$ curl -u elastic http://localhost:9200
{
  "name" : "fDpNQ4m",
  "cluster_name" : "es",
  "cluster_uuid" : "mayxoDENThSmrUltkXyRWg",
  "version" : {
    "number" : "5.5.1",
    "build_hash" : "19c13d0",
    "build_date" : "2017-07-18T20:44:24.823Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.0"
  },
  "tagline" : "You Know, for Search"
}

### 再起動
$ service kibana restart
kibana stopped.
kibana started

Install X-Pack on Kibana

KibanaのX-Pack5.5もインストールします。

Install X-Pack on Kibana

$ sudo /usr/share/kibana/bin/kibana-plugin install x-pack
Attempting to transfer from x-pack
Attempting to transfer from https://artifacts.elastic.co/downloads/kibana-plugins/x-pack/x-pack-5.5.1.zip
Transferring 119276972 bytes....................
Transfer complete
Retrieving metadata from plugin archive
Extracting plugin archive
Extraction complete

Install EC2 Discovery Plugin

ここからEC2 Discovery Pluginをインストールします。
やっとここまできましたね!

$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install discovery-ec2
-> Downloading discovery-ec2 from elastic
[=================================================] 100%  
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.lang.RuntimePermission accessDeclaredMembers
* java.lang.RuntimePermission getClassLoader
See http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
for descriptions of what these permissions allow and the associated risks.

Continue with installation? [y/N]y
-> Installed discovery-ec2

Elasticsearch.ymlに設定します。

$ sudo vim /etc/elasticsearch/elasticsearch.yml
cluster.name: es-cluster
discovery.zen.hosts_provider: ec2
discovery.ec2.groups: "SECURITY_GROUP_NAME" or "SECURITY_GROUP_ID"
discovery.ec2.availability_zones: [ "ap-northeast-1a", "ap-northeast-1c" ]
cloud.aws.region: ap-northeast-1

### サービス再起動
service elasticsearch restart

### クラスタ状態確認
$ curl http://localhost:9200/_cluster/health?pretty
{
  "cluster_name" : "es-cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 0,
  "active_shards" : 0,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

2台目&3台目いくよ!!

2台目も上記と同じで設定を実施しますので割愛しちゃいますm(_ _)m
SecurityGroupは、1台目と同じのを使ってください。
また、ElasticsearchのX-Packは、3台すべてに入れてください。
Kibanaは、インストールしないです。

もろもろ設定して、Elasticsearchを再起動するとログにクラスタが組み込まれたことがわかります。

クラスタに組み込まれているかをログから確認

### Master側のログ
[20xx-xx-xxxx:xx:xx][INFO ][o.e.c.s.ClusterService   ] [fDpNQ4m] added {{gdRR6r1}{gdRR6r17T5iaGPmaO9wgTA}{6l3QNArhSkyBVu08jTfwYQ}{IP_ADDR}{IP_ADDR:9300},}, reason: zen-disco-receive(from master [master {dKgmQfLLg}{IP_ADDR}{IP_ADDR:9300} committed version [15]])

### Node側のログでマスタを検出したことがわかる
$ tail -f /var/log/elasticsearch/es.log
[20xx-xx-xxxx:xx:xx][INFO ][o.e.c.s.ClusterService   ] [gdRR6r1] detected_master {dKgmQfL}{dKgmQfLASM-35x0X0ulSXg}{XE4jgXEzQwqgkSfRypgoLg}{IP_ADDR}{IP_ADDR:9300}, added {{fDpNQ4m}{fDpNQ4mrRR2vN7wiTVjfIg}{aqPbmbhbTkm1X40gH1tylw}{IP_ADDR}{IP_ADDR:9300},{dKgmQfL}{dKgmQfLASM-35x0X0ulSXg}{XE4jgXEzQwqgkSfRypgoLg}{IP_ADDR}{IP_ADDR:9300},}, reason: zen-disco-receive(from master [master {dKgmQfL}{dKgmQfLASM-35x0X0ulSXg}{XE4jgXEzQwqgkSfRypgoLg}{IP_ADDR}{IP_ADDR:9300} committed version [15]])

Kibanaのモニタリングで確認するよ

Kibana [http://KIBANA_IP_ADDR:5601] にアクセスします。

「Monitoring」をクリックし、ElasticsearchにNodeが3台あることがわかりますね。
ステータス:Green

kibana01.png

「Nodes」をクリックし、Nodeの状態を確認できます。

kibana02.png

無事にクラスタを組むことができましたヽ(*゚д゚)ノ

補足#01

AWS Configureの設定とIAM Roleにポリシーをアタッチしないと以下のエラーがでます。
ちなみに、作成したクラスタ名でログが作成されちゃいます。

$ sudo /var/log/elasticsearch/es-cluster.log
[20xx-xx-xxxx:xx:xx][INFO ][o.e.d.e.AwsEc2UnicastHostsProvider] [node_id] Exception while retrieving instance list from AWS API: Unable to execute HTTP request: connect timed out

補足#02

既に存在しているNodeIDのAMIから起動すると、NodeIDがかぶっているためクラスタに組み込むことができないです。。
その際のログが以下です。

### AMIから起動したノード
$ tail -f /var/log/elasticsearch/es.log
[20xx-xx-xxxx:xx:xx][INFO ][o.e.d.z.ZenDiscovery     ] [gdRR6r1] failed to send join request to master [{fDpNQ4m}{fDpNQ4mrRR2vN7wiTVjfIg}{eHfV5HLkRrKo8_FXfgyHDA}{IP_ADDR}{IP_ADDR:9300}{ml.enabled=true}], reason [RemoteTransportException[[fDpNQ4m][IP_ADDR:9300][internal:discovery/zen/join]]; nested: IllegalArgumentException[can't add node {gdRR6r1}{gdRR6r17T5iaGPmaO9wgTA}{hzzXQXB8TM-xQVn9Uj8e2A}{IP_ADDR}{IP_ADDR:9300}{ml.enabled=true}, found existing node {gdRR6r1}{gdRR6r17T5iaGPmaO9wgTA}{9pWjYpL5Tq23yIte7WzMiw}{IP_ADDR}{IP_ADDR:9300}{ml.enabled=true} with the same id but is a different node instance]; ]

さいごに

EC2 Discovery Pluginいかがでしたか?
簡単にクラスタを組むことができたんじゃないかなと思います。

ただ、個人的には、運用を考えると自動復旧できる構成にする必要があると思ってます。
今の状態だとElasticsearchのクラスタ化する時にNodeIDがかぶっちゃうので、AMIからの自動復旧がむずかしい状態です。
なので、Elasticsearchをインストールする前のAMIからプロビジョニングして、クラスタに組み込む必要があるかなと。
(Elasticsearchインストール時にNodeIDが振られる)

うーん。。NodeIDを変更する方法が他にあればいいのですが、誰か知っている人いたら教えてくださいm(_ _)m

てことで、今回は、ElasticsearchのプラグインのEC2 Discovery Pluginについて書かせて頂きました。
ありがとうございましたー

続きを読む

AWSのチュートリアル 〜Analyze Big Data with Hadoop編〜

AWSのチュートリアルの日本語メモ

はじめに

最近業務でAWS上に構築したHiveを利用するのですが、より理解を深めたいと思い、今回はAWSのチュートリアルを利用して、Hadoop + Hive環境を1から構築してみました。

チュートリアルの内容

Step1: Set Up Prerequisites for Your Sample Cluster

Sign Up for AWS

以前登録していたため、今回はスキップ

Create an Amazon S3 Bucket

S3とは、データを保存するサービス、詳しい内容はここ
以前に利用したことがあったのでここもスキップ

Create an Amazon EC2 Key Pair

EC2とは、Amazonが提供してくれているWEBサーバ、詳しくはここ
sshでログインするために、key pairを発行する必要がある。
今回はここのサイトを参考に、以前作成したkey-pairを利用。

  • EC2のコンソールページのネットワーク&セキュリティタブのキーペアをクリック
  • 上のキーペアのインポートをクリック
  • key-pairの名前とkey-pair.pubの中身をペーストして登録

Step2: Launch Your Sample Amazon EMR Cluster

Launch the Sample Cluster

EMRのクラスタを作成する。EMRとは、AWS上でHadoopを使用するためのサービス。
詳しくはここを参照

  • EMRのコンソールページに移動
  • クラスターの作成をクリック
  • EC2キーペアの部分で、先ほど登録したkey-pairを指定する
  • クラスターの作成をクリック

Step3: Prepare Your Sample Data and Script

ここでは提供されているサンプルログデータとサンプルhiveコードの説明

Sample Data Overview

サンプルのログデータは、s3://[region].elasticmapreduce.samplesに格納されているらしい。
ただし、[region]には自分が使用しているリージョン名が入る。

Sample Hive Script Overview

Hiveのサンプルコードはs3://[region].elasticmapreduce.samples/cloudfront/code/Hive_CloudFront.qにある。
記録されているコードは以下の通り

Hive_CloudFront.q
-- Summary: This sample shows you how to analyze CloudFront logs stored in S3 using Hive

-- Create table using sample data in S3.  Note: you can replace this S3 path with your own.
CREATE EXTERNAL TABLE IF NOT EXISTS cloudfront_logs (
  DateObject Date,
  Time STRING,
  Location STRING,
  Bytes INT,
  RequestIP STRING,
  Method STRING,
  Host STRING,
  Uri STRING,
  Status INT,
  Referrer STRING,
  OS String,
  Browser String,
  BrowserVersion String
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
  "input.regex" = "^(?!#)([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+[^(]+[(]([^;]+).*%20([^/]+)[/](.*)$"
) LOCATION '${INPUT}/cloudfront/data';

-- Total requests per operating system for a given time frame
INSERT OVERWRITE DIRECTORY '${OUTPUT}/os_requests/' SELECT os, COUNT(*) count FROM cloudfront_logs WHERE dateobject BETWEEN '2014-07-05' AND '2014-08-05' GROUP BY os;

CREATE EXTERNAL TABLE table-name ... LOCAL data-pathはdata-pathにあるファイルを新しく作成したテーブルtable-nameにinsertするコード。

INSERT DIRECTORY path SELECT ...は、s3上のpathにselect以下の結果を出力するコード。

Step4: Process Your Sample Data By Running a Hive Script

ここからは作成したEMR上でhiveのコードを実行していく。

Submit the Hive Script as a Step

  • EMRのコンソール画面を開く
  • クラスターリストの中から、先ほど起動したクラスターを指定する。
  • ステップの追加をクリックする。
  • ステップタイプをhive programにする
  • スクリプトs3の場所に、s3://[region].elasticmapreduce.samples/cloudfront/code/Hive_CloudFront.qを指定する。
  • S3 の場所の入力に、s3://[region].elasticmapreduce.samplesを指定
  • 引数に-hiveconf hive.support.sql11.reserved.keywords=falseを記述(予約語と同じ列名を許可するためのオプション)
  • 追加をクリック

実行されたsqlはSELECT os, COUNT(*) count FROM cloudfront_logs WHERE dateobject BETWEEN '2014-07-05' AND '2014-08-05' GROUP BY osで、2014-07-05から2014-08-05期間のosの種類を集計するというもの。

出力されたファイルは

Android 855
Linux 813
MacOS 852
OSX 799
Windows 883
iOS 794

Step5

最後はシャットダウンするための処理、これを忘れると永遠に課金され続ける・・・

To terminate your Amazon EMR cluster

  • EMRのコンソール画面を開く
  • コンソールリストから起動中のコンソールを選択
  • 上の削除ボタンを押す

最後に

今回はAWSのチュートリアルページの内容をそのまま実行しました。

自分でhqlファイルを書いて、s3上にアップロードして実行すると自分のしたい処理が出来たり、sshでemrのマスタノードに入り、hiveを実行することでインタラクティブに操作することもできます。

時間のある時に、AWSの勉強を続けていきたいと思います。

続きを読む

JAWSUG HPC: AWS Batch x OpenFoam HandOn

JAWSUG HPC支部 第10回勉強会 AWS Batch x OpenFoam Hand-On
https://jawsug-hpc.connpass.com/event/61919/

元ネタ:http://qiita.com/porcaro33/items/0b6cf3e2c2a0f88fc305

OpenFoam x AWS Batch ハンズオン環境
image

1. Build Infrastructure

Prerequisites

まずはAWSにログイン https://console.aws.amazon.com/
Oregonリージョンに移動、ログインしたユーザがEC2, S3, Batch, ECR, Cloudformation, IAM等を操作できる権限であることを確認してください。

Create KeyPair

Bastion Serverにアクセスするのに使用するKeyPairを作成します。
後ほどCloudFormationを実行するときにKeyNameを入力するのでメモしといてください。

AWS Console -> EC2 -> Key Pairs -> Create Key Pair -> Enter key name -> Create
image

Run CloudFormation

Docker Imageのビルド環境としてUbuntuサーバをAWS上にたてます。このハンズオンではCloudFormationで必要な環境を構築してしまいます。
– VPC
– Subnet
– SecurityGroup
– Bastion EC2 (Ubuntu16.06)
– SpotFleet Role
– AWS Batch Role
– Batch Job Role
– S3 Bucket
– Container Repo

CloudFormationテンプレートをGithubからダウンロード
https://raw.githubusercontent.com/porcaro33/openfoam-docker/master/aws_batch_base.yml

CloudFormation -> Create New Stack -> Choose File -> Next
image

Enter Stack Name and KeyPair Name -> Next
image

Next -> checkin at “I acknowledge that AWS CloudFormation…” -> Create
image

CloudFormaitonが収束したら、Outputsを見てください。ここの情報をBatch Jobを設定するスクリプト編集するときに使います。このBrowser Tabは残しておいてください。
image

2. Docker Build and Push

Bastion Server

CloudFormationで作成したUbuntuサーバにログインします。お好きなssh clientでログインしてください。ユーザ名は”ubuntu”です。

ssh -i <path_to_keypair> ubuntu@<IP_from_CF_OUTPUT>

ここから先は必要なスクリプト類はgithubに準備したので、git cloneで持ってきてください。

git clone https://github.com/porcaro33/openfoam-docker.git

openfoam-dockerフォルダに移動し、bastion_setup.shを実行してください。docker-ceとawscliをインストールします。

cd openfoam-docker
./bastion_setup.sh

docker build/push

Dockerfileはgithubからダウンロードしてあるので、いきなりビルド!

sudo docker build -t openfoam-batch:latest .

ビルドが終わったらECRにdocker imageをpushします。

aws --region us-west-2 ecr get-login --no-include-email

返り値の”docker login -u AWS -p ….”をコピー、sudoを前につけて、ペーストして実行。
“Login Succeeded”と表示されたらOK。

次はtagをつけて、pushします。

sudo docker tag openfoam-batch:latest <account-id>.dkr.ecr.us-west-2.amazonaws.com/openfoam-batch:latest
sudo docker push <account-id>.dkr.ecr.us-west-2.amazonaws.com/openfoam-batch:latest

3. Create Batch Environment

Batchを実行する上で必要な、Job Definition, Compute Environment, Job Queueを作成していきます。CloudFormationのOutputsをもとに3つのjsonファイル編集して、AWCCLIを実行していきます。

job_definition.json

sudo vi job_definition.json

imageにはarnではなくURIを入力する必要があるので、一度ECSの画面にいってURIをコピーしてjsonに貼り付ける。
image

compute_environment.json

sudo vi computing_env.json

image

job_queue.json

sudo vi job_queue.json

特に変更点なし、内容だけ確認してください。

create job definition, compute enmvironment, job queueのCLI実行。それぞれ返り値を確認しながら実行してください。

aws --region us-west-2 batch register-job-definition --cli-input-json file://job_definition.json
aws --region us-west-2 batch create-compute-environment --cli-input-json file://computing_env.json
aws --region us-west-2 batch create-job-queue --cli-input-json file://job_queue.json

5.Submit Jobs

これでOpenFoamを実行する環境は準備できました。最後にジョブを実行します。AWSCLIをつかって10回ジョブを実行して、その結果をS3に保存していきます。

./submit_batch.sh

ジョブが実行されると、BatchのDashboardで各ジョブのstatusが次々を変わっていくのが見えます。ジョブがない場合はECS Clusterのコア数を0に設定しているので、ジョブに合わせてEC2 Instanceを起動していくのも見えます。

Batch Dashboard
image

EC2
image

最後にS3にファイルが保存されているのを確認しください。

6.Close this environment

Batch環境を消すには、作成とは逆の順番で消していく必要があります。
– disable/delete job queue
– disable/delete compute environment
– disable/delete job definition

Batchを消したら、S3内の結果ファイルも消してください。バケットを空にしないとCloudFormationの削除でfailします。
– delete s3 objects
– delete container repo
– delete cloudformation stack

fin!

続きを読む

Aurora小ネタ/MySQLレプリケーションでのしくじりポイント

先に、オンプレMySQL~RDS for MySQL/Aurora間のレプリケーションにおけるタイムゾーン設定という記事を書きましたが、それ以外にもAuroraでのMySQLレプリケーションでいくつか問題に遭遇しましたので、書き残しておきます。

しくじり1. そもそもレプリケーションが開始できない

Auroraがマスターになるケースで、

  • バイナリログの出力をON(MIXEDまたはROW)にした
  • バイナリログの保存期間も設定した(mysql.rds_set_configurationプロシージャで)
  • スレーブに対してREPLICATION SLAVE・REPLICATION CLIENT権限を付与した
  • スレーブ側でCHANGE MASTER TOコマンドはエラーにならずに通った

にもかかわらず、スレーブ側でSTART SLAVE後にレプリケーションが開始されない場合、セキュリティグループやNACL、ルートテーブル、(オンプレ環境にレプリケーションする場合)オンプレ側のファイアーウォールポリシーなどのネットワークの問題ばかり気にしがちですが(実際、そちらに原因があることも多い)、

「MySQLのレプリケーションで設定可能なマスターホスト名は60文字までである」

という制限に引っかかっていることもあります。

東京リージョンでAuroraのクラスターエンドポイント(IPアドレスではなくFQDN指定で)を使う場合、

  • 読み書き可能 : 【クラスター識別子】.cluster-XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com
  • 読み取りのみ : 【クラスター識別子】.cluster-ro-XXXXXXXXXXXX.ap-northeast-1.rds.amazonaws.com

ということで、クラスター識別子以外の文字数が、前者で54文字、後者で57文字もあります。

つまり、「クラスター識別子を極端に短く設定しないと、クラスターエンドポイントをMASTER_HOSTに指定できない」(指定できるけど動かない)ということになります。

このクラスターエンドポイント、パブリック公開しない(=プライベートIPアドレスが返る)場合でも外部から引くことができるので(RFC的にどうなの?というツッコミは一旦置いておいて)、オンプレ環境のスレーブサーバーとVPN等経由でレプリケーションする場合にも便利なのですが、こういうトラップもありますので、注意しましょう。

なお、最初のほうにさらっと、

  • バイナリログの保存期間も設定した(mysql.rds_set_configurationプロシージャで)

と書きましたが、この設定を忘れると(何事もなくレプリケーションを開始できてしまうのですが)予期せぬタイミングでレプリケーションが続行不能になる可能性があるため、こちらも注意が必要です(単位は日数ではなく時間=hours)。

しくじり2. レプリケーションが途中で止まる

こちらも、原因は色々ありますが(レプリケーションを開始するときのマスター/スレーブの状態に差があった、読み込むバイナリログの開始ポジションを誤った、マスター側/スレーブ側でアクセス権限に差があるのに、うっかりマスター側にしか存在しないユーザーを変更/削除しようとした、など)、

「Auroraでは、MySQL(5.6)の既知のバグが全てフィックスされているわけではない」

点に注意が必要です。

私の場合、MySQLのBug #69861(MySQL 5.6.15でBug #17234370とともにフィックス)に引っかかって、

[1]オンプレ ⇒ [2]Aurora ⇒ [3]オンプレ

の環境で、[3]オンプレへのレプリケーション時に「LAST_INSERT_ID()の実行結果が0になる」不具合に遭遇しました。

[2]のAuroraでバイナリログの形式をMIXEDからROWに変更することで解決しましたが、このようなレアなユースケース(まさか、AuroraをMySQLレプリケーションの「中継サーバー」に使うとは、AWSの中の人も思わない…?)で問題になるようなバグはフィックスされていない可能性があるので、本家MySQLのChangelogとAuroraのバグフィックス情報を見比べて確認しておいたほうが良いでしょう。

続きを読む

Aurora小ネタ/テストDBを削除するときに…

AuroraでテストDBの復元→削除を繰り返すときに、うっかり既存のスナップショットと同じ名前(○○-final-snapshot)を付けて最終スナップショットを取得すると…?

0. 初期状態

以下のテストDBを削除し、最終スナップショットを取得しているとします。

  • DBインスタンス識別子 : db1-test
  • 同・クラスター識別子 : db1-test-cluster
  • 最終スナップショット名 : db1-test-final-snapshot

01_rds_snap.png
こんな感じになります。この時点では、クラスター「db1-test-cluster」はきれいに削除されています。

1. スナップショットからテストDBを復元

↑のスナップショットからDBインスタンス「db1-test」を復元します。

02_aurora_connect.png
クラスター識別子は元のままで、クラスターエンドポイントのIPアドレスもDNSで引くことができており(PINGで確認)、MySQLクライアントからの接続もちゃんとできています。

2. テストDBを削除

このテストDBを削除します。

04_aurora_delete2.png
ここで、うっかり、最終スナップショット名を(元のスナップショットを消さないまま)同じものにすると、画面上には何のメッセージも出ませんが…

05_aurora_cluster.png
インスタンスは削除されますが、クラスターが残っています(インスタンス数は0です)。
クラスターエンドポイントのIPアドレスは、DNSで引けなくなりました。

3. 再度、スナップショットからテストDBを復元

最初と同じ画面で、同じスナップショットから再びテストDBを復元します。

06_aurora_restore.png
何の指定もしていませんが、クラスター識別子の末尾に「-1」が付きます。
つまり、先ほどまでとは別のクラスターでインスタンスが復元されます。

07_aurora_new_cluster.png
クラスターが変わっていることに気づかないまま、前回のクラスターエンドポイントにPINGを打ってみると…なんと、新しいインスタンスのIPアドレスが引けてしまいます!(第4オクテットが152から154に変わっていますね。)
当然、MySQLクライアントから接続もできてしまいます。

4. レプリカを作成し、フェイルオーバーを試す

フェイルオーバーのテストをするために、別AZにレプリカを作成します。

08_aurora_replica.png

作成後、フェイルオーバーしてみると…?

09_aurora_failover.png
前回のクラスターエンドポイントにPINGを打ってみても、IPアドレスは変わりません。DNSエンドポイントがレプリカにフェイルオーバーしない…!?

当然ですが、このときのクラスターエンドポイントは「db1-test-cluster-1」用のものが正解です。
こちらのエンドポイントを使うと、ちゃんと「db1-replica」インスタンスのIPアドレスを指しているのですが…そもそも、この時点では別クラスターにインスタンスが復元されていることに気づいていないので、ちょっとしたパニックに…。

私の場合、しばらく悩み、AWSのパートナーさんのサポート窓口とやり取りしている途中にようやく気づきました(スクリーンショットと画面ログを添付していたのですが、私自身が気付くまで、サポート窓口の方も気づきませんでした)。

その後、同僚が別のテストでDBの復元→削除を繰り返しているときに全く気づかずに同じことをしていて、「○○-cluster-2」まで出来上がり(末尾の番号はインクリメントされていきます)、さらに「○○-cluster-3」までも(意図せず)作ろうとしていたので、慌てて止めました。

なお、クラスターを削除し損ねた場合、指定のバックアップウィンドウの中で自動スナップショットの取得が行われるので、そちらを見て「おや?なんか変だぞ?」と気づくかもしれません。

10_aurora_snap.png

皆さんも、騙されないよう、気を付けましょう。

続きを読む

(途中) ECS始めてみました。

◎はじめに

・下記のようECSを使うためにDockerの学習をしていましたが概要ぐらいは掴めた気がするため、今回はECS(Amazon EC2 Container Service)を実際に触ってみました。

  1. AWS ECSを使用する前にDockerを理解しなきゃ
  2. Docker学習中につき!(コマンドの整理とイメージ構築など)
  3. Docker学習中につき!(ユーザ定義ネットワークでコンテナ間の通信)

1. ECS使用開始

ECSアイコン.png

■とりあえず触ってみよう
・とりあえずECSを動かしてみたかったため、下記公式ドキュメントの記載に沿ってやってみました。
・今回はCLIは使っておらずAWSコンソールから実施しています。

セットアップ
ECS クラスター作成

1-1. IAM

IAMユーザ作成

セキュリティの観点からECS操作用のIAM ユーザーを作成する

1) Set user details
[Users] – [Add Users]

User name: mitzi_ecs
Programmatic access – check
AWS Management Console access – check

[Next: Permissions]

2) Set permissions for
[Create group]
Group name: group-policy-ecs

[Filter: Job function] – [Policy name: AdministratorAccess] を選択 – [Create group]
[Next: Review]
※全権限付与しちゃってます(とりあえず)

・作成したIAMユーザ
mitzi_ecs

ちなみに
3) sign-in URLに Aliasを設定
IAM – [Dashboard] –
IAM Users sign-in link:
https://.signin.aws.amazon.com/console
このリンクの右側にある [Customize]を押下し、Aliasを設定

https://mitzi-users.signin.aws.amazon.com/console
Alias設定出来るって始めてしりました。

2017-07-10_IAM Alias for ECS.png

IAM Role

Amazon ECS インスタンスとサービスのロールは、コンソールの初回実行時に自動的に作成される
→ とあるのですが、私の環境にはなかったので新規作成

IAMコンソール
[Roles] – [Create New Role]

Step1: Select role type – 「Amazon EC2 Role for EC2 Container Service」を選択
Step2: Establish trust – (スキップされました)
Step3: Attach Policy – 「AmazonEC2ContainerServiceforEC2Role」を選択
Step4: Set role name and review –
Role name: ecsInstanceRole (デフォルトで作成されるはずの名前)

1-2. ECS クラスター作成

[Clusters] ページより

[Create Cluster]選択
Cluster name: mitzi-ecs-cluster (任意)

・Instance configuration

 Provisioning Model: On-Demand Instance (デフォルト)
 EC2 instance type: t2.micro (任意. テストなのでお金が掛からないように)
 Number of instances: (クラスターで起動する Amazon EC2 インスタンスの数を選択)
 EBS storage (GiB): (ルートボリュームは8GBで固定の模様。こちらではデータボリュームのサイズを指定)
 Key pair: (既存のkey pareを指定)

※これらのインスタンスは、Amazon ECS に最適化された最新の AMI を使用して起動されるとのこと。
参考

・Networking

 VPC: (コンテナインスタンスを起動するVPCを設定)
 Subnets: (指定したVPCのSubnetを1つ以上選択可能)
 Security group: (コンテナインスタンスにアタッチするセキュリティグループを選択)

・Container instance IAM role

 Container instance IAM role: ecsInstanceRole (デフォルトで選択されてました)

[Create]ボタンを押下すると launchが開始される
その結果は下記

・Cluster Resources

Instance typet: 2.micro
 Desired number of instances: 2
 Key pair: aws-hashimoto
 ECS AMI ID: ami-e4657283
 VPC: vpc-16a94573
 Subnets: subnet-467f4500, subnet-ab0ce8dc
 VPC Availability Zones: ap-northeast-1c, ap-northeast-1a
 Security group: sg-c79765a2
 Launch configuration: EC2ContainerService-mitzi-ecs-cluster-EcsInstanceLc-1NIUNEFA0R9O6
 Auto Scaling group: EC2ContainerService-mitzi-ecs-cluster-EcsInstanceAsg-1LVE67JUKXLG8

1-3. リポジトリの設定 (テスト用リポジトリを下記のように作成)

Repository name: example-repository
Repository URI : 253920042626.dkr.ecr.ap-northeast-1.amazonaws.com/example-repository

※このリポジトリにはまだ何も登録していないため、後述するとおり本稿では Docker Hubを利用しています。

1-4. Docker イメージの構築、タグ付け、プッシュ

Docker CLI を使用して既存のローカルイメージ (Dockerfile から構築したもの、または Docker Hub などの別のレジストリから取得したもの) にタグを付け、そのタグ付きイメージを Amazon ECR レジストリにプッシュします。

→ 今回はデフォルトリポジトリにあるimageを使うため、この工程はスキップ

1-5.タスク定義

[Task Definitions] – [Create new Task Definition]

・今回は JSON 形式のタスク定義のため
[Configure via JSON] – タスク定義記載(※1) – [Save] – [Create]

※[Network Mode]未設定のままCreateすると、「Bridge」が設定されていた。
この辺はDockerでコンテナ作成する際と合わせているようだ。

(※1. Amazon ECS での AWS CLI の使用よりタスク定義を拝借

Docker Hub から取得した busybox イメージを使用し、360 秒間スリープ状態になるシンプルなタスク定義

{
  "containerDefinitions": [
    {
      "name": "sleep",
      "image": "busybox",
      "cpu": 10,
      "command": [
        "sleep",
        "360"
      ],
      "memory": 10,
      "essential": true
    }
  ],
  "family": "sleep360"
}

1-6. サービス設定

・サービスとは

タスク定義の指定した数 (“必要数”) のインスタンスを ECS クラスターで同時に実行して維持できます。これはサービスと呼ばれます。

タスクが何らかの理由で失敗または停止した場合、Amazon ECS サービススケジューラは、タスク定義の別のインスタンスを起動してそれに置き換え、サービスで必要数のタスクを維持します。
→ Auto Scalingのような挙動のようです。

・タスク定義で作成した Task Definition: 「sleep360:1」(最新版)を選択して
[Actions] – [Create Service]

・Create Service

 [Cluster] -> mitzi-ecs-cluster (公式のECS の使用開始どおりに進めていくとこの時点でClusterが出来ておらず、サービスを設定出来ませんでした。。)
 [Service name] -> mitzi-ecs-service (任意)
 [Number of tasks] -> クラスターで起動して維持するタスクの数
 [Minimum healthy percent] -> Auto Scaling GroupのMin Size(最小数)に似た設定のようだが、タスクに必要なインスタンス数のパーセント値を指定している
 [Maximum percent] -> こちらもASに似たような設定。デフォルト200%

・Task Placement (オプション)

タスク配置戦略と制約を使用してタスクをどのように配置するかを指定できます。
幾つかのテンプレートから選択可能

Placement Templates: AZ Balanced Spread (オプション設定と公式にあるが、どれかしら選択しないといけない作りになっています)
※AZ Balanced Spread: アベイラビリティーゾーン間およびアベイラビリティーゾーン内のコンテナインスタンス間でタスクを分散

・Optional configurations
Configure ELB
→ 今回のタスク定義では、portMappingsを設定していないため選択出来ませんでした。

Configure Service Auto Scaling
→ 今回は利用しない

[Create Service]を押下するとサービス作成開始

1-7.確認

一先ずECS(クラスター、コンテナ、サービス)を開始出来ました。

2017-07-10_ECS Service.png

続きを読む

Amazon Elasticsearch Serviceでcluster_block_exceptionがでたら

症状

こんなエラー。
読み込みは出来るが、書き込みやインデックス作成は全て失敗するようになる。

"error": {
  "type": "cluster_block_exception",
  "reason": "blocked by: [FORBIDDEN/8/index write (api)];"
}
"error": {
  "type": "index_create_block_exception",
  "reason": "blocked by: [FORBIDDEN/10/cluster create-index blocked (api)];"
}

原因と対策

原因は主に2つある模様。

ディスク容量不足

AmazonESのメトリックスでFreeStorageSpaceを見ると0になっているはず。
インスタンスタイプかEBSの容量を上げればいいはず。

Amazon ES ドメインの設定 – AmazonES 開発者ガイド
EBS ベースのストレージの設定 – AmazonES 開発者ガイド

メモリ容量不足

AmazonESのメトリックスでJVMMemoryPressureが92%を超えているはず。
超えているというか92%をキープしている。

スクリーンショット 2017-06-20 14.35.10.png

t2特有の現象というわけでなく他のインスタンスタイプでも同じことが起きたので、単純にスケールアップしてメモリ増やせということだと思う。
この状態でもClusterHealthは青いままなので要注意。
JVMMemoryPressureは監視対象にしたほうがよさそう。

参考

AWS サービスエラー処理 – AmazonES 開発者ガイド
elasticsearchを利用するときは容量を管理しようという話 – Qiita

続きを読む