おいおいおい。AWSをはじめて,そろそろ初心者を名乗っても良いかなと思い始めた今も,俺は結局AWSのCLIでしか作業していないじゃないか,ミドルウェアというものはどこに行ってしまったんだ。
コマンドラインでデータベースを起動したら,それが自動でレプリケーションされるわ,バックアップは取られているわでかなり便利になっているのはわかった。でも,なんか物足りなさを感じている。今日はもうクラウドの醍醐味を味わうために,AutoScalingというのに挑戦してみることにする。
AMI
とりあえず,俺はWebアプリケーションを動かす事をしてみたいから何か適当に構築しながらAutoScalingを楽しんで行ってみたいと思う。最終回にしてやっとEC2にログインしてpingとexit以外のコマンドを打つ時が来た。AuctoScalingというのを使うためにはまずはAMIというのを作る必要があるらしい。まずは既存のイメージからEC2を起動し,簡単なWEBアプリケーションを作り,そこからAMIを作成するということをする。
AMIを作るときのVPCは特にどこでも良いらしい。ただ,Security Groupのことなどを考えると,動かしたい所でAMIを作ったほうが,あとあとの手間が減りそうなのは想像がつくから,稼働させたいVPCで作ることにする。
ちょっとこのあたりで,先週までに作っていた構成を確認も兼ねてまとめてみることにする。
$ aws ec2 describe-vpcs $ aws ec2 describe-subnets $ aws ec2 describe-internet-gateways $ aws ec2 describe-route-tables
これでネットワークのCIDRとそれぞれのIDを列挙しておくことができた。
これがあったほうがこの後の作業が楽だということにはこの数日間で思い知らされている。もし,CLIだけでやるときは,できることなら,この図のようにidとCIDRのセットをまとめておくことをおすすめする。
$ aws ec2 describe-key-pairs
key-pairの名前もこれで[id_rsa]だということがわかった。
$ aws ec2 describe-security-groups
今回はSecurity Groupについてはもう一度作り直していくことにした。
$ aws ec2 create-security-group --vpc-id vpc-6ac1020f --group-name webapp-ssh --description "eccube-web server ssh SG" { "GroupId": "sg-d2e353b7" }
Security Groupを作ったら,sshが接続できるようにする。
$ aws ec2 authorize-security-group-ingress --group-id sg-d2e353b7 --port 22 --protocol tcp --cidr m.y.I.p/32
Security Group管理表
ID | Name | Source | Protocol |
---|---|---|---|
sg-d2e353b7 | webapp-ssh | myIp | TCP:22 |
改めてEC2を起動しようと思ったけど,AMIのIDを覚えていないので,もう一度AMIのIDを調べるところからやり直す。これは,今後も頻繁に発生しそうだから,何かしらScriptを作っておくといいんだろう。
$ aws ec2 describe-images --owners amazon |jq '.[][] |select(.ImageType == "machine") | {"Name" :.Name,"ImageId":.ImageId }' |grep -A 1 amzn-ami-hvm
このコマンドで,一番新しそうなamiを探して,起動時の--image-idに指定する
$ aws ec2 run-instances --key-name id_rsa --instance-type t2.micro --subnet-id subnet-d806ee81 --associate-public-ip-address --security-group-ids sg-d2e353b7 --image-id ami-35072834
これでEC2が立ち上がった。
__| __|_ ) _| ( / Amazon Linux AMI ___|\___|___|
無事にログインもできたし,ここからはついにping以外のコマンドを投入していく時間だ。
$ sudo yum install httpd mysql php php-mbstring php-pdo php-mysql php-mcrypt $ sudo chkconfig httpd on
なんだろう。いつもなら何も感じないこんなコマンドも,クラウド上でやるとこんなに感動的なのか。
とりあえず,今起動したApacheの動作を見るために,Security GroupでHTTPを開ける。
$ aws ec2 create-security-group --vpc-id vpc-6ac1020f --group-name webapp-http --description "eccube-web server http SG" { "GroupId": "sg-b15eeed4" } $ aws ec2 authorize-security-group-ingress --group-id sg-b15eeed4 --port 80 --protocol tcp --cidr 0.0.0.0/0
これで,Security Groupはこうなっている。
ID | Name | Source | Protocol |
---|---|---|---|
sg-d2e353b7 | webapp-ssh | myIp | TCP:22 |
sg-b15eeed4 | webapp-http | 0.0.0.0/0 | TCP:80 |
今作ったhttpへのアクセスを認めていたSecurity Group webapp-httpを起動しているインスタンスにくっつけてみる。さっきEC2を起動した時にpublic IPばかり気にしてしまっていて,instance-idを残しておくのを忘れてしまっていた。
describe-instancesでインスタンスの情報を取得するというのも有りだけど,今回は別の方法でinstance-idを調べてみる。インスタンスにsshで接続できている事が前提になるけど,ec2-metadataというコマンドがあって,そのec2のいろいろな情報が見られる。
$ ec2-metadata ami-id: ami-35072834 ami-launch-index: 0 ami-manifest-path: (unknown) ancestor-ami-ids: not available block-device-mapping: ami: /dev/xvda root: /dev/xvda instance-id: i-44eb0fb1 instance-type: t2.micro local-hostname: ip-172-16-32-209.ap-northeast-1.compute.internal local-ipv4: 172.16.32.209 kernel-id: not available placement: ap-northeast-1c product-codes: not available public-hostname: public-ipv4: 54.x5.1xx.176 public-keys: keyname:id_rsa index:0 format:openssh-key key:(begins from next line) ssh-rsa =*********************************************************************************************************************==_id_rsa ramdisk-id: not available reservation-id: r-033810f1 security-groups: webapp-ssh user-data: not available
けっこう便利かもしれない。これでinstance-idがわかったので,改めてSecurity Groupを付けなおす。Security Groupをつけるときは,modify-instance-attribute だろう多分。
$ aws ec2 modify-instance-attribute --groups sg-d2e353b7 sg-b15eeed4 --instance-id i-44eb0fb1
そしてApacheを起動して
$ sudo service httpd start
ブラウザでアクセスしてみる。
“Amazon Linux AMI Test Page”と無事に表示された。感無量。
このままテストページで何かしても面白くないので,何かデータベースとつなぐものを動かしたい。そのためにもまずはSecurity Groupの設定を,今作ったmysql用のSecurity GroupをEC2とRDSにそれぞれ割り当てる。
$ aws ec2 create-security-group --group-name webapp-mysql --vpc-id vpc-6ac1020f --description mysql { "GroupId": "sg-b4ac1fd1" } $ aws ec2 authorize-security-group-ingress --group-id sg-b4ac1fd1 --source-group sg-b4ac1fd1 --port 3306 --protocol tcp
ID | Name | Source | Protocol |
---|---|---|---|
sg-d2e353b7 | webapp-ssh | myIp | TCP:22 |
sg-b15eeed4 | webapp-http | 0.0.0.0/0 | TCP:80 |
sg-b4ac1fd1 | webapp-mysql | sg-b4ac1fd1 | TCP:3306 |
$ aws ec2 modify-instance-attribute --groups sg-d2e353b7 sg-b15eeed4 sg-b4ac1fd1 --instance-id i-44eb0fb1 $ aws rds modify-db-instance --vpc-security-group-ids sg-b4ac1fd1 --db-instance-identifier test-db
Security Groupを変更してみて,EC2からデータベースにアクセスできるのかどうかを確かめてみる。
$ mysql -h test-db.**********.ap-northeast-1.rds.amazonaws.com -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 5.6.19-log MySQL Community Server (GPL) Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
mysqlに接続できること。なんだろう,当たり前のことなんだけど,環境がクラウドになるだけでこんなにも嬉しいものなのかという感動をかみしめている。
簡単なWebアプリケーション
ミドルウェアとかその辺はこれで良いと思うけれど,今度はWebアプリケーションを作って動かしてみたいと思う。その前に,PHPでTimeZoneを設定しておく。
$ diff -Nur /etc/php.ini /etc/php.ini.orig --- /etc/php.ini 2015-02-21 09:09:04.988734049 +0000 +++ /etc/php.ini.orig 2015-02-21 09:05:49.630312476 +0000 @@ -953,7 +953,7 @@ [Date] ; Defines the default timezone used by the date functions ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone -date.timezone = Asia/Tokyo +;date.timezone = ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.default-latitude ;date.default_latitude = 31.7667
そして,index.phpを作る。
<html> <head> <title>test application</title> </head> <body> <h1>InstanceID = <?php $instance_id = file_get_contents('http://169.254.169.254/latest/meta-data/instance-id'); echo $instance_id; ?></h1> あなたは <?php $dsn = 'mysql:dbname=counter;host=test-db.cojvgercnfvt.ap-northeast-1.rds.amazonaws.com'; $user = 'USERNAME’; $password = *************; try{ $dbh = new PDO($dsn, $user, $password); $sql = "SELECT counter FROM counter LIMIT 1"; $stmt = $dbh->query($sql); $result = $stmt->fetch(PDO::FETCH_ASSOC); echo $result['counter']; $sql = 'update counter set counter = counter + 1; '; $stmt = $dbh->prepare($sql); $flag = $stmt->execute(array()); $dbh = null; }catch (PDOException $e){ print('Connection failed:'.$e->getMessage()); die(); } ?>人目の訪問者です。 </body> </html>
すごくシンプルに,インスタンスIDとアクセスカウンターを表示するだけのアプリケーションをGoogleとコピペを駆使して頑張って開発した。
このアプリケーションをAutoScalingでスケーリングさせてみる。そのためにはまず,このアプリケーションの入ったインスタンスからAMIを作らなくちゃいけない。
$ aws ec2 create-image --instance-id i-44eb0fb1 --name access-counter-version-1 { "ImageId": "ami-e118fbe1" }
できているかの確認をするために,describe-images というコマンドを --owners をselfにして実行しみる。
$ aws ec2 describe-images --owners self { "Images": [ { ~略~ "ImageId": "ami-e118fbe1", "State": "pending", } ~略~ ] }
State:の所がpendingからavailableになればAMIの作成は完了だ。