ELB配下でのサーバ(EC2)の負荷分散を考えた場合、当然ながら対象となるEC2を複数用意することになりますが、それらを全て一から構築するのは手間です。また、AnsibleのようなIaCの仕組みを使用すれば別ですが、一般的には環境構築は手作業で行う場合も多く、各サーバが本当に同等(アドレスなどの必然的な差分は別)の環境になっているかどうかを保証することは難しいかと思います。
このようなケースではある程度環境が整ったサーバに関して環境を丸ごとイメージ化して、それを流用するのが一般的かと思います。例えば、Virtualbox/Vagrant環境で作成済みのサーバ環境を他者にも提供したい場合は、この方法を用いています(Vagrantのパッケージ化)。
AWSでも特定のEC2インスタンスをAMI(Amazon Machine Image)なる形でイメージ化しておいて、これをベースに他のEC2インスタンス生成に使用する方法があるようなので、これを試してみたいと思います。
なお、以下ではコピー元となるEC2インスタンスを「元EC2」と表現します。
EC2の停止(と再起動)
EC2のAMI作成に際しては、ベースとなる元EC2は停止しておいた方が良いようです。
起動したままでも可能なようですが、普通に考えてディスクにアクセスがあるような状態でイメージ化して本当にファイルの内容や状態に整合性を持たせられるのかはかなり心配なので、停止した上でイメージ化した方が堅実でしょう。
なお、実は対象となる元EC2に関しては環境構築以降一度も再起動したことないので、まずはその点含めて確認しておきたいと思います。
EC2の停止に関しては、EC2コンパネメニューから「インスタンス」を選択し、対象となるEC2を選択して、「インスタンスの状態」から「インスタンスを停止」を選択します。
インスタンス一覧上で「インスタンスの状態」列が「停止済み」になればOKです。停止操作開始後しばらくは「停止中」と言う表示になっていますが、これは文字通り停止作業中ということのようですので「停止済み」になるまで我慢します。
EC2の再起動に関しても、同じくEC2のインスタンス一覧から対象となるEC2を選択し、「インスタンスの状態」から「インスタンスを開始」を選択します。
「インスタンスの状態」列が「保留中」から「実行中」に変わればOKです。
なお、EC2を再起動すると自動割り振りされているパブリックIPが変わるようです(確実に変わるかどうかまでは分かりませんが)。
個人的にはパブリックIPを直接使用している処理(箇所)は以下くらいだったのであまり影響を受けませんでしたが。
- ssh接続する際のホスト指定
- VirtualminのコンパネアクセスURL(https://<IPアドレス>:10000)
- 特別な事情でDNSではなくhostsファイルで特定のドメイン名とパブリックIPの変換を行なっているケース(phpMyAdminへのアクセス用ドメイン定義など)
一般的には上記のような点を考慮してElastic IPを割り当てておくと言うのが常套手段だと思いますが、Elastic IPを使用しなくて困るケースが今のところ上記程度であったり、Elastic IP自体は無償で使用できるものの紐づくEC2が存在しない(停止や削除された)場合は課金されると言う罠(?)があったりで、今一つElastic IPの使用に踏み切れません。
何か決定的な理由ができれば別ですが、もうしばらくはElastic IPなしで運用してみようと思います。
AMI作成
改めて元EC2を停止してAMI作成を行います。
元EC2が「停止済み」になったら、元EC2を選択して、「アクション」から「イメージとテンプレート」、「イメージを作成」と選択して行きます。
「イメージ名」には適当なもの(分かりやすいもの)を指定しておきます。
「再起動しない」と言う項目で「有効化」が選択できるようになっていますが、これは元EC2を起動したままAMIを作成した場合でも本項目を指定しておかないと勝手に元EC2が再起動されてしまうようで、それを抑止するかどうかと言う選択のようです。
今回は元EC2を停止してAMI作成するので選択する必要はないです。
「インスタンスボリューム」に関して選択できるのは「サイズ」と「終了時に削除」くらいでした。ここは元EC2の作り方に依存しているかもしれません。
「サイズ」に関しては元EC2に合わせておきます。
「終了時に削除」に関しては本イメージから生成されたEC2を削除した際にEBSを合わせて削除するかどうかを指定するものらしく、これを指定しておかないとEC2を削除してもEBSだけ残り続けて課金され続けるという憂き目に合うようなので、何か理由がない限りは選択しておくのが良いかと思います。
上記設定を行ったら「イメージを作成」をクリックします。
左メニューから「AMI」を選択すると、一覧上に上記で指定したイメージに関する情報が追加されており、ステータスが「pending」になっていると思います。このステータスが「available」になればOKです(今回のケースでは完了まで10分程度要したと思います)。
上記まで終われば元EC2には用がないので再起動しておきます。先に触れたようにパブリックIPの変化に要注意です。
AMIからEC2インスタンス生成
作成されたAMIからEC2インスタンスを生成します。
AMIを選択して、「アクション」から「起動」を選択します。
以降の手順はEC2インスタンスを新規作成する場合とほぼ同じなので、要点に関してのみ記述します。
「ネットワーク」および「サブネット」の選択はある意味この操作で最も重要なポイントかもしれません。
今回の作業の直接的な目標はAMIからEC2インスタンスを生成することですが、その根本的な目的は負荷分散環境の構築にあります。
負荷分散環境の構築においては、文字通り複数のEC2で処理を分担することが主目的ですが、複数のサーバが存在することでその中の一部に問題が生じても残りで運用が続けられると言う点も重要です。実のところ今回の環境においては特に後者の意味で負荷分散環境を構築しようとしていると言っても過言ではありません。
この観点から言えば、追加するEC2は元EC2とは別のAZに配置した方がより安全です。よって、「ネットワーク」としては元EC2と同じVPCを選択しますが、「サブネット」に関してはAZの異なるサブネットを選択します。
実は過去の記事でもしれっと「EC2を配置するサブネット(インターネットからアクセス可)を2つ構築」と書いていましたが、ここで構築したサブネット2つではAZを別にしてありました。これは当然ながら複数台のEC2を異なるAZで運用することを意識したものです。
「タグの追加」では「Name」として適当な名称を付けておきます。
「セキュリティグループの設定」では元EC2で作成したセキュリティグループを指定します。
一通りの設定が終了したら、最後の「インスタンス作成の確認」画面で「起動」をクリックします。
キーペアに関しては元EC2と同じキーペアを使用することにし、「インスタンスの作成」をクリックします。
あとは「インスタンスの状態」が「実行中」、「ステータスチェック」が「2/2のチェックに合格しました」になるまで待ちます。
上記状態になったらsshでアクセスしてざっくりサーバ内の様子を確認し、問題なさそうであれば今回の目的である「EC2の複製」としては「成功」とします。
総括
まずは既存EC2インスタンスからAMIを作成すること、およびAMIからEC2インスタンスを作成することができました。
なお、一旦別EC2となった後はそれぞれに関するメンテナンスが必要になりますので、どの段階まで1つのEC2で進化させ、その後AMI作成して横展開するかと言う点に関してはそれなりの戦略が必要そうです。
また、今回はあくまでEC2の複製までを目標としましたが、本来の目的は負荷分散環境の構築であるため、次回はその辺に関して触れて行きたいと思います。