akiyoko blog

akiyoko の IT技術系ブログです

「AWS体験ハンズオン ~セキュア&スケーラブルウェブサービス構築~」に参加してきました

先月19日に、AWS体験ハンズオンに初めて参加してきました。



AWS Summit Tokyo 2015 で、「AWS 認定ソリューションアーキテクト – アソシエイト」を受験予定だったこともあり、その予習として実際に手を動かしながらやってみようと思ったからです。受検結果はまた別途。


結論としては、このハンズオンは私にとって非常に有益でした。
ハンズオンのスピードがすごく速くて、着いていくのにギリギリでしたが。。


また、ハンズオンの前にこちらの本をちょうど読み終えていったのですが、この本がなければ、内容は半分くらいしか理解できなかったかもしれません。オススメの本です。

Amazon Web Services クラウドデザインパターン実装ガイド 改訂版

Amazon Web Services クラウドデザインパターン実装ガイド 改訂版

  • 作者: 大澤文孝,アマゾンデータサービスジャパン玉川憲,アマゾンデータサービスジャパン片山暁雄,アイレット鈴木宏康,日経SYSTEMS
  • 出版社/メーカー: 日経BP社
  • 発売日: 2015/03/05
  • メディア: 単行本
  • この商品を含むブログ (2件) を見る
Amazon Web Services クラウドデザインパターン 実装ガイド 改訂版 日経BP Next ICT選書

Amazon Web Services クラウドデザインパターン 実装ガイド 改訂版 日経BP Next ICT選書

  • 作者: アマゾンデータサービスジャパン玉川憲,片山暁雄,アイレット鈴木宏康
  • 出版社/メーカー: 日経BP社
  • 発売日: 2015/04/01
  • メディア: Kindle版
  • この商品を含むブログを見る





説明資料(英語コンソール版)
https://aws-ref.s3.amazonaws.com/handson/building_3tier_on_vpc_ver9.2.pdf

説明資料(日本語コンソール版)
https://aws-ref.s3.amazonaws.com/handson/building_3tier_on_vpc_ver9.2_ja.pdf



最終的には、↓ のような構成のシステムを構築していきます。
f:id:akiyoko:20150603230204p:plain

やっていること

  • VPC とサブネットを活用
    • パブリックなサブネットとプライベートなサブネットを明確に分離
    • 別アベイラビリティゾーンにも同様に、パブリックなサブネットとプライベートなサブネットを配置
  • Elastic Load Balancer による Webサーバの冗長化
    • Multi-Server, Multi-Datacenterパターン
  • RDS をインターネットに直接接続しないプライベートサブネットに配置してセキュリティを向上
  • RDS を別アベイラビリティゾーンに レプリケーションさせることで可用性を向上
    • DB Replicationパターン

やっていないこと

  • IAM によるセキュリティ管理
  • Route53 による独自ドメイン管理
  • AutoScaling によるクラスターの伸縮
  • CloudWatch による監視
  • SSL による通信暗号化

 

 

Phase 0:VPC の作成

AWSクラウド上に、VPC とサブネットを作成します。


【 完成形となる構成図 】
f:id:akiyoko:20150603231532p:plain



最終的なサブネットはこのようになります。

# AZ インターネットに接続可能? サブネット名 CIDR
1 1a パブリック T1-Public #1 10.0.0.0/24
2 1c パブリック T1-Public #2 10.0.1.0/24
3 1a プライベート T1-Private #1 10.0.2.0/24
4 1c プライベート T1-Private #2 10.0.3.0/24



 
まずはじめに、リージョンは「Tokyo」にします。
f:id:akiyoko:20150603232914p:plain

「Networking」から、「VPC」を選択します。
f:id:akiyoko:20150603235246p:plain

VPC作成ウィザードを開始します。
f:id:akiyoko:20150603235314p:plain

「VPC with a Single Public Subnet」を選択し、VPCを作成しつつ、パブリックなサブネットも作成していきます。
f:id:akiyoko:20150603235344p:plain

IP CIDR block 10.0.0.0/16
VPC name 任意の名前。ここでは、「T1」
Public subnet 10.0.0.0/24 251個のIPが確保できる
Availability Zone ap-northeast-1a 1a側を指定
Subnet name T1-Public #1

を入力し、「Create VPC」をクリックします。
f:id:akiyoko:20150603235533p:plain


VPCが作成されました。
(VPCが 2つ表示されていますが、もう1つは、アカウント作成時のデフォルトVPC です。)
f:id:akiyoko:20150604000127p:plain


ここで、「Filter by VPC」を使ってフィルタリングすれば、指定したVPC に関連したリソースしか表示されなくなるので、非常に便利です。
f:id:akiyoko:20150604000323p:plain


