Terraform で AWS インフラストラクチャ!

Terraform で AWS インフラストラクチャ!

Terraform とは

  • インフラ構成や設定をコードにより実行計画を確認しながら自動化できるツール
  • AWS, Google Cloud 等多数のクラウドサービスで利用可能
  • HashiCorp 社製

今回やること

  • インスタンス起動
  • Elastic IP 付きインスタンス起動
  • インスタンス破棄

非常にミニマムなインフラ構築をしてみます。
※個人のアカウントでも無料枠を使えば数十円しか掛からなかったです。

環境

  • Mac OS Sierra X 10.12.3 16D32
  • Terraform 0.9.1

terraform インストール

1
$ brew install terraform

バージョン確認

1
2
3
$ terraform version

Terraform v0.9.1

では、早速使ってみます。

EC2 instance (t2.micro) 起動

  • main.tf 作成
1
2
3
4
5
6
7
8
9
10
provider "aws" {
access_key = "A******************Q"
secret_key = "q**************************************Z"
region = "ap-northeast-1"
}

resource "aws_instance" "example" {
ami = "ami-71d79f16"
instance_type = "t2.micro"
}
  • 実行計画確認
1
$ terraform plan
  • 実行
1
$ terraform apply

Amazon Console からインスタンスが起動されたことが確認できます。

変数を別ファイルで管理

上記 main.tf を github 等で管理するとなると
access_key, secret_key が露見されてしまいます。

その為、以下の様に別ファイルで管理することが望ましいです。

  • main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
variable "access_key" {}
variable "secret_key" {}
variable "region" {
default = "ap-northeast-1"
}

provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}

resource "aws_instance" "example" {
ami = "ami-71d79f16"
instance_type = "t2.micro"
}
  • terraform.tfvars
    • terraform 実行時に自動で読み込まれるファイル
1
2
access_key = "A******************Q"
secret_key = "q**************************************Z"
  • 実行計画確認
1
2
3
4
5
$ terraform plan

...

Plan: 1 to add, 0 to change, 0 to destroy.

正しく実行できることが確認できました。

terraform.tfvars ファイルは .gitignore に登録しておくなど
絶対に公開されない様な設定が望ましいと思います。

EC2 instance (t2.micro) AMI 変更

  • main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
variable "access_key" {}
variable "secret_key" {}
variable "region" {
default = "ap-northeast-1"
}

provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}

resource "aws_instance" "example" {
ami = "ami-047aed04"
instance_type = "t2.micro"
}
  • 実行計画

変更される内容が表示されます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ terraform plan

...

-/+ aws_instance.example
ami: "ami-71d79f16" => "ami-047aed04" (forces new resource)
associate_public_ip_address: "true" => "<computed>"
availability_zone: "ap-northeast-1a" => "<computed>"
ebs_block_device.#: "0" => "<computed>"
ephemeral_block_device.#: "0" => "<computed>"
instance_state: "running" => "<computed>"
instance_type: "t2.micro" => "t2.micro"
ipv6_addresses.#: "0" => "<computed>"
key_name: "" => "<computed>"
network_interface_id: "eni-f4a214bb" => "<computed>"
placement_group: "" => "<computed>"
private_dns: "ip-172-31-31-239.ap-northeast-1.compute.internal" => "<c
omputed>"
private_ip: "172.31.31.239" => "<computed>"
public_dns: "ec2-52-199-88-146.ap-northeast-1.compute.amazonaws.com"
=> "<computed>"
public_ip: "52.199.88.146" => "<computed>"
root_block_device.#: "1" => "<computed>"
security_groups.#: "0" => "<computed>"
source_dest_check: "true" => "true"
subnet_id: "subnet-7a79cc0d" => "<computed>"
tenancy: "default" => "<computed>"
vpc_security_group_ids.#: "1" => "<computed>"


Plan: 1 to add, 0 to change, 1 to destroy.

最初に作成したインスタンスは破棄され、新たにインスタンスを作成していることがわかります。

terraform で新規作成・変更ができました。

次は破棄してみましょう。

