2011年8月31日水曜日

SQS & CloudWatch & Auto Scaling、その後

スズキです。

下記のように"SQS"と"Auto Scaling"を使って、
"SQS"と"CloudWatch"と"Auto Scaling"
複数インスタンスでクロールする仕組みを運用しています。

はじめ、下記のように"CloudWatch"のカスタムメトリクスを使って、
SQSのキューのサイズ(メッセージ数)と"Auto Scaling"の連携をとっていたのですが、
SQSのキューのサイズをCloudWatchに登録
下記のように、SQSのメトリクス自体が標準でサポートされるようになりました。
CloudWatchでSQSのメトリクスが取得可能に
ですので、現在は"Auto Scaling"のトリガーとなるメトリクスはカスタムメトリクスではなく、
標準のSQSのメトリクス(ApproximateNumberOfMessagesVisible)を利用するように
変更しました。

ということで現状、下記のような仕組みで処理しています。
  1. SQSにクロールしたい対象ID一つを一つのメッセージとして一気に登録する。
  2. SQSのメッセージ数が0以上になると指定した数だけインスタンスが起動しキューの
    メッセージを処理(該当IDでクロール)する。
  3. SQSのメッセージ数が0になったらすべてのインスタンスがターミネートする。

また下記のようにSQSのメトリクスを監視し通知を受けることで、
クロール処理の状況をリアルタイムに把握できるようにもしています。

ApproximateNumberOfMessagesVisible

値が0以上になったらクロール処理開始、0にもどったらクロール処理終了として
通知するようにしています。

NumberOfMessageReceived

値が0以上になったらクロール処理開始、0にもどったらクロール処理が停止(正常 or 異常)
として通知するようにしています。詳細は下記となります。
SQSのキューのメッセージが処理されなくなったら通知(CloudWatch)

ここまででもAWSの機能をふんだんに利用した、定時でのバッチ処理システムですが、
さらにやりたいことがあります。

現在SQSへのメッセージ登録は、常時起動しているEC2から"cron"にて行っているのですが、
下記で紹介したように"Auto Scaling"を利用すれば、指定した時刻にインスタンスを
立ち上げることができるので、
"Auto Scaling"で指定時刻にEC2インスタンスを起動
起動時と同時にSQSにメッセージを登録して、登録し終わったらインスタンスが
ターミネートするようにできるのでは、と思っています。

これができると、定時のバッチ処理が常時起動しているサーバ無しに、サーバが遊ぶこと無く
実施することができるはずです。サーバの稼動時間がかなり限定される形になるので、
コストも大幅に下げることができると思います。

ということで上記が実現できたら、また、このブログで紹介します。乞うご期待!
--------
http://www.suz-lab.com

2011年8月30日火曜日

Varnish経由でS3のコンテンツをPOSTで取得(Facebookアプリ用)

スズキです。

下記のようにS3にはPOSTでアクセスすることができません。
S3のコンテンツにPOSTでアクセスできない
なので、FacebookアプリのコンテンツをS3に置こうとすると、
FacebookはS3にPOSTでコンテンツを取得しにいくので、うまくいきません。

ということで、一旦FacebookはVarnishにアクセスし、VarnishがPOSTをGETに書き換え
S3からコンテンツを取得できるようにしてみました。

FacebookからS3までのコンテンツ取得経路は下記となり、
Facebook → ELB(www.suz-lab.com) → Varnish → S3(origin.suz-lab.com)
設定ファイル(/etc/varnish/default.vcl)は次の通りです。

backend default {
    .host = "localhost";
    .port = "80";
}
sub vcl_recv {
    if (req.url == "/healthcheck.txt") {
        return (error);
    }
    if(req.http.host == "www.suz-lab.com") {
        set req.backend   = suz_lab;
        set req.http.host = "origin.suz-lab.com";
        set req.request   = "GET";
        return (pass);
    }
    return (lookup);
}
sub vcl_error {
    set obj.http.Content-Type = "text/plain; charset=utf-8";
    if (req.url == "/healthcheck.txt") {
      set obj.status = 200;
      synthetic {"healthcheck"};
    }
    return (deliver);
}
backend suz_lab {
  .host = "origin.suz-lab.com";
  .port = "80";
}

ポイントは下記で、
set req.backend = suz_lab;
バックエンドを指定して、
set req.http.host = "origin.suz-lab.com";
HOSTヘッダを書き換えて、
set req.request = "GET";
メソッドも書き換えて、
return (pass);
キャッシュを利用しないようにしています。

これでFacebookアプリのコンテンツをS3で運用することができるようになりました。

ニーズはあまりないだろうなー...
--------
http://www.suz-lab.com

VarnishでELBヘルスチェックに対応させる

スズキです。

バックエンド関係無しに対応させる方法です。
といってもVarnishで、ELBにてヘルスチェック用に指定したパス(/healthcheck.txt)が、
ステータス200で返るようにすればOKです。

設定ファイル(/etc/varnish/default.vcl)は下記のような感じです。

backend default {
  .host = "www.suz-lab.com";
  .port = "80";
}
sub vcl_recv {
    if (req.url == "/healthcheck.txt") {
        return (error);
    }
    return (lookup);
}
sub vcl_error {
    set obj.http.Content-Type = "text/plain; charset=utf-8";
    if (req.url == "/healthcheck.txt") {
      set obj.status = 200;
      synthetic {"healthcheck"};
    }
    return (deliver);
}

これで"/healthcheck.txt"へのアクセスはVarnishが生きている限り、
とにかくステータス200を返すようになり、ELBから切り離されなくなります。

次はFacebook用Varnishかな。
--------
http://www.suz-lab.com

Varnishのログを確認

スズキです。

Varnishのログはファイルではなく共有メモリに出力されます。
なので、ログを確認するには"varnishlog"という専用のコマンドを利用します。

実際、下記のようにログは出力されます。

# varnishlog
   13 SessionOpen  c xxx.xxx.xxx.xxx 14608 :80
   13 ReqStart     c xxx.xxx.xxx.xxx 14608 472752705
   13 RxRequest    c GET
   13 RxURL        c /form.html
   13 RxProtocol   c HTTP/1.1
   13 RxHeader     c Host: ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
   13 RxHeader     c Connection: keep-alive
   13 RxHeader     c Cache-Control: max-age=0
   13 RxHeader     c User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30
   13 RxHeader     c Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
   13 RxHeader     c Accept-Encoding: gzip,deflate,sdch
   13 RxHeader     c Accept-Language: ja,en-US;q=0.8,en;q=0.6
   13 RxHeader     c Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.3
   13 RxHeader     c Cookie: BX=bccskvt72b1sa&b=3&s=vb
   13 RxHeader     c If-None-Match: "062704cdcec5d810241a3aab8bfaba45"
   13 RxHeader     c If-Modified-Since: Mon, 29 Aug 2011 09:24:05 GMT
   13 VCL_call     c recv
   13 VCL_return   c pass
   13 VCL_call     c hash
   13 VCL_return   c hash
   13 VCL_call     c pass
   13 VCL_return   c pass
   13 Backend      c 14 default default