作成されたサブネットを確認します。
「Route Table」タブをクリックすることで、ルートテーブルを確認することができます。なお、「VPC with a Single Public Subnet」ウィザードを使って初めに作成されたこのサブネットだけ、IGW に接続できるようになっています。

f:id:akiyoko:20150604001145p:plain


あと3つのサブネットを追加していきます。
f:id:akiyoko:20150604001855p:plain

f:id:akiyoko:20150604001922p:plain

このようにして、全部で4つのサブネットを用意します。

# AZ インターネットに接続可能? サブネット名 CIDR
1 1a パブリック T1-Public #1 10.0.0.0/24
2 1c パブリック T1-Public #2 10.0.1.0/24
3 1a プライベート T1-Private #1 10.0.2.0/24
4 1c プライベート T1-Private #2 10.0.3.0/24

f:id:akiyoko:20150604003306p:plain


2番目のサブネットがインターネットに接続できない状態になっているので、ルートテーブルを現在選択されているものから変更します。

f:id:akiyoko:20150604003337p:plain

f:id:akiyoko:20150604003349p:plain

f:id:akiyoko:20150604003402p:plain




 

Phase 1:EC2 の作成

WordPress を最小構成(Web + DB 1台構成)で構築して、インスタンスに Elastic IP を付与します。


【 完成形となる構成図 】
f:id:akiyoko:20150603231543p:plain



f:id:akiyoko:20150604011445p:plain


f:id:akiyoko:20150604011503p:plain


f:id:akiyoko:20150604011517p:plain


f:id:akiyoko:20150604011533p:plain

Network T1 作成した VPC を選択
Subnet T1-Public #1
Auto-assign Public IP Enable Public IP を自動的に付与。今回は後で Elastic IP を付与するので、結局破棄される

と入力して、「Next」をクリック。
f:id:akiyoko:20150604011826p:plain

ストレージはそのまま。
f:id:akiyoko:20150604012317p:plain

「Name」タグは、適当に「T1-Web #1」と入力。
f:id:akiyoko:20150604013029p:plain

セキュリティグループを新たに作成します。セキュリティグループ名は適当に「T1-Web」などとします。

また、セキュリティグループ作成時に、22番と80番ポートを許可します。

Type Protocol Port Range Source
SSH TCP 22 MyIP
HTTP TCP 80 MyIP

f:id:akiyoko:20150604013933p:plain


f:id:akiyoko:20150604013948p:plain

キーペアを新たに作成して、ダウンロードしておきます。
f:id:akiyoko:20150604014004p:plain

「Launch Instance」をクリックして、インスタンスを起動します。
f:id:akiyoko:20150604014204p:plain

「running」になりました。
f:id:akiyoko:20150605113806p:plain


次に、作成したインスタンスに、Elastic IP を付与していきます。
f:id:akiyoko:20150604015925p:plain

f:id:akiyoko:20150604015938p:plain

f:id:akiyoko:20150604015954p:plain

f:id:akiyoko:20150604020006p:plain

f:id:akiyoko:20150604020019p:plain

f:id:akiyoko:20150605113956p:plain


続いて、作成したインスタンスに SSHで乗り込んで、WordPress をインストールしていきます。

$ chmod 600 ~/Downloads/T1-key.pem
$ ssh -i ~/Downloads/T1-key.pem ec2-user@52.68.117.22

 
以降、root で操作します。

$ sudo -i

 
MySQL をインストールします。

# yum install -y mysql-server
# service mysqld start
# chkconfig --level 345 mysqld on
# mysqladmin -u root -h localhost password 'Password1'

# mysql -p
(Enter password: Password1)
mysql> CREATE DATABASE wordpress;
mysql> GRANT ALL ON wordpress.* to admin@localhost;
mysql> FLUSH PRIVILEGES;
mysql> SET PASSWORD FOR admin@localhost=password('Password1');
mysql> exit

 
次に、Nginx + PHP をインストールします。

# yum install -y nginx
# yum install -y php php-fpm php-mbstring php-mysql

# service nginx start
# service php-fpm start

# chkconfig --level 345 nginx on
# chkconfig --level 345 php-fpm on

 
Nginx で PHP を実行するように設定します。

# cat << EOF > /etc/nginx/conf.d/wordpres.conf
server {
  listen 80;
  location / {
    root /var/www/html;
    index index.php index.html;
  }
  location ~ \.php$ {
    root /var/www/html;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
    include fastcgi_params;
  }
}
EOF

 
WordPress をインストールします。

# service nginx restart

# wget http://wordpress.org/latest.tar.gz
# tar xzvf latest.tar.gz
# mv wordpress/* /var/www/html/
# chown -R apache:apache /var/www/html/

 
ブラウザで、Elastic IP
http://52.68.117.22/
にアクセスします。