EC2 instance (t2.micro) 破棄

  • 実行計画確認

破棄対象のリソースが表示されます。

1
2
3
4
5
$ terraform plan -destroy

...

- aws_instance.example
  • 実行
1
2
3
4
5
6
7
8
9
10
$ terraform destroy

Do you really want to destroy?
Terraform will delete all your managed infrastructure.
There is no undo. Only 'yes' will be accepted to confirm.

Enter a value: yes (← yes 入力)
...

Destroy complete! Resources: 1 destroyed.

Amazon コンソールで破棄されたことを確認できます。

インスタンス起動し Elastic IP (固定 IP) 設定

  • main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
variable "access_key" {}
variable "secret_key" {}
variable "region" {
default = "ap-northeast-1"
}

provider "aws" {
access_key = "${var.access_key}"
secret_key = "${var.secret_key}"
region = "${var.region}"
}

resource "aws_instance" "example" {
ami = "ami-047aed04"
instance_type = "t2.micro"
}

resource "aws_eip" "ip" {
instance = "${aws_instance.example.id}"
}
  • 実行計画確認
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$ terraform plan

...

+ aws_eip.ip
allocation_id: "<computed>"
association_id: "<computed>"
domain: "<computed>"
instance: "${aws_instance.example.id}"
network_interface: "<computed>"
private_ip: "<computed>"
public_ip: "<computed>"
vpc: "<computed>"

+ aws_instance.example
ami: "ami-047aed04"
associate_public_ip_address: "<computed>"
availability_zone: "<computed>"
ebs_block_device.#: "<computed>"
ephemeral_block_device.#: "<computed>"
instance_state: "<computed>"
instance_type: "t2.micro"
ipv6_addresses.#: "<computed>"
key_name: "<computed>"
network_interface_id: "<computed>"
placement_group: "<computed>"
private_dns: "<computed>"
private_ip: "<computed>"
public_dns: "<computed>"
public_ip: "<computed>"
root_block_device.#: "<computed>"
security_groups.#: "<computed>"
source_dest_check: "true"
subnet_id: "<computed>"
tenancy: "<computed>"
vpc_security_group_ids.#: "<computed>"


Plan: 2 to add, 0 to change, 0 to destroy.
  • 実行
1
$ terraform apply

Elastic IP が設定されたインスタンスが起動していることが確認できます。
※ただ、起動しただけで接続できないことがわかります(>_<) 次回実施します

[f:id:kenzo0107:20170323230208p:plain]

  • 実行計画確認

破棄される Elastic IP, インスタンスが確認できます。

1
2
3
4
5
6
7
$ terraform plan -destroy

...

- aws_eip.ip

- aws_instance.example
  • 実行
1
2
3
4
5
$ terraform destroy

...

Destroy complete! Resources: 2 destroyed.

全インスタンスが破棄されていることが確認できました。

その他便利な設定

Map 設定

  • region 毎に AMI を選択し terraform apply 時に変数指定し選択可能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...

variable "amis" {
type = "map"
default = {
us-east-1 = "ami-13be557e"
us-east-2 = "ami-71d79f16"
us-west-1 = "ami-00175967"
us-west-2 = "ami-06b94666"
ap-northeast-1 = "ami-047aed04"
}
}

...

resource "aws_instance" "example" {
ami = "${lookup(var.amis, var.region)}"
instance_type = "t2.micro"
}

ex) region us-west-2 を選択

1
$ terraform apply -var region=us-west-2

出力設定

生成された Elastic IP の値が知りたいときなど便利です。

  • main.tf
1
2
3
4
5
6
7
resource "aws_eip" "ip" {
instance = "${aws_instance.example.id}"
}

output "ip" {
value = "${aws_eip.ip.public_ip}"
}

出力値が確認できます。

1
2
3
4
5
6
7
$ terraform apply

...

Outputs:

ip = 52.197.157.206
  • terraform output

より明示的にパラメータを絞って表示できます。

1
2
3
$ terraform output ip

52.197.157.206
  • show
1
2
3
4
5
6
7
$ terraform show

...

Outputs:

ip = 52.197.157.206

構成のグラフ化

1
$ terraform graph | dot -Tpng > graph.png
  • graph.png
  • dot コマンドがない場合は graphviz インストール
1
$ brew install graphviz

総評

簡単でしょ?と言われているようなツールでした ♪

引き続きプロビジョニングや AWS の各種設定をしていきたいと思います。

次回 EC2 インスタンスを起動し、ローカル環境で作った鍵をキーペア登録し SSH ログインを実施します。

no-ipでAWSインスタンスの動的ip更新対応 ~いつも同じドメイン名でアクセスしたい~

概要

AWSの起動停止をするとElasticIPを設定していない限り
Public IPが変更されてしまいます。

ElasticIPは設定するとAWSを停止していても費用が発生します。

検証用環境など一時的に利用するインスタンスについて
起動時にIPが変更したことを関係者に周知するなどの手間が掛かります。

その為No-IPを利用しドメインを固定しIP変更に対応するようにしました。

No-IPは無料のドメインサービスで動的IP変更を検知するLinux用モジュールも配布しています。

環境

  • Amazon Linux AMI release 2015.09
  • noip 2.1.9

手順

まずnoipサイトで会員登録し利用したいドメインを登録します。
ipはとりあえず適当で良いです。

http://www.noip.com/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// rootユーザで実行
$ sudo su
# cd /usr/local/src

// noipモジュール
# wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
# tar xzf noip-duc-linux.tar.gz
# cd noip-2.1.9
# make
# make install

// 起動スクリプト作成
# cp redhat.noip.sh /etc/init.d/noip
# chmod 755 /etc/init.d/noip

// 起動設定
# /sbin/chkconfig noip on

// 起動
# /etc/init.d/noip start

起動後、no-ipのコンソール上で指定ドメインのIPが
1分もしない程度で切り替わっていることが確認できます。

今後

No-IPはMicroSoftによりマルウェアの温床となっておりユーザを保護すべく
22のNO-IPドメイン差し止めを連邦裁判所に申し立て、受理されましたが

No-IP側としては相談していただければ対応もできた、とし申し立て後
対応し随時ドメインの復活を果たしています。

ある程度セキュリティを加味して利用する必要がありますね。
今の所、AWSのセキュリティグループで特に外部アクセスはなく
問題なく動作しています。

また、
以下のようなGREEさんの記事がありました。

AWS EC2 での最強の Public IP 取得方法

内部関係者に聞いてみたいと思います。

===追記===

GREEさんの記事の件、内部関係者に聞いた所ubuntuのみで利用しているそうです。

AWS Multi-AZにおける Pacemaker + Corosync による Elastic IP の付け替え

概要

Pacemaker & Corosync による
AWS での Multi-AZ 間のEIP付け替えによる
フェイルオーバーについて実装したのでまとめます。

以下イメージです。

  • 通常状態

Normal

  • Avalavility Zone A に配置された Instance A で障害が発生した場合
    Avalavility Zone B に配置された Instance B に EIPを付け替え

Accident occured

ToDo

  • VPC, Subnet 設定
  • Pacemaker & Corosync インストール / 設定
  • Cluster 構築
  • EIP付け替えスクリプト作成
  • フェイルオーバー試験

環境

  • CentOS 7 (x86_64) with Updates HVM (t2.micro)
    ※ 検証用の為、 t2.microで実施しています。

VPC, Subnet 構築

以下記事にて非常によくまとめて頂いているので参考にしていただき
この設定を以降そのまま利用します。

0から始めるAWS入門①:VPC編

念のため、以下 VPC, Subnet 設定です。
  • VPC 設定
項目
Name tag 任意
CIDR 10.0.0.0/16
tenancy Default
  • Subnet 設定
項目 Subnet 1 Subnet 2
Name tag 任意(VPCのタグ名と関連付けたほうが管理しやすい) 任意(VPCのタグ名と関連付けたほうが管理しやすい)
VPC 上記で作成したVPCを選択する 上記で作成したVPCを選択する
Availability Zone ap-northeast-1a ap-northeast-1c
CIDR 10.0.0.0/24 10.0.1.0/24