また、CentOS6で"yum"でのインストールの場合、"/etc/init.d/varnishlog"という、
サービススクリプトもあります。
中身をみると、結局"varnishlog"コマンドが実行されているのですが、
下記のオプションがついています。

DAEMON_OPTS="-a -w $logfile -D -P $pidfile"

オプションの詳細は下記となりますが、このサービスを実行することで
Varnishのログがファイルに出力されるようになります。

-a'      When writing to a file, append to it rather thanoverwrite it.
         (追記モードでファイルに出力)
-w file' Write log entries to file instead of displaying them. The file will be overwritten unless the -a option was specified.
         (出力ファイルを指定)
-D'      Daemonize.
         (デーモンモードで実行)
-P file' Write the process's PID to the specified file
         (PID保存ファイルを指定)

ログは"/var/log/varnish/varnish.log"に出力されますが、
バイナリ形式で保存されているので、確認するにはやはり下記のように、
"varnishlog"コマンドを利用する必要があります。

# varnishlog -r /var/log/varnish/varnish.log

Facebook用Varnish、もうすぐできるかも...
--------
http://www.suz-lab.com

2011年8月29日月曜日

SQSのキューのメッセージが処理されなくなったら通知(CloudWatch)

スズキです。

キューのメッセージが0になったときに通知することは、よくやると思いますが、
ここではキューのメッセージが処理されなくなったときの通知に関してです。

当然CloudWatchを利用するわけですが、キューのメッセージが処理されなくなったか
どうかは、アプリケーションが受信したメッセージ数を表す下記の
"NumberOfMessageReceived"を確認することで可能です。
キューのメッセージが処理されなくなった場合は、"NumberOfMessageReceived"が「0」
になるはずです。


そして、この"NumberOfMessageReceived"に対して、下記のようにアラームを作成します。
ここでは値が「0」になったら(メッセージが処理されなくなったら)
アラーム状態になるようにしています。


メールは下記のように、状態が「ALARM」「OK」「INSUFFICIENT_DATA」になったとき、
つまり、すべての状態に対して、その変わり目に送信されるようにしました。


SNSを確認すると下記のように上記で指定した通知先(メールアドレス)が作られてますが、
まだ"PendingConfirmation"の状態で有効にはなっていません。


この状態では、次のようなメールが送られているはずなので"Confirm subscription"を
クリックすることで有効になります。

You have chosen to subscribe to the topic: 
arn:aws:sns:ap-northeast-1:238042831511:golfans

To confirm this subscription, click or visit the link below (If this was in error no action is necessary):
Confirm subscription

Please do not reply directly to this e-mail. If you wish to remove yourself from receiving all future SNS subscription confirmation requests please send email to sns-opt-out

有効になると、下記のように"Subscription ID"がふられます。


実際に通知時に送られてくるメールは下記のようなものとなります。


[ALARM] Alarm "ZeroMessageReceived" in APAC - Tokyo is now in state ALARM
You are receiving this email because your Amazon CloudWatch Alarm "ZeroMessageReceived" in the APAC - Tokyo region has entered the ALARM state, because "Threshold Crossed: 1 datapoint (0.0) was less than or equal to the threshold (0.0)." at "Sunday 28 August, 2011 20:56:25 UTC".

View this alarm in the AWS Management Console:
...

Alarm Details:
- Name:                       ZeroMessageReceived
- Description:                ZeroMessageReceived
- State Change:               OK -> ALARM
- Reason for State Change:    Threshold Crossed: 1 datapoint (0.0) was less than or equal to the threshold (0.0).
- Timestamp:                  Sunday 28 August, 2011 20:56:25 UTC

Threshold:
- The alarm is in the ALARM state when the metric is LessThanOrEqualToThreshold 0.0 for 300 seconds.

Monitored Metric:
- MetricNamespace:            AWS/SQS
- MetricName:                 NumberOfMessagesReceived
- Dimensions:                 [QueueName = crawl]
- Period:                     300 seconds
- Statistic:                  Sum
- Unit:                       not specified

State Change Actions:
- OK: [arn:aws:sns:ap-northeast-1:000000000000:suz-lab]
- ALARM: [arn:aws:sns:ap-northeast-1:000000000000:suz-lab]
- INSUFFICIENT_DATA: [arn:aws:sns:ap-northeast-1:000000000000:suz-lab]

これでアプリケーションの処理が途中でとまっても、すぐに検知できます。
--------
http://www.suz-lab.com

S3のコンテンツにPOSTでアクセスできない

スズキです。

FacebookアプリのコンテンツはFacebookがPOSTで取得しにくるのですが、
それをS3に置こうと思ったら、S3のコンテンツはPOSTでアクセスできないということで、
うまく行きませんでした...

ということで下記のHTMLで確認してみました。

<html>
  <body>
    <form method="GET">
        <input type="submit" value="GET"/>
    </form>
    <form method="POST">
        <input type="submit" value="POST"/>
    </form>
  </body>
</html>

GETボタンを押しても、当然GETでの取得なので問題ないのですが、


POSTボタンを押した場合は、下記のようなエラーになってしまいました。


"405 Method Not Allowed"ということで、POSTメソッドは許可されてないとのことです。

プロキシーサーバたてるか...
--------
http://www.suz-lab.com

なぜかOracleにつながらなくなったら(ORA-12514)

スズキです。

急に下記のようにOracleにつながらなくなりました。
(多分、何かはしたんだと思いますが、誰も心当たりはありません...)

$ sqlplus sys/password@localhost:1521/oracle.suz-lab.com as sysdba

SQL*Plus: Release 11.1.0.6.0 - Production on Fri Aug 26 01:50:25 2011

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

ERROR:
ORA-12514: TNS:listener does not currently know of service requested in connect
descriptor

リスナーがOracleのサービス名(oracle.suz-lab.com)を解決できないようです。

確かにリスナーを再起動してみると、

$ lsnrctl restart
...
The listener supports no services
...

サービスは登録されてないと言われてしまいます。

このような場合、一番かんたんな解決方法は、下記のように"listener.ora"に静的に
サービス名に関する記述をしてしまうことです。
(本来なら動的に登録されるはずですが...)