f:id:akiyoko:20150605021822p:plain

f:id:akiyoko:20150605021848p:plain

MySQL ユーザ「admin」のパスワードは「Password1」です。
f:id:akiyoko:20150605021858p:plain

f:id:akiyoko:20150605021908p:plain

WordPress管理者「admin」のパスワードは「Password2」としておきます。
f:id:akiyoko:20150605023230p:plain

WordPress のインストールが完了しました。
f:id:akiyoko:20150605022804p:plain



 

Phase 2:RDS の作成

WordPress を Web + DB の 2台構成で構築します。


【 完成形となる構成図 】
f:id:akiyoko:20150603231558p:plain



まず先に、DB用のセキュリティグループを作成しておきます。
f:id:akiyoko:20150605024356p:plain

セキュリティグループ名 T1-DB(任意)
VPC T1

とし、3306番ポートをセキュリティグループ「T1-Web」に対して解放します。
f:id:akiyoko:20150605024418p:plain



RDS の管理ページを開きます。
f:id:akiyoko:20150605030745p:plain


まず、DBサブネットグループを作成します。
f:id:akiyoko:20150605030802p:plain

DBサブネットグループ名、および VPC は以下のように設定し、

Name t1-db(任意) 英大文字は作成後に小文字に変換される?
VPC ID T1

1a および 1c、それぞれのアベイラビリティゾーンから、プライベートなサブネットを追加します。
f:id:akiyoko:20150605030816p:plain

f:id:akiyoko:20150605030828p:plain

「Create」ボタンをクリック。
f:id:akiyoko:20150605030838p:plain

DBサブネットグループが作成されました。
f:id:akiyoko:20150605030956p:plain



続いて、RDS インスタンスを作成していきます。
f:id:akiyoko:20150605033532p:plain

MySQL を選択します。
f:id:akiyoko:20150605033546p:plain

非Multi-AZ 構成とします。
f:id:akiyoko:20150605033612p:plain

検証用なので、最小インスタンスタイプを選択します。

DB Instance Class db.t2.micro
Multi-AZ Deployment No


RDSインスタンスの管理者のユーザ名とパスワードを設定します。

DB Instance Idetifier t1-wp-db ホスト名の一部になります
Master Username admin
Master Password Password1

f:id:akiyoko:20150605033647p:plain

ネットワークの設定をします。

VPC T1
Subnet Group t1-db
Publicly Accessible No
Availability Zone ap-northeast-1a
VPC Security Group(s) T1-DB


データベース名(Database Name)は、「wordpress」とします。
なお、RDS 1インスタンスにつき、データベースは1つとなります。


検証用なので、バックアップは取らない設定にしておきます。「Backup Retention Period」を「0 days」にすれば OK です。
f:id:akiyoko:20150605033703p:plain

RDSインスタンスの起動には、5分くらいかかります。
起動したら、RDSインスタンスのエンドポイントを確認しておきます。
f:id:akiyoko:20150605035308p:plain


Webサーバの EC2インスタンスから、RDSインスタンスに接続できることを確認します。

# mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress
(Enter password: Password1)

mysql> show tables;
Empty set (0.00 sec)

mysql> exit

「wordpress」というデータベースは存在しますが、当然ながらテーブルはまだ一つもありません。


 
次に、RDSにデータ移行をするために、EC2上の MySQLレコードをエクスポートします。

# service nginx stop
# mysqldump -u root -p wordpress > wordpress.sql
(Enter password: Password1)
# service nginx start

 
EC2上の mysqld はもう使わないので、stop しておきます。

# service mysqld stop
# chkconfig --level 345 mysqld off

 
エクスポートしたデータを、RDS にインポートします。

# mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress < wordpress.sql
(Enter password: Password1)

 
RDSに正常にインポートできたか、チェックします。

$ mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress
(Enter password: Password1)

mysql> show tables;
+-----------------------+
| Tables_in_wordpress   |
+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+
11 rows in set (0.00 sec)

mysql> exit


ここから少し WordPressのテクニカルな部分になりますが、WordPress の DB接続設定を初期化するために、WordPress の設定ファイルを一旦待避します。

# mv /var/www/html/wp-config.php /var/www/html/wp-config_bk.php

 
待避させてから、
http://52.68.117.22/
に再びアクセスして、WordPress を再インストールしていきます。

 
「データベースのホスト名」に、RDSインスタンスのエンドポイントを設定します。
f:id:akiyoko:20150605105600p:plain

f:id:akiyoko:20150605105700p:plain

WordPress の再インストールが完了しました。



 

Phase 3:ELB の作成