上記VPC設定に基づき以下設定していきます。

構築するイメージは以下になります。

セキュリティグループ作成

今回作成するインスタンス2つにアタッチするセキュリティグループを事前に作成します。

マイIPからのSSHログイン許可

項目 設定値
セキュリティグループ名 VPC-for-EIP(任意)
説明 VPC-for-EIP(任意)
VPC 上記で作成したVPCを選択する

作成したセキュリティグループ編集

  • フィルターで検索

※以下は環境により変更してください。

  • 送信元を作成したグループIDとし以下追加し保存
タイプ プロトコル ポート範囲 送信元 用途
すべてのTCP TCP 0 - 65535 作成したセキュリティグループID 今回は検証用の為、全解放。適宜設定変更してください。
すべてのICMP ICMP 0 - 65535 作成したセキュリティグループID ping疎通確認用。今回は検証用の為、全解放 適宜設定変更してください。
すべてのUDP UDP 0 - 65535 作成したセキュリティグループID corosyncで必要なポートはデフォルトで 5404 - 5405。 環境により設定変更する場合は注意が必要です。今回は検証用の為、全解放。適宜設定変更してください。
SSH TCP 20 マイIP 自PC端末からSSHログイン用。実環境で設定する必要はありません。
HTTP TCP 80 マイIP FailOver検証用。実環境で設定する必要はありません。

以上でインスタンスに適用するセキュリティグループの作成が完了しました。


ポリシー作成

今回、以下コマンドを実行する必要があります。

コマンド 用途
aws ec2 associate-address ElasticIPをインスタンスに関連付ける
aws ec2 disassociate-address ElasticIPをインスタンス関連付け解除
aws ec2 describe-addresses IPアドレスについて詳細取得
Identity & Access Management ページにアクセス
「ポシリー作成」クリック
独自ポリシー作成
独自ポリシー情報入力
  • ポリシー名(任意)

floatingElasticIP

  • ポリシードキュメント
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:DisassociateAddress",
"ec2:AssociateAddress"
],
"Resource": [
"*"
]
}
]
}
確認

IAMロール作成

ElasticIPの付け替え権限を持ったロールを作成します。

新しいロールの作成 をクリック
ロール名の設定
ロールタイプの選択

Amazon EC2 の「選択」ボタンをクリック

ポリシーのアタッチ
登録内容を確認しロールの作成
作成されたか確認

以上でインスタンスに適用するIAMロールの作成が完了しました。

ユーザ作成

Identity & Access Management ページにアクセス
メニューからユーザクリック & 新規ユーザの作成 ボタンクリック
ユーザ名入力し作成ボタンクリック
認証情報をダウンロードクリック

Access Key IdSecret Access Key が記載されたCSVがダウンロードされます。
大切に保管しましょう。

作成されたユーザーにアクセス
ポリシーのアタッチ開始
ポリシーにチェックを入れアタッチ

以上で
AmazonEC2FullAccess 権限を持ったユーザ floatingIP ユーザが作成されました。

上記ユーザの認証情報は 手順 aws-cli インストール で利用します。


インスタンスの作成

  • 上記で作成したVPCのSubnet (ap-northeast-1a)にインスタンス (以降Instance A)を作成します。

「インスタンスの作成」をクリック

マシンイメージ選択

今回は CentOS 7 (x86_64) with Updates HVM を選択します。

インスタンスタイプ選択

今回は検証用で無料枠として利用したいので t2.micro を選択します。

インスタンスの詳細の設定

ap-northeast-1a に作成する Instance A のプライマリIPを
10.0.0.20 とします。

ストレージの追加

特に変更することなく次の手順へ

インスタンスのタグ付け

Name タグに Instance A と指定します。
※ 任意なのでわかりやすいテキストであれば良いです。

セキュリティグループの設定

  • 事前に作成したセキュリティグループを選択

インスタンス作成の確認

以上で Insntace A の作成が完了しました。

同様に Instance B 作成