LISTENER =
    (DESCRIPTION_LIST =
        (DESCRIPTION =
            (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
            (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
        )
    )
SID_LIST_LISTENER =
    (SID_LIST =
        (SID_DESC =
            (GLOBAL_DBNAME = oracle.suz-lab.com)
            (ORACLE_HOME   = /u01/app/oracle/product/11.1.0/db_1)
            (SID_NAME      = oracle)
        )
    )

この状態で再度リスナーを再起動すると、
下記のようにサービスが登録されていることを確認することができます。

$ lsnrctl start
...
Service "oracle.suz-lab.com" has 1 instance(s).
Instance "oracle", status UNKNOWN, has 1 handler(s) for this service...
...

そして、最初と同じようにOracleに接続すると、今度は無事接続できることが確認できます。

$ sqlplus sys/password@localhost:1521/oracle.suz-lab.com as sysdba

SQL*Plus: Release 11.1.0.6.0 - Production on Fri Aug 26 02:01:19 2011

Copyright (c) 1982, 2007, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

本来なら自動登録ができてない理由を調査しないといけないんだけど、時間がないので...
--------
http://www.suz-lab.com

2011年8月28日日曜日

パーティション分割されたEBSを"resize2fs"で拡張

スズキです。

以前、"resize2fs"を使ってEBSの容量を増やす方法を紹介しましたが、
"resize2fs"でEBSの容量を増やす
この方法だと、EBSがパーティション分割されている場合、うまくいきません。

パーティション(/dev/sdf1)に対して"resize2fs"すると下記のようになり、

# resize2fs /dev/sdf1 
resize2fs 1.39 (29-May-2006)
The filesystem is already 5241198 blocks long.  Nothing to do!

大もとのEBS(/dev/sdf)対して"resize2fs"すると、下記のようになってしまいます。

# resize2fs /dev/sdf
resize2fs 1.39 (29-May-2006)
resize2fs: デバイスもしくはリソースがビジー状態です while trying to open /dev/sdf
Couldn't find valid filesystem superblock.

ですので、パーティション分割している場合は、下記のように"fdisk"で
パーティションの調整もしなければなりません。

# umount /home
# fdisk /dev/sdf
...
コマンド (m でヘルプ): p
...
デバイス Boot      Start         End      Blocks   Id  System
/dev/sdf1               1        2610    20964793+  83  Linux
...
コマンド (m でヘルプ): d
Selected partition 1
...
コマンド (m でヘルプ): n
コマンドアクション
e   拡張
p   基本領域 (1-4)
p
領域番号 (1-4): 1
最初 シリンダ (1-13054, default 1): 
Using default value 1
終点 シリンダ または +サイズ または +サイズM または +サイズK (1-13054, default 13054): 
Using default value 13054
...
コマンド (m でヘルプ): p
...
デバイス Boot      Start         End      Blocks   Id  System
/dev/sdf1               1       13054   104856223+  83  Linux
...
コマンド (m でヘルプ): w
...
ioctl() を呼び出して領域テーブルを再読込みします。
ディスクを同期させます。

上記はパーティション(/dev/sdf1)を一旦削除して、
終点シリンダを増加させたEBSにあったものにした形で作りなおしています。

そして、"resize2fs"です。

# mount /home
# df -k
Filesystem           1K-ブロック    使用   使用可 使用% マウント位置
/dev/sda1             10321208   1308404   8488516  14% /
none                   3932160         0   3932160   0% /dev/shm
/dev/sdf1             20635700  17689260   1898204  91% /home
# resize2fs /dev/sdf1 
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/sdf1 is mounted on /home; on-line resizing required
Performing an on-line resize of /dev/sdf1 to 26214055 (4k) blocks.
The filesystem on /dev/sdf1 is now 26214055 blocks long.
# df -k
Filesystem           1K-ブロック    使用   使用可 使用% マウント位置
/dev/sda1             10321208   1308404   8488516  14% /
none                   3932160         0   3932160   0% /dev/shm
/dev/sdf1            103210940  17705312  80264180  19% /home

今度は無事、サイズを拡張することができました。

EBSはパーティション分割するべきではないなー...
--------
http://www.suz-lab.com

2011年8月25日木曜日

MySQLのレプリケーションでマスターサーバを変更

スズキです。

EC2はStop/StartやAMIから起動し直したりすると"Private IP / Private DNS Name"が
変更されてしまいます。

MySQLのスレーブサーバで上記を直接指定している場合は、
変更されてしまうと下記のように接続エラーになってしまいます。

mysql> show slave status\G
...
Last_IO_Error: error connecting to master 'repl@ip-yyy-yyy-yyy-yyy.us-west-1.compute.internal:3306' - retry-time: 60  retries: 86400
...

このような場合は、下記のようにスレーブサーバ上で新しい"Private IP / Private DNS Name"を
指定すればOKです。

mysql> STOP SLAVE;
mysql> CHANGE MASTER TO MASTER_HOST='ip-xxx-xxx-xxx-xxx.us-west-1.compute.internal';
mysql> START SLAVE;

でも"Private IP"をhostsファイルで管理してれば、その書き換えですんだのに...
--------
http://www.suz-lab.com

(献本御礼)日経コンピュータ2011年8月4日号

スズキです。

日経BP社様から「日経コンピュータ2011年8月4日号」を
献本いただきました。

他にも興味深い記事があるのですが、
やはりAWS関係の特集である

クラウドのトラブル(Amazonの事例にみる三つの予防策)

に目がいってしまいました。

この記事は、まだ記憶に新しいAWSの2011/04/21に
US東岸リージョンで発生した、大規模なトラブルの
詳細な説明が中心となっています。

最大4日間程度、部分的なサービスが停止していたのですが、
その障害内容を非常に詳しく紹介しています。そして、紹介する上でAWSの内部的な仕組みも
多々出てきます。ですのでAWSの内部的な仕組み(特にEBSまわり)を知るうえでも、
非常に参考になる記事です。

障害ばかりではなく、その対策に関しても下記3点を軸に言及されています。
  • ストレージ障害
  • 仮想マシン障害
  • DC設備障害
せっかくなので、この3点に関して、僕の考え(AWS限定)もいれた形で
まとめておこうと思います。


ストレージ障害

EBSの障害に関しては三つの対策かあると思います。
  • 定期的にスナップショット
  • 定期的にファイルバックアップ
  • ソフトウェアRAID(ミラーリング)
ファイルバックアップ先はS3やAWS外も考えることができます。

仮想マシン障害

EC2インスタンスの障害は冗長構成にしてELBで分散させる方式になるでしょう。
冗長構成はAZをまたがる形にしておけば、下記のDC設備障害にも
ある程度対応できるはずです。また、ELBが利用できなくても、
EIPは他のインスタンスへの割り当て直しができるので、障害を検知したら、
スタンバイ状態のEC2インスタンスにEIPを割り当て直す方法も可能だと思います。

DC設備障害

"DC=AZ"とした場合は、上記のような方法や、並列で動かせるシステムなら、
別のAZで複数起動することで対応できると思います。
また、AZ間は非常にシームレスになりように設計されているので、上記の構築も簡単です。

"DC=Region"とした場合は、Region間は完全に隔離されているので、
自分たちで仕組みを作成する必要があるでしょう。


実際問題、上記の中でもAWSの仕組みを利用して簡単にできるものは、
  • 定期的にスナップショット
  • 定期的に(S3へ)ファイルバックアップ
  • 複数AZで冗長構成を組みELBで分散
といった感じだと思います。

EBSのソフトウェアRAID(ミラーリング)は試しておかないと...
--------
http://www.suz-lab.com

2011年8月24日水曜日

VPC上のEC2(Subnetごと)にVPN経由での通信確認

スズキです。

下記でVPN接続が確立できたので、
"Customer Gateway"の作成とVPN接続
実際にVPC上のEC2と通信して見ます、下記と同じような内容ですが、
VPC上のEC2にVPN経由で接続(SSH)
今回は"Subnet"ごとの挙動に注目して確認してみます。

まずは何も"Route Table"を設定していない状態で、
自宅(VPNルータ側)のPC(192.168.1.2)から"10.0.1.0/24"上のEC2(10.0.1.4)に
"ping"すると、タイムアウトしてしまいました。

> ping 10.0.1.4
10.0.1.4 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。

接続できるようにするには"10.0.1.0/24"が割り当てられている"Route Table"に
下記のように"0.0.0.0/0"("192.168.1.0/24"でもOK)の"Target"に
VPN接続が確立している"Virtual Private Gateway"を指定する必要があります。


また、セキュリティグループも調整しておきます。


この状態で再度"ping"すると、通信できていることがわかります。

> ping 10.0.1.4
10.0.1.4 に ping を送信しています 32 バイトのデータ:
10.0.1.4 からの応答: バイト数 =32 時間 =9ms TTL=61
10.0.1.4 からの応答: バイト数 =32 時間 =8ms TTL=61
10.0.1.4 からの応答: バイト数 =32 時間 =10ms TTL=61

そして別のSubnet"10.0.0.0/24"上のEC2インスタンス(10.0.0.4)にも
"ping"できるかと試してみると下記のようにタイムアウトしてしまいました。

> ping 10.0.0.4
10.0.0.4 に ping を送信しています 32 バイトのデータ:
要求がタイムアウトしました。
要求がタイムアウトしました。
要求がタイムアウトしました。

やはり通信できるようにするには、下記のように"Target"に"Virtual Private Gateway"を
指定する設定を"10.0.0.0/24"が割り当てられた"Route Table"に行う必要があります。


この状態だと"ping"が通ることがわかります。

> ping 10.0.0.4
10.0.0.4 に ping を送信しています 32 バイトのデータ:
10.0.0.4 からの応答: バイト数 =32 時間 =11ms TTL=61
10.0.0.4 からの応答: バイト数 =32 時間 =8ms TTL=61
10.0.0.4 からの応答: バイト数 =32 時間 =10ms TTL=61

反対にEC2側からVPN経由での通信ですが、下記のように
VPNルーター((192.168.1.1))までは"ping"が通ることがすぐに確認できます。

$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=62 time=9.18 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=62 time=9.76 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=62 time=10.4 ms

しかし、PC(192.168.1.2)に"ping"すると、タイムアウトしてしまいました。

$ ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2421ms

このあたりは、VPCというよりもVPNルーター(SSG5)の設定だと思いますので、
後日、改めて調査することにします。

そろそろ"NAT"か!?
--------
http://www.suz-lab.com

"Customer Gateway"の作成とVPN接続

スズキです。

下記でSubnetを二つ(10.0.0.0/24, 10.0.1.0/24)を作成しました。
VPCの"Subnet"と"Route Table"の挙動の確認
"10.0.0.0/24"は下記のようにインターネットにつなげているので(Internet Gateway)、
インターネットからVPC上のEC2に接続
"10.0.1.0/24"の方は自宅のVPNルーター(SSG5)とVPN接続するようにしてみます。
("Subnet"に関する設定"Route Table"は次の記事で書きます)

まずは"Customer Gataway"の作成です。
自宅のVPNルーター(SSG5)の(Public)IPアドレスを指定します。



次に"Virtual Private Gateway"の作成です。


 

作成後に、適用する"VPC"をアタッチします。


最後に上記で作成した"Customer Gataway"と"Virtual Private Gateway"を選択して、
"VPN Connection"を作成します。



そして設定ファイルをダウンロードすれば、


VPNルーター(SSG5)の設定や接続確認は下記の通りです。
VPCとSSG5を接続

次は"Route Table"調整して、自宅からVPN経由でVPC内のEC2インスタンスにアクセスします。
--------
http://www.suz-lab.com

2011年8月23日火曜日

簡単なCloudFrontのInvalidationのUI(PHP)

スズキです。

下記のようなPHPスクリプトになります。

"AWS PHP SDK"の場所と、ACCESS_KEYとSECRET_KEYと、
対象CloudFrontのDISTRIBUTION_IDは適宜変更して下さい。

<?php
require_once("/opt/aws/php/sdk.class.php");
define("AWS_KEY"       , "ACCESS_KEY");
define("AWS_SECRET_KEY", "SECRET_KEY");
$info = "Please input the path list of invalidation and push \"Invalidate\" button.";
if($_SERVER["REQUEST_METHOD"] == "POST") {
  $path_list = array();
  $tmp_list  = preg_split("/\n/", $_POST["path_list"]);
  foreach($tmp_list as $path) {
    if(trim($path) != "") {
      array_push($path_list, trim($path));
    }
  }
  $cf = new AmazonCloudFront();
  $response = $cf->create_invalidation("DISTRIBUTION_ID", time(), $path_list);
  $info = $response->body;
}
?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>CroudFront Invalidation</title>
  </head>
  <body>
    <pre><?php var_dump($info); ?></pre>
    <form method="POST">
      <input type="submit" value="Invalidate"/>
      <input type="reset"  value="Clear"/>
      <textarea style="width:100%;height:100px" name="path_list"></textarea>
    </form>
  </body>
</html>

利用方法は簡単で、下記のように一行ごとにInvalidationしたいファイルのパスを入力して、
「Invalidate」ボタンを押すだけです。


成功すると、下記のようにレスポンス結果が表示されます。


失敗すると、下記のようにエラーのレスポンス結果が表示されます。


ブログのペースが落ちてる...
--------
http://www.suz-lab.com

2011年8月22日月曜日

VPCの"Subnet"と"Route Table"の挙動の確認

スズキです。

下記の続きです。
インターネットからVPC上のEC2に接続
今回は"Subnet"と"Route Table"の挙動を確認してみます。

まずは、"10.0.0.0/24"のEC2インスタンス(10.0.0.4)で確認です。
$ ping 10.0.0.4
PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.
64 bytes from 10.0.0.4: icmp_seq=1 ttl=64 time=0.024 ms
64 bytes from 10.0.0.4: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 10.0.0.4: icmp_seq=3 ttl=64 time=0.031 ms
当然、自分自身への"ping"は通ります。

ちなみにルーティングテーブルは下記のようになっており、
$ route 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        *               255.255.255.0   U     0      0        0 eth0
default         10.0.0.1        0.0.0.0         UG    0      0        0 eth0
デフォルトゲートウェイは"10.0.0.1"となっています。

次に、同じ"Subnet"のインスタンスに"ping"してみます。
$ ping 10.0.0.5
PING 10.0.0.5 (10.0.0.5) 56(84) bytes of data.
64 bytes from 10.0.0.5: icmp_seq=1 ttl=64 time=10.9 ms
64 bytes from 10.0.0.5: icmp_seq=2 ttl=64 time=0.470 ms
64 bytes from 10.0.0.5: icmp_seq=3 ttl=64 time=0.490 ms
当然、上記のように通信できます。

そして、下記のように"10.0.1.0/24"の"Subnet"を作成します。
ちなみに"Availability Zone"は"10.0.0.0/24"とは違う場所にしています。


"Subnet"を作成すると、デフォルトで"Route Table"は"Main"のもの("10.0.0.0/24"と同じもの)
が適用されるようになっており、そのSubnetのインスタンス(10.0.1.4)にpingすると、
$ ping 10.0.1.4
PING 10.0.1.4 (10.0.1.4) 56(84) bytes of data.
64 bytes from 10.0.1.4: icmp_seq=1 ttl=64 time=3.11 ms
64 bytes from 10.0.1.4: icmp_seq=2 ttl=64 time=3.16 ms
64 bytes from 10.0.1.4: icmp_seq=3 ttl=64 time=3.13 ms
上記のように通信でき、しっかりルーティングされていることがわかります。

実際に"Main"の"Route Table"は次のようになっており、


VPC作成時に指定したネットワークアドレス(10.0.0.0/16)の"Target"が
"local"に必ず設定されています。つまり、そのVPC内のEC2インスタンスは
お互いに通信できるようになっています。

今度はもう一つ"Route Table"を作成し、


(やはり"10.0.0.0/16"の"Target"は"local"に設定されています)


下記のように"10.0.1.0/24"の"Subnet"に適用させます。
つまり"10.0.1.0/24"の"Subnet"を"10.0.1.0/24"とは別の"Route Table"にします。


この状態で再度、"10.0.1.4"に"ping"すると、 

$ ping 10.0.1.4
PING 10.0.1.4 (10.0.1.4) 56(84) bytes of data.
64 bytes from 10.0.1.4: icmp_seq=1 ttl=64 time=3.09 ms
64 bytes from 10.0.1.4: icmp_seq=2 ttl=64 time=3.01 ms
64 bytes from 10.0.1.4: icmp_seq=3 ttl=64 time=3.08 ms

それでも通信はできます。つまり、どんな"Route Table"にもVPCで設定した
ネットワークアドレス(10.0.0.0/16)の"Target"が必ず"local"に設定されてしまうので、
VPC内(10.0.0.0/16)のインスタンスは、お互いに通信できてしまうことになります。

ちなみに"10.0.1.4"のインスタンスのルーティングテーブルは下記のようになっており、
$ route 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.1.0        *               255.255.255.0   U     0      0        0 eth0
default         10.0.1.1        0.0.0.0         UG    0      0        0 eth0
デフォルトゲートウェイは所属しているSubnetのもの(10.0.1.1)になっていることが
わかります。

ということで、"Subnet"間でアクセス制御をしたい場合は、
"Network ACL"を利用することになります。

次は"Network ACL"をやるか、"Route Table"深めるか...
--------
http://www.suz-lab.com

MySQLのユーザー一覧を確認

スズキです。

久しぶりにメンテナンスするMySQLで、
そのときの資料がすぐに見つからないときに、便利です。

mysql> select Host, User, Password from mysql.user;
+--------------+----------+-------------------------------------------+
| Host         | User     | Password                                  |
+--------------+----------+-------------------------------------------+
| localhost    | root     |                                           |
| localhost    |          |                                           |
| %            | test     | *EF7F84CF1B6023B08DFA2D65123DD9F793F82E0D |
+--------------+----------+-------------------------------------------+

まあとりあえず、MySQL(root)でログインできないといけませんが...

すべてのITスキルを、ドキュメントが無くてもなんとかできるくらいまでにはしたいなー...
--------
http://www.suz-lab.com

2011年8月19日金曜日

インターネットからVPC上のEC2に接続

スズキです。

下記でVPC上にEC2インスタンスを起動したのですが、
VPCでEC2インスタンスを起動
VPNルーターとのコネクションも張っていないので、接続することができません。

今回はインターネット経由で接続する方法を紹介します。

まずは、下記のように"Internet Gateway"を作成します。


そして、作成した"Internet Gateway"に"VPC"をアタッチします。
(注意: "Internet Gateway"と"VPC"は1対1です)



次に、下記のように"Route Table"に"Internet Gateway"を追加します。
"0.0.0.0/0"(インターネット)への経路は"Internet Gateway"を利用する形になります。


さらに、"Route Table"に"Subnet"も割り当てます。これにより、
"Subnet"上のEC2インスタンスのインターネット("0.0.0.0/0")への経路は
"Internet Gateway"を利用するようになります。


外部(インターネット)からVPC上のEC2インスタンスにアクセスするためには、
VPC用のEIPを作成し、EC2インスタンスに割り当てる必要があります。




最後にEC2インスタンスに割り当てられたセキュリティグループを下記のように調整すれば、
EIPに接続することで、外部(インターネット)からVPC上のEC2にアクセスできるようになります。


実際にログイン(SSH)したVPC上のEC2インスタンス(Amazon Linux)は
下記のようなネットワーク情報となっています。

$ ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 02:08:36:56:A3:A1  
          inet addr:10.0.0.4  Bcast:10.0.0.255  Mask:255.255.255.0
          inet6 addr: fe80::8:36ff:fe56:a3a1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:655 errors:0 dropped:0 overruns:0 frame:0
          TX packets:904 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:68446 (66.8 KiB)  TX bytes:92665 (90.4 KiB)
          Interrupt:10
$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.0        *               255.255.255.0   U     0      0        0 eth0
default         10.0.0.1        0.0.0.0         UG    0      0        0 eth0

次は、"Route Table"をもっと詳しく紹介しよう。
--------
http://www.suz-lab.com

2011年8月18日木曜日

VPCでEC2インスタンスを起動

スズキです。

下記で最小構成のVPCまで作成したので、
VPCの最小構成
ここから、少しずつ拡張していきます。

今回は、VPC上にEC2インスタンスを立ち上げてみます。

EC2インスタンスを立ち上げるためには、"Subnet"を作成する必要があるので、
下記のように作成します。
(注意: 同じ"CIDR Block"を別リージョンで登録することはできません)


作成した"Subnet"は下記の通りで、デフォルトの"Route Table"と"Network ACL"が
割り当てられていることがわかります。("Route Table"と"Network ACL"は変更できます)

また、"Available IPs"が251となっていますが、これは
10.0.0.4〜10.0.0.254
の251個のIPアドレスが実際にEC2に割り振れることを意味します。


実際のEC2インスタンスは次のように上記で"Subnet"を指定して起動します。
(注意: マイクロインスタンスは利用できません)


IPアドレス(10.0.0.4〜10.0.0.254)を指定して起動することもできます。


当然、セキュリティグループはVPCの方で作られていたものが選択できます。


これで無事、指定したIPアドレス(10.0.0.4)でEC2インスタンスが起動できました。

でもインスタンスのSSHするルートがない...
--------
http://www.suz-lab.com

VPCの最小構成

スズキです。

VPC自体は下記のように"CIDR Block"を指定して作成します。
"/16"以上を指定することはできないため、VPCのネットワークの範囲は、
x.x.0.0 〜 x.x.255.255
ということになります。


作成されたVPCは下記の通りとなり、
"DHCP Options Set", "(Main) Route Table", "(Default) Network ACL"
が割り当てられていることがわかります。



DHCP Options Set

下記のように自動で作成されています。



Route Table

こちらも、下記のように自動で作成されていますが、割り当てる"Subnet"は、
最小構成だと存在しないので、一つも割り当てられてない状態です。



Network ACL

同様に下記のように自動で作成されており、
こちらも"Subnet"が一つも割り当てられてない状態です。



また下記のように、EC2インスタンスに割り当てるデフォルトの
セキュリティグループも作成されています。


次は、ここの状態から、EC2インスタンスを立ち上げれるようにしてみます。
(上記では"Subnet"が無いので作成できません)
--------
http://www.suz-lab.com

Oracleで複数インスタンスを起動&接続

スズキです。

まず下記で紹介した感じでデータベースを作成しますが、
Oracleでレスポンスファイルを利用したCUIでのDB作成

データベースは次のようにGDBNAMEとSIDが異なるように作成します。

suzlab1.rsp
...
GDBNAME = "suzlab1.suz-lab.com"
...
SID = "suz-lab1"
...

suzlab2.rsp
...
GDBNAME = "suzlab2.suz-lab.com"
...
SID = "suz-lab2"
...

"/etc/init.d/dbstart"などで複数起動する場合は、
"/etc/oratab"を下記のようにしておく必要があります。

suzlab1:/u01/app/oracle/product/11.1.0/db_1:Y
suzlab2:/u01/app/oracle/product/11.1.0/db_1:Y

起動すると、下記のようにOracleインスタンスが二つ立ち上がります。

# /etc/init.d/dbstart start
Starting Oracle Net Listener.

Starting up Oracle Database Instance: "suzlab1".
ORACLE instance started.
Total System Global Area 1068937216 bytes
Fixed Size		    2151248 bytes
Variable Size		  599788720 bytes
Database Buffers	  461373440 bytes
Redo Buffers		    5623808 bytes
Database mounted.
Database opened.

Starting up Oracle Database Instance: "suzlab2".
ORACLE instance started.
Total System Global Area 1068937216 bytes
Fixed Size		    2151248 bytes
Variable Size		  599788720 bytes
Database Buffers	  461373440 bytes
Redo Buffers		    5623808 bytes
Database mounted.
Database opened.

"suzlab1"に接続する場合はこんな感じです。(GDBNAMEを指定します)

$ sqlplus sys/password@localhost:1521/suzlab1.suz-lab.com as sysdba

"suzlab2"に接続する場合も同様です。

$ sqlplus sys/password@localhost:1521/suzlab2.suz-lab.com as sysdba

EC2上のOracleもニーズあるなー...(AMI公開してもいいのかなー...)
--------
http://www.suz-lab.com

2011年8月17日水曜日

Oracleの割当メモリ調整(自動メモリ管理)

スズキです。

今のOracle(11g)だと、自動メモリ管理という機能があり、
SGAやPGAを指定したメモリ内で、適当に割り振ってくれます。

例えば、デフォルトでDBインスタンスを作成し、
下記のようにメモリが割り当てられていたとすると、

Total System Global Area 3206836224 bytes
Fixed Size                  2148680 bytes
Variable Size            1728054968 bytes
Database Buffers         1459617792 bytes
Redo Buffers               17014784 bytes

次のように、Oracleの"MEMORY_TARGET"と"MEMORY_MAX_TARGET"を指定することで

$ export ORACLE_SID=suzlab1
$ sqlplus / as sysdba;
SQL> ALTER SYSTEM SET MEMORY_TARGET = 1024M SCOPE = SPFILE;
SQL> ALTER SYSTEM SET MEMORY_MAX_TARGET = 1024M SCOPE = SPFILE;

下記のように、指定したメモリ内で適当に割り当てられるようになります。

Total System Global Area 1068937216 bytes
Fixed Size                  2151248 bytes
Variable Size             599788720 bytes
Database Buffers          461373440 bytes
Redo Buffers                5623808 bytes

※Oracleリスタート後の結果です。

"ORA-01102"が解決できない...
--------
http://www.suz-lab.com

2011年8月16日火曜日

SUZ-LAB謹製 CentOS AMI (6.0.2 64bit ap-northeast-1)

スズキです。

下記をアップデートしました。
SUZ-LAB謹製 CentOS AMI (6.0.1 64bit ap-northeast-1)

AMIを「suz」で検索してもらえれば、
811118151095/suz-lab_ebs_centos-core-x86_64-6.0.2
として見つかるはずです。

アップデート内容は下記と同じです。
SUZ-LAB謹製 CentOS AMI (6.0.2 32bit ap-northeast-1)

Enjoy!
--------
http://www.suz-lab.com



"bash: scp: command not found"の対策

スズキです。

適当なマシンから"scp"すると、下記のようなエラーメッセージが出力されることがあります。

bash: scp: command not found
lost connection

これは、対象のマシンに"scp"が入っていないからです。
("SUZ-LAB CentOS 6.0"には現在入っていません...)

"scp"のインストールは"CentOS 6.0"では下記のように、
"openssh-clients"パッケージでインストールできます。

# yum install -y openssh-clients
# rpm -ql openssh-clients
/etc/ssh/ssh_config
/usr/bin/.ssh.hmac
/usr/bin/scp
/usr/bin/sftp
/usr/bin/slogin
/usr/bin/ssh
/usr/bin/ssh-add
/usr/bin/ssh-agent
/usr/bin/ssh-copy-id
/usr/bin/ssh-keyscan
/usr/share/man/man1/scp.1.gz
/usr/share/man/man1/sftp.1.gz
/usr/share/man/man1/slogin.1.gz
/usr/share/man/man1/ssh-add.1.gz
/usr/share/man/man1/ssh-agent.1.gz
/usr/share/man/man1/ssh-copy-id.1.gz
/usr/share/man/man1/ssh-keyscan.1.gz
/usr/share/man/man1/ssh.1.gz
/usr/share/man/man5/ssh_config.5.gz

これで無事、"scp"ができるようになりました。

原因がわかるまでに時間がかかってしまった...
--------
http://www.suz-lab.com

MySQLのレプリケーションをSSL接続で

スズキです。

下記でSSL接続できるようになったので
MySQLにSSLで接続
今度はレプリケーションをSSLで行ってみます。

MySQLのレプリケーション自体は、基本的に下記で紹介した通りですが、
MySQLのレプリケーション
変更点は次の通りとなります。

マスターサーバ

(1)上記で紹介したようにSSL接続できるようにしておきます。

(2)下記のようにレプリケーションに利用するユーザーを"REQUIRE SSL"オプションで
SSL接続のみ受け付けるようにします。
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@xxx.xxx.xxx.xxx IDENTIFIED BY 'xxxxxxxx' REQUIRE SSL;

スレーブサーバ

(3)"CHANGE MASTER TO ..."するときにSSL関係の値も指定します。
mysql> CHANGE MASTER TO
    -> MASTER_HOST     = 'yyy.yyy.yyy.yyy',
    -> MASTER_USER     = 'repl',
    -> MASTER_PASSWORD = 'xxxxxxxx',
    -> MASTER_LOG_FILE = 'us-east-1-bin.000011',
    -> MASTER_LOG_POS  = 7782,
    -> MASTER_SSL      = 1,
    -> MASTER_SSL_CA   = '/tmp/ssl/ca-cert.pem',
    -> MASTER_SSL_CERT = '/tmp/ssl/server-cert.pem',
    -> MASTER_SSL_KEY  = '/tmp/ssl/server-key.pem';

この状態で、スレーブサーバを再起動すると
SSL接続でレプリケーションされるようになります。

AWSでのリージョン間レプリケーションでは、是非、使いたいところです。
--------
http://www.suz-lab.com

2011年8月15日月曜日

MySQLにSSLで接続

スズキです。

MySQLにインターネット経由で接続するような場合は、SSL接続にしたいところです。

ということで、試してみました。

まずは、現状の確認です。SSL接続が無効になっていることがわかります。

mysql> SHOW VARIABLES LIKE '%ssl%';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_key       |          |
+---------------+----------+

SSL接続には、当然、証明書類が必要になるので、下記のディレクトリで作成します。

# pwd
/tmp/ssl

まずは、CAのキーを作成します。

# openssl genrsa -out ca-key.pem 2048
Generating RSA private key, 2048 bit long modulus
.+++
...............................+++
e is 65537 (0x10001)

そして、CAの証明書の作成です。

# openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:JP
State or Province Name (full name) [Berkshire]:Tokyo
Locality Name (eg, city) [Newbury]:SHibuya-ku
Organization Name (eg, company) [My Company Ltd]:
[root@ip-10-150-174-7 ssl]# openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:JP
State or Province Name (full name) [Berkshire]:Tokyo
Locality Name (eg, city) [Newbury]:Shibuya-ku
Organization Name (eg, company) [My Company Ltd]:SUZ-LAB
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []ca.suz-lab.com
Email Address []:

今度は、MySQLサーバのキーとCSRの作成です。

# openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem -out server-req.pem
Generating a 2048 bit RSA private key
.................................................................................+++
...........................................................+++
writing new private key to 'server-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:JP
State or Province Name (full name) [Berkshire]:Tokyo
Locality Name (eg, city) [Newbury]:Shibuya-ku
Organization Name (eg, company) [My Company Ltd]:SUZ-LAB
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:mysql.suz-lab.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

最後に、MySQLサーバの証明書を作成します。

# openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -out server-cert.pem -set_serial 01
Signature ok
subject=/C=JP/ST=Tokyo/L=Shibuya-ku/O=SUZ-LAB/CN=mysql.suz-lab.com
Getting CA Private Key

上記で作成したファイルは下記の通りです。

# ls
ca-cert.pem  ca-key.pem  server-cert.pem  server-key.pem  server-req.pem

これらのファイルを、下記のように"/etc/my.cnf"に記述します。

[mysqld]
...
ssl-ca=/tmp/ssl/ca-cert.pem
ssl-cert=/tmp/ssl/server-cert.pem
ssl-key=/tmp/ssl/server-key.pem

MySQLをリスタートすると、下記のように今度はSSLが有効になっていることが確認できます。

mysql> SHOW VARIABLES LIKE '%ssl%';
+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| have_openssl  | YES                      |
| have_ssl      | YES                      |
| ssl_ca        | /tmp/ssl/ca-cert.pem     |
| ssl_capath    |                          |
| ssl_cert      | /tmp/ssl/server-cert.pem |
| ssl_cipher    |                          |
| ssl_key       | /tmp/ssl/server-key.pem  |
+---------------+--------------------------+

クライアントからの接続に関しては、下記のようにSSL接続専用のユーザーを作成し、

mysql> GRANT ALL PRIVILEGES ON *.* TO ssluser@'%' IDENTIFIED BY 'sslpass' REQUIRE SSL;

接続時にCAの証明書を指定すると、無事接続することができます。

# mysql -h xxx.xxx.xxx.xxx -u ssluser --ssl-ca=/tmp/ssl/ca-cert.pem -p

MySQLのリージョン間レプリケーションはSSL接続したいところです。
--------
http://www.suz-lab.com

RDS上のOracleライセンス(BYOL)について

スズキです。

EC2上のOracleのライセンスに関しては、下記のように紹介していますが、
EC2上でのOracle(Standard Edition)のライセンス(再び)
今回は、RDS上でのライセンス(BYOL)に関してです。

といってもEC2同様、コチラの通りで、

Standard Edition One(SE1)およびStandard Edition(SE)
必要ライセンス数 = 仮想コア数 / 4 (小数点以下切り上げ)
Enterprise Edition(EE)
必要ライセンス数 = 仮想コア数 / 2 (小数点以下切り上げ)
といった計算となります。

インスタンスタイプごとに必要なライセンス数は、下記のような表となります。

タイプ メモリ(G) ECU 仮想コア数 必要プロセッサ数 BYOL(Tokyo)
SE1/SE EE
db.m1.small 1.7 1.0 1 1 1 $0.13/時
db.m1.large 7.5 4.0 2 1 1 $0.52/時
db.m2.xlarge 17.1 6.5 2 1 1 $0.78/時
db.m2.2xlarge 34.0 13.0 4 1 2 $1.56/時
db.m2.4xlarge 68.0 26.0 8 2 4 $3.11/時

ライセンスばかり調べてる気が...
--------
http://www.suz-lab.com

2011年8月11日木曜日

EIPのインスタンスを変更してSSH接続できなくなったら

スズキです。

EIPにぶら下がってるインスタンスを別のものに付けかえて、
SSHにてそのIPアドレスでアクセスすると、下記のように接続拒否されることがあります。

$ ssh -i suz-lab_ap-northeast-1.pem -l root xxx.xxx.xxx.xxx
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
Please contact your system administrator.
Add correct host key in /Users/suzuki/.ssh/known_hosts to get rid of this message.
Offending key in /Users/suzuki/.ssh/known_hosts:5
RSA host key for xxx.xxx.xxx.xxx has changed and you have requested strict checking.
Host key verification failed.

再び接続できるようにするためには下記のように、登録されている(EIPに対応している)
公開鍵をリセットする必要があります。

▼ 確認
$ ssh-keygen -F xxx.xxx.xxx.xxx
# Host xxx.xxx.xxx.xxx found: line 5 type RSA
xxx.xxx.xxx.xxx ssh-rsa 
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

▼ リセット
$ ssh-keygen -R xxx.xxx.xxx.xxx
/Users/suzuki/.ssh/known_hosts updated.
Original contents retained as /Users/suzuki/.ssh/known_hosts.old

そして再びSSHで接続すると、今度は無事ログインできます。

$ ssh -i suz-lab_ap-northeast-1.pem -l root xxx.xxx.xxx.xxx
The authenticity of host 'xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)' can't be established.
RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'xxx.xxx.xxx.xxx' (RSA) to the list of known hosts.
Last login: Thu Aug 11 13:14:08 2011 from xxx.xxx.xxx.xxx

ブログに書いておけば、次はすぐに思い出すはず!?
--------
http://www.suz-lab.com

SUZ-LAB謹製 CentOS AMI (6.0.2 32bit ap-northeast-1)

スズキです。

下記をアップデートしました。
SUZ-LAB謹製 CentOS AMI (6.0.1 32bit ap-northeast-1)
AMIを「suz」で検索してもらえれば、
811118151095/suz-lab_ebs_centos-core-i386-6.0.2
として見つかるはずです。

アップデート内容は下記となります。

仮想コンソールを一つに
CentOS6で仮想コンソール(/dev/ttyN)を一つにする

Monitでサービス監視
CentOS6にMonitをインストール&初期設定(auditd/crond/ntpd/rsyslog/sshd/postfix)

NRPE(Nagiosエージェントを削除)
Zabbix使う場合もあるので、ニュートラルな状態にしました。

Enjoy!
--------
http://www.suz-lab.com

2011年8月10日水曜日

公開AMIを作成する直前で行っていること

スズキです。

いろいろAMI作ってますが、公開AMIを作成する前に、下記を実施しています。
(下記はCentOS6の場合です)

公開鍵の消去(必須です!)
# echo "" > /root/.ssh/authorized_keys

ログの消去
# echo "" > /var/log/boot.log
# echo "" > /var/log/btmp
# echo "" > /var/log/cron
# echo "" > /var/log/dmesg
# echo "" > /var/log/dmesg.old
# echo "" > /var/log/lastlog
# echo "" > /var/log/maillog
# echo "" > /var/log/messages
# echo "" > /var/log/secure
# echo "" > /var/log/spooler
# echo "" > /var/log/tallylog
# echo "" > /var/log/wtmp
# echo "" > /var/log/yum.log
# echo "" > /var/log/audit/audit.log

コマンドヒストリーのクリア
# history -c

公開鍵の消去を忘れると、AWSから注意メールがくることがあります...
--------
http://www.suz-lab.com

CentOS6にMonitをインストール&初期設定(auditd/crond/ntpd/rsyslog/sshd/postfix)

スズキです。

以前、CentOS5でいろいろMonitしてましたが、
Monitでプロセスの再起動

Monitで"crond/syslog/sshd"の監視

Monitを"init"経由で起動

"MySQL Proxy"を"Monit"で監視
今回はCentOS6で、もう一度インストール&初期設定
(auditd/crond/ntpd/rsyslog/sshd/postfix)をやり直してみました。

インストールは下記の通りです。

# yum -y install monit
# chkconfig monit on
# mkdir /var/monit

"/etc/monit.conf"は下記のようにデーモンとログの設定のコメントをはずしておきます。

...
set daemon  120           # check services at 2-minute intervals
...
set logfile syslog facility log_daemon
...

"/etc/monit.d"以下のファイルは下記の通りです。

▼ auditd.conf
# cat /etc/monit.d/auditd.conf
check process auditd with pidfile /var/run/auditd.pid
    start program = "/etc/init.d/auditd start"
    stop program = "/etc/init.d/auditd stop"
    if 5 restarts within 5 cycles then timeout

▼ crond.conf
# cat /etc/monit.d/crond.conf
check process crond with pidfile /var/run/crond.pid
    start program = "/etc/init.d/crond start"
    stop program = "/etc/init.d/crond stop"
    if 5 restarts within 5 cycles then timeout

▼ ntpd.conf
# cat /etc/monit.d/ntpd.conf
check process ntpd with pidfile /var/run/ntpd.pid
    start program = "/etc/init.d/ntpd start"
    stop program = "/etc/init.d/ntpd stop"
    if 5 restarts within 5 cycles then timeout

▼ rsyslog.conf
# cat /etc/monit.d/rsyslog.conf
check process rsyslog with pidfile /var/run/syslogd.pid
    start program = "/etc/init.d/rsyslog start"
    stop program = "/etc/init.d/rsyslog stop"
    if 5 restarts within 5 cycles then timeout

▼ sshd.conf
# cat /etc/monit.d/sshd.conf
check process sshd with pidfile /var/run/sshd.pid
    start program = "/etc/init.d/sshd start"
    stop program = "/etc/init.d/sshd stop"
    if failed port 22 protocol ssh then restart
    if 5 restarts within 5 cycles then timeout

▼ postfix.conf
# cat /etc/monit.d/postfix.conf
check process postfix with pidfile /var/spool/postfix/pid/master.pid
    start program = "/etc/init.d/postfix start"
    stop program = "/etc/init.d/postfix stop"
    if failed port 25 protocol smtp then restart
    if 5 restarts within 5 cycles then timeout

最後に下記で開始です。

# /etc/init.d/monit start

これも次のAMIリリースに反映させておこう。
--------
http://www.suz-lab.com

CentOS6で仮想コンソール(/dev/ttyN)を一つにする

スズキです。

デフォルトでは下記のように6個立ち上がっています。
EC2などの仮想サーバの場合は、メモリ節約の意味合いも含め、1個でいいと思います。

# ps aux
...
root       851  0.0  0.0   1964   480 tty1     Ss+  17:04   0:00 /sbin/mingetty /dev/tty1
root       853  0.0  0.0   1964   484 tty2     Ss+  17:04   0:00 /sbin/mingetty /dev/tty2
root       855  0.0  0.0   1964   480 tty3     Ss+  17:04   0:00 /sbin/mingetty /dev/tty3
root       857  0.0  0.0   1964   480 tty4     Ss+  17:04   0:00 /sbin/mingetty /dev/tty4
root       859  0.0  0.0   1964   488 tty5     Ss+  17:04   0:00 /sbin/mingetty /dev/tty5
root       861  0.0  0.0   1964   480 tty6     Ss+  17:04   0:00 /sbin/mingetty /dev/tty6
...

ということで1個にしたいわけですが、これを減らすには、
CentOS6では"/etc/sysconfig/init"を下記のように調整する必要があります。

# cat /etc/sysconfig/init
...
#ACTIVE_CONSOLES=/dev/tty[1-6]
ACTIVE_CONSOLES=/dev/tty[1-1]
...

この状態でリブートすると、下記のように1に減っていることがわかります。

# ps aux
...
root       837  0.0  0.0   1964   488 tty1     Ss+  18:14   0:00 /sbin/mingetty /dev/tty1...
...

次のAMIの更新に反映させておこう。
--------
http://www.suz-lab.com

VPC上のEC2にVPN経由で接続(SSH)

スズキです。

下記のようにVPCが構築できたので、
VPCとSSG5を接続
今回は、VPC上に実際にEC2を立ち上げて、VPNルーター(SSG5)にぶら下がってる
マシンから接続(SSH)してみます。

まずはVPCの上のEC2インスタンスの立ち上げです。
基本的にいつもと同じですが、下記のように
"Launch Instances Into Your Virtual Private Cloud"を選択し、
VPC設定時に作られたサブネットを指定して立ち上げます。


すると、"10.0.1.161"のようなプライベートIPが付与されるので、
VPNルーター(SSG5)の下にぶら下がってるマシンから、
このIPアドレスに対してSSHします。

ですが、最初はアクセス制限に引っかかって接続できないはずです。
VPCのアクセス制限は、いつもの"Security Groups"と
VPC特有の"Network ACLs"で行われています。

デフォルトの"Network ACLs"は下記のようになっており、制限はかかっていないようです。


そして"Security Groups"のデフォルトは例のごとく
自分の"Security Groups"以外からのアクセスがすべて禁止されている状態だったので、
下記のようにVPNルーター(SSG5)以下のマシンがぶら下がっている
ネットワークのアドレスを登録しておきます。



これで、再度SSHで接続すると、無事ログインできることが確認できるはずです。

ログインできたときは、少し感動してしまった...
--------
http://www.suz-lab.com