LB + Web × 2 + DB のサーバ 3台構成を構築します。


【 完成形となる構成図 】
f:id:akiyoko:20150603231611p:plain



はじめに、Webサーバの AMI を作成していきます。

f:id:akiyoko:20150605114224p:plain

f:id:akiyoko:20150605111604p:plain

f:id:akiyoko:20150605114241p:plain

Status が「available」になるのを待ちます。
f:id:akiyoko:20150605111630p:plain



作成した AMI から、2台目の Webサーバインスタンスを起動します。

f:id:akiyoko:20150605120022p:plain

f:id:akiyoko:20150605120048p:plain

1c 側のアベイラビリティゾーンで起動するように、ネットワーク、サブネットを指定します。
f:id:akiyoko:20150605120106p:plain

f:id:akiyoko:20150605120124p:plain

f:id:akiyoko:20150605120141p:plain

1台目の Webサーバと同じセキュリティグループを選択します。
f:id:akiyoko:20150605120154p:plain

f:id:akiyoko:20150605120217p:plain

キーペアも同じものを選択します。
f:id:akiyoko:20150605120238p:plain

2台のインスタンスが起動しました。
f:id:akiyoko:20150605120250p:plain


 
続いて、ELB を作成していきます。

f:id:akiyoko:20150605125207p:plain

Load Balancer name T1-LB
Create LB Inside VPC を選択

を設定し、Selected Subnets で管理対象とするサブネットを選択します。

f:id:akiyoko:20150605125219p:plain

新たにセキュリティグループを作成します。
f:id:akiyoko:20150605131124p:plain

f:id:akiyoko:20150605125253p:plain

ヘルスチェックの設定を調整します。
f:id:akiyoko:20150605125305p:plain

管理する EC2インスタンスを選択します。
f:id:akiyoko:20150605125332p:plain

タグは何も設定せずそのまま。
f:id:akiyoko:20150605125345p:plain

f:id:akiyoko:20150605130303p:plain

f:id:akiyoko:20150605130316p:plain

ELB は作成されましたが、インスタンスのヘルスチェックは「OutOfService」のままです。これは、インスタンスのセキュリティグループが「MyIP」しか許可していない状態になっているからです。
f:id:akiyoko:20150605130326p:plain


そこで、インスタンスのセキュリティグループの「HTTP」を、ELB からアクセスできるように(ELB のみをアクセス許可するように)設定変更していきます。

f:id:akiyoko:20150605130339p:plain

HTTP の Source に「T1-LB」を設定します。
f:id:akiyoko:20150605130356p:plain
f:id:akiyoko:20150605130411p:plain

ELB のヘルスチェックが、どちらも「InService」になりました。
f:id:akiyoko:20150605130424p:plain

疎通が完了したら、ELB の DNS名をチェックしておきます。
f:id:akiyoko:20150605132925p:plain



 
WordPress の HTML内のリンク先ホスト名がインストール時の EIP になっているので、それを ELB のホスト名に書き換える必要があります。

そこで、以下のコマンドをどちらかの Webサーバ上で実行します。

# mysql -u admin -p -h t1-wp-db.cgxyjyymghsx.ap-northeast-1.rds.amazonaws.com wordpress
(Enter password: Password1)

mysql> update wp_options set option_value='T1-LB-53959373.ap-northeast-1.elb.amazonaws.com' where option_name='siteurl' or option_name='home';


変更処理が完了したら、ELB の DNS名でアクセスします。
http://T1-LB-53959373.ap-northeast-1.elb.amazonaws.com/
f:id:akiyoko:20150605132816p:plain


アクセスできました。





 

Phase 4:RDS のレプリケーション

最後に、LB + Web × 2 + DB × 2 のサーバ4台構成を構築していきます。


【 完成形となる構成図 】
f:id:akiyoko:20150603230204p:plain



RDS の管理ページから、RDS インスタンスの設定を変更します。

f:id:akiyoko:20150605134823p:plain

Multi-AZ Deployment Yes
Apply Immediately チェックを付ける

とするだけで、すぐに設定変更できます。
f:id:akiyoko:20150605134843p:plain

f:id:akiyoko:20150605134903p:plain


設定変更には少し時間(5分くらい)がかかります。容量に応じて必要な時間が変わってくるそうです。

f:id:akiyoko:20150605134918p:plain
f:id:akiyoko:20150605134933p:plain

Status が「modifying」から「available」になり、Multi-AZ が「Yes」に変われば、設定変更が完了です。



なお、マスターに障害が発生した場合の RDSのフェイルオーバーは 1〜3分で完了するそうです。また、ディスクのブロックレベルのレプリケーションができる設計になっているので、データのロスはほぼ無いとのこと。