Instance A との主な変更点
  • Subnet 10.0.1.0/24 を選択
  • インスタンスのタグは Instance B とする
Instance B 設定時注意点
  • セキュリティグループInstance B でも同様 Instance A で設定した
    セキュリティグループ を選択する。

送信元/送信先の変更チェックを無効化

※上記 Instance A, B 共に Source/Destination Check (ネットワーク > 送信元/送信先の変更チェック) を Disabled (無効) に設定する必要があります。

インスタンス SSHログイン後まずやること

最低限必要なモジュールインストール

※ git は ElasticIP付け替え時のシェルをインストールする際に必要になります。

1
2
3
4
5
[Instance A & B ]# yum install -y git

[Instance A & B ]# git --version

git version 1.8.3.1

Fail Over 検証用に httpd, php インストール

あくまで Fail Over 時の動きを見る為の確認用にインストールし起動しています。
※必須工程ではありません。

1
2
3
4
5
6
[Instance A & B ]# yum --disableexcludes=main install -y gcc
[Instance A & B ]# yum install -y gmp gmp-devel
[Instance A & B ]# yum install -y php php-mysql httpd libxml2-devel net-snmp net-snmp-devel curl-devel gettext
[Instance A & B ]# echo '<?php print_r($_SERVER["SERVER_ADDR"]); ?>' > /var/www/html/index.php
[Instance A & B ]# systemctl start httpd
[Instance A & B ]# systemctl enable httpd

system clock 調整 JST設定

OS内の時間が現実の時間とずれていると
aws-cliが正常に動作しない可能性があるので
念の為、調整しておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
# バックアップ確保
[Instance A & B ]# cp /etc/sysconfig/clock /etc/sysconfig/clock.org

# 再起動しても設定維持する様にする。
[Instance A & B ]# echo -e 'ZONE="Asia/Tokyo"\nUTC=false' > /etc/sysconfig/clock

# バックアップ確保
[Instance A & B ]# cp /etc/localtime /etc/localtime.org

# Asia/Tokyo を localtime に設定
[Instance A & B ]# ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

[Instance A & B ]# date

Elastic IP作成

Elastic IPを作成し Server A に関連付けます。

新しいアドレスを割り当てる
確認ポップアップで「関連付ける」をクリック
成功確認
インスタンスに関連付け
関連するインスタンス選択
確認

以上で Instance A に ElasticIP が関連付けされました。

Instance A & B に SSHログイン

  • Instance A に SSHログイン

    1
    [Local PC]# ssh -i aws.pem centos@<Instance AのPublic IP>
  • Instance B に SSHログイン

    1
    [Local PC]# ssh -i aws.pem centos@<Instance BのPublic IP>

/etc/hosts設定

1
2
[Instance A ]# uname -n
ip-10-0-0-10.ap-northeast-1.compute.internal
1
2
[Instance B ]# uname -n
ip-10-0-1-10.ap-northeast-1.compute.internal
1
2
3
4
5
6
7
[Instance A & B ]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6

# 以下追加
10.0.0.20 ip-10-0-0-20.ap-northeast-1.compute.internal
10.0.1.20 ip-10-0-1-20.ap-northeast-1.compute.internal

Pacemaker & Corosync インストール

  • pcsは旧来のcrmshに代わるPacemakerクラスタ管理ツールであり、RHEL/CentOS7においてはpcsの使用が推奨されている。
1
[Instance A & B ]# yum -y install pcs fence-agents-all
  • バージョン確認
1
2
3
4
5
6
7
8
9
10
[Instance A & B ]# pcs --version
0.9.143

[Instance A & B ]# pacemakerd --version
Pacemaker 1.1.13-10.el7
Written by Andrew Beekhof

[Instance A & B ]# corosync -v
Corosync Cluster Engine, version '2.3.4'
Copyright (c) 2006-2009 Red Hat, Inc.

hacluster パスワード設定

corosyncパッケージインストール時に自動で hacluster ユーザが追加される。
その hacluster のパスワードを設定する。

1
2
3
4
5
[Instance A & B ]# passwd hacluster
ユーザー hacluster のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。

pcsd 起動

cluster監視を実施する為

1
2
3
[Instance A & B ]# systemctl start pcsd
[Instance A & B ]# systemctl enable pcsd
[Instance A & B ]# systemctl status pcsd

cluster認証

クラスタを組む各ホストへのアクセス認証を検証します。

どちらか一方のInstanceから実行します。
以下はInstance Aから実行しています。

1
2
3
4
5
[Instance A ]# pcs cluster auth ip-10-0-0-20.ap-northeast-1.compute.internal ip-10-0-1-20.ap-northeast-1.compute.internal
Username: hacluster
Password:
ip-10-0-1-20.ap-northeast-1.compute.internal: Authorized
ip-10-0-0-20.ap-northeast-1.compute.internal: Authorized

上記のように Authorized (認証済み) と出力されていれば問題ありませんが
以下のような Unable to Communicate というエラーが出力されている場合は
各Instance の設定を見直してください。

  • 認証エラーの例
    1
    2
    3
    [Instance A ]# pcs cluster auth ip-10-0-0-20.ap-northeast-1.compute.internal ip-10-0-1-20.ap-northeast-1.compute.internal -u hacluster -p ruby2015
    Error: Unable to communicate with ip-10-0-0-20.ap-northeast-1.compute.internal
    Error: Unable to communicate with ip-10-0-1-20.ap-northeast-1.compute.internal

cluster設定

クラスタ設定をします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Instance A ]# pcs cluster setup --name aws-cluster ip-10-0-0-20.ap-northeast-1.compute.internal ip-10-0-1-20.ap-northeast-1.compute.internal --force

Shutting down pacemaker/corosync services...
Redirecting to /bin/systemctl stop pacemaker.service
Redirecting to /bin/systemctl stop corosync.service
Killing any remaining services...
Removing all cluster configuration files...
ip-10-0-0-20.ap-northeast-1.compute.internal: Succeeded
ip-10-0-1-20.ap-northeast-1.compute.internal: Succeeded
Synchronizing pcsd certificates on nodes ip-10-0-0-20.ap-northeast-1.compute.internal, ip-10-0-1-20.ap-northeast-1.compute.internal...
ip-10-0-0-20.ap-northeast-1.compute.internal: Success
ip-10-0-1-20.ap-northeast-1.compute.internal: Success

Restaring pcsd on the nodes in order to reload the certificates...
ip-10-0-0-20.ap-northeast-1.compute.internal: Success
ip-10-0-1-20.ap-northeast-1.compute.internal: Success

cluster起動

全ホストに向け クラスタ起動します。

1
2
3
4
[Instance A ]# pcs cluster start --all

ip-10-0-1-20.ap-northeast-1.compute.internal: Starting Cluster...
ip-10-0-0-20.ap-northeast-1.compute.internal: Starting Cluster...

aws-cli インストール

手順: ユーザ作成 でダウンロードした credentials.csv に記載された
Access Key Id Secret Access Key を使用します。

1
2
3
4
5
6
7
8
9
10
11
[Instance A & B ]# rpm -iUvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
[Instance A & B ]# yum -y install python-pip
[Instance A & B ]# pip --version
pip 7.1.0 from /usr/lib/python2.7/site-packages (python 2.7)

[Instance A & B ]# pip install awscli
[Instance A & B ]# aws configure
AWS Access Key ID [None]: *********************
AWS Secret Access Key [None]: **************************************
Default region name [None]: ap-northeast-1
Default output format [None]: json

EIP 付け替えリソース作成

heartbeat で問題検知した際に起動するリソースとして登録します。

OCF_ROOT が定数として指定されているが、存在しない為

1
2
3
4
5
6
7
[Instance A & B ]# cd /tmp
[Instance A & B ]# git clone https://github.com/moomindani/aws-eip-resource-agent.git
[Instance A & B ]# cd aws-eip-resource-agent
[Instance A & B ]# sed -i 's/\${OCF_ROOT}/\/usr\/lib\/ocf/' eip
[Instance A & B ]# mv eip /usr/lib/ocf/resource.d/heartbeat/
[Instance A & B ]# chown root:root /usr/lib/ocf/resource.d/heartbeat/eip
[Instance A & B ]# chmod 0755 /usr/lib/ocf/resource.d/heartbeat/eip

pacemaker 設定

stonish 無効化
1
[Instance A ]# pcs property set stonith-enabled=false
split-brain (スプリット・ブレイン) が発生しても quorum (クォーラム) が特別な動作を行わないように設定
1
[Instance A ]# pcs property set no-quorum-policy=ignore

split-brain とは
ハートビート通信を行うネットワークに断線などの問題が発生した場合、ホストに障害が起こったと勘違いし、
本来立ち上がってほしくないスタンバイ側のホストがアクティブになってしまうというもの

属性値更新時の待ち時間( crmd-transition-delay )を 0s(秒) 設定
1
[Instance A ]# pcs property set crmd-transition-delay="0s"
自動フェイルバックなし、同一サーバでリソースの再起動を試みる回数を 1 回に設定
1
[Instance A ]# pcs resource defaults resource-stickiness="INFINITY" migration-threshold="1"
EIP切り替え設定

今回作成し Instance A に関連付けした ElasticIP は 52.192.203.215 です。
以下設定に反映させます。

1
2
3
4
5
6
[Instance A ]# pcs resource create eip ocf:heartbeat:eip \
params \
elastic_ip="52.192.203.215" \
op start timeout="60s" interval="0s" on-fail="stop" \
op monitor timeout="60s" interval="10s" on-fail="restart" \
op stop timeout="60s" interval="0s" on-fail="block"

cluster 設定確認

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[Instance A ]# pcs config

pcs config
Cluster Name: aws-cluster
Corosync Nodes:
ip-10-0-0-20.ap-northeast-1.compute.internal ip-10-0-1-20.ap-northeast-1.compute.internal
Pacemaker Nodes:
ip-10-0-0-20.ap-northeast-1.compute.internal ip-10-0-1-20.ap-northeast-1.compute.internal

Resources:
Resource: eip (class=ocf provider=heartbeat type=eip)
Attributes: elastic_ip=52.192.203.215
Operations: start interval=0s timeout=60s on-fail=stop (eip-start-interval-0s)
monitor interval=10s timeout=60s on-fail=restart (eip-monitor-interval-10s)
stop interval=0s timeout=60s on-fail=block (eip-stop-interval-0s)

Stonith Devices:
Fencing Levels:

Location Constraints:
Ordering Constraints:
Colocation Constraints:

Resources Defaults:
resource-stickiness: INFINITY
migration-threshold: 1
Operations Defaults:
No defaults set

Cluster Properties:
cluster-infrastructure: corosync
cluster-name: aws-cluster
crmd-transition-delay: 0s
dc-version: 1.1.13-10.el7-44eb2dd
have-watchdog: false
no-quorum-policy: ignore
stonith-enabled: false

Fail Over 実行確認

手順 Fail Over 検証用に httpd, php インストール にて
DocumentRoot (/var/www/html/) に
Private IP ($_SERVER["SERVER_ADDR"]) を表示させるindex.phpファイルを
配置しました。

ブラウザから Private IP を元に Instance A or B どちらのInstance に
アクセスしているかがわかります。

ブラウザから ElasticIP にアクセス

ElasticIP 52.192.203.215 にアクセスすると
Private IP 10.0.0.20 が表示されていることがわかります。

現状、ElasticIP は Instance A に関連付いていることがわかります。

Instance A の corosync 停止
1
[Instance A]# systemctl stop corosync
再度ブラウザから ElasticIP にアクセス

先ほど表示させていたブラウザを幾度かリロードすると
Private IP 10.0.1.20 が表示されていることがわかります。

ElasticIP は Instance B に関連付けられたことがわかります。

ElasticIP が Instance A から関連付けが解放され、 Instance B に関連付けされるようになりました。

コンソールページ上でも確認することができます。

以上で簡易的ではありますが
Cloud Design Pattern の floating IP (ElasticIP) が実現できました。

以上です。

参考