Backlog インフラ担当の松浦です。正式リリースから今年で 11 年目を迎えたBacklogは、昨年2016年末に新しいユーザーインターフェース(以下UI)へ大幅にリニューアルしました。開発メンバーが新しいUIの開発を進める裏側では、さらに運用しやすくするために、粛々とインフラの改善を実施していました。今回はその改善内容の一部である EC2-Classic から EC2-VPC に移行したときの内容をご紹介します。
EC2-Classic と EC2-VPC の違いに関してはこちらをご参照ください
EC2-Classic から EC2-VPC へ移行した理由
ヌーラボのサービスは全て AWS で運用されています。私自身、昔から AWS を使っていたこともあり、古い環境では EC2-Classic 利用していました。EC2-Classic で運用していて、不便に感じていた点を以下に挙げます。
EC2 のメンテナンス頻発問題
M1 系等の古いインスタンスタイプを使っているため、 EC2 インスタンスのメンテナンスのための再起動が高い頻度で必要になっており、その度にBacklogの計画停止を実施していました。
メンテナンスの種類によってはインスタンスの STOP, START を実施する必要があるので、エフェメラルディスク領域のリカバリ、Private IP / Public IP の変更対応を都度実施していました。
エフェメラルディスクは揮発性のディスクで、インスタンスを停止するとデータが消えます。EC2-Classic のインスタンスは Private IP / Public IP が動的に割り当てられるので IP の変更が必要です。ヌーラボでは hosts, Ansible の設定ファイルを都度書き換えていました。
新しいインスタンスタイプや新しいサービスはVPC前提でサービスが開始される
良さそうなインスタンスタイプや新しいサービスを見つけた際に、気軽に試しづらい状況(気持ち)になっていました。例えば Amazon Aurora を試したいけれど、 DB に接続する必要のあるインスタンスを ClassicLink でずっと接続して運用するのは、複雑性が増すだけで「ちょっとつらいな、嫌だな」と感じることがありました。
ClassicLink は EC2-Classic のインスタンス と VPC を接続して、プライベートIPで通信できるようにしてくれます。VPC に用意した Private Subnet と通信できる等のメリットがあります。
移行してよかったこと
Backlogの計画停止の頻度が大幅に減った
移行前の一年間で30件ぐらい発生していたメンテナンスが、移行完了の2016年8月から現在までの約8ヶ月間で、4件に減っています(補足ですが移行に際して、仮想化方式を paravirtual から HVM に変更しています)。
新しいインスタンスタイプを使用できる
ちょっと本番で試したいことがあった場合に、 T2 系のインスタンスを投入できるようになったのは、コスト面からみてもメリットがあります。
Private IP が固定になるので設定ファイルの書き換えがなくなった
Private IP の管理を dnsmasq で行っていましたが、都度設定を書き換え再起動する必要がなくなりました。
また SSH の接続も踏み台を経由して、 Private IP で接続するため、設定を書き換えする必要がなくなりました。
AWS の新しいサービスを試しやすくなった
新しいサービス投入した際に、EC2-Classic で使えるの??と調べる時間を短縮できました。
インスタンスタイプのシリーズ( C4, M4 等 )を合わせることでリザーブドインスタンスの集計、再利用、購入の負担が減った
ある程度統一できたことで、何十種類もあるインスタンスタイプを集計し、適切にリザーブドインスタンスが有効になっているかを、集計する負担が大幅に減りました。こちらはリージョン単位で、リザーブドインスタンスを購入できるようになったことも大きかったです。
移行手順の検討について
移行を計画するにあたって、最優先にしたのは、EC2 のインスタンスで運用していたデータベースを Amazon Aurora ( RDS ) に移行できるかどうか、です。密着 24時! MySQL 5.1 から Aurora への移行100日間 〜 Backlog 編 にもあるようにデータベースの移行が問題ないことが確認できたため、計画的にすべてのインスタンスを VPC に移行していきました。
データベース以外の移行方針は以下の内容で決定しました。
- インスタンスは新規でプロビジョニングする
- EC2-Classic で使っていた EIP は VPC 用の EIP へマイグレーションし使用する
- 各インスタンスにアタッチされている EBS はそのまま利用する
- 完全に移行するまでは EC2-Classic と VPC は ClassicLink で接続する
サーバを抜粋すると、移行前は下の図の状態でした。
データベースを移行した結果、下の図の状態になりました。
移行時に工夫した点・注意点
ヌーラボのインフラ運用最前線 2015 〜Terraform による AWS の構成の自動化〜 にもあるように、インスタンスそのもののプロビジョニングは Terraform と Ansible で実施しています。
Elastic IP 移行
Backlog の DNS サーバーには、 Elastic IP アドレスを指すレコードが大量に登録されているため、Elastic IP アドレスを変更しない方法を検討することにしました。 Elastic IP アドレスは新しく作り直さずに、以前から使っていたものを Classic 環境から VPC 内へ移動させることに決めました。
移行の際の注意点として2つ制限があります。ヌーラボではメールサーバーを自前で運用しているため、逆引き DNS レコードに関連付けられている Elastic IP アドレスは移行または復元できません。 これに関しては移行方法を検討する必要がありました。
[Elastic IPアドレスの移行に関する制限]
- 24 時間以内にアカウントに割り当てられた Elastic IP アドレスを移行することはできません。
- 逆引き DNS レコードに関連付けられている Elastic IP アドレスは移行または復元できません。
メールサーバは冗長化構成を取っていたため、一旦送信サーバの設定を外して以下の手順で移行しました。
- 逆引き設定の解除申請
- EIP を VPC に移行
- 新しいサーバに EIP をアタッチする
- 逆引き設定を申請する
EIP 移行そのものは AWS CLI だと以下の内容で移行することができます。
# AWS CLI command
aws ec2 move-address-to-vpc --public-ip 111.222.333.444
ディスクテスト
Backlog のサーバの中にはたくさんの EBS がアタッチされているサーバがあります。
サーバー入替えの方式として、差し替える方針をとったので、旧サーバー停止後に新サーバーに正しくディスクがアタッチされたのかを確認する必要があります。EBS の移行に際して2つのツールを使い、試験しました。
awspec で正しいデバイスにディスクがアタッチされているかをチェックする
予め EBS のアタッチのテストを書いておき、移行後に instance_id
の変数を書き換えテストできる状態にしておきました。
# awspec sample code
instance_id = 'i-99999999'
disk_sdf = 'vol-99999999'
describe ebs(disk_sdf) do
it { should exist }
it { should be_in_use }
it { should be_attached_to(instance_id) }
its('attachments.first.device') { should eq '/dev/sdf' }
end
Serverspec でマウント先が正しいかチェックする
予め正しくマウントの設定がされていることをテストを書いておき、チェックするホストを変更して、テストができる状態にしておきました。
# Serverspec sample code
describe file("/data") do
it do
should be_mounted.with(:device => "/dev/sdf").with(:type => 'xfs'))
end
end
describe file('/etc/fstab') do
its(:content) { should match /dev/sdf /data xfs rw,noatime,nodiratime,nobarrier,inode64 0 0/ }
end
この 2 パターンのテストを追加することで、アタッチされている EBS が多いインスタンスも安心して移行することができました。
ClassicLink
たくさんあるサーバーを完全に VPC に移行するには時間がかかりました。ClassicLink はインスタンスをSTOP,STARTをした場合に設定が外れてしまいます。一度緊急を要するトラブルが発生し、インスタンスを停止したことがあったのですが、DBと通信できず悩んだ事がありました。
そういうトラブルもあったためテストケースを追加することにしました。awspec を調査した結果、機能がなかったので have_classiclink()
と have_classiclink_security_group()
の2つの機能を追加してもらいました。
ヌーラボでは awspec を使っているのですが、作者である @k1LoW さんがすぐに反応対応してくれるので安心して使用できています。本当に感謝しております。
脱線しましたが、テストケースを記載すると以下のようになります。
# awspec sample code
describe ec2('i-11111111') do
it { should have_classiclink(vpc-22222222) }
it { should have_classiclink_security_group(sg-33333333) }
it { should have_classiclink_security_group(sg-44444444) }
it { should have_classiclink_security_group(sg-55555555) }
end
様々な点を工夫したり注意点に気をつけたりして、移行した結果下の図の状態になりました。
最後に
このブログを書くにあたって AWS 10年の歩み ~ 沿革 ~ を見ていました。
AWS のサービス開始は Backlog正式版と同じ2006 年です。私自身も感動して、サービス開始された当初からAWSをずっと触ってきました。
何も変更しなければ時間の経過とともにレガシーなものになっていきますが、ヌーラボでは経営層・開発メンバーの理解があり、運用構成も変更していける体制があります。
今後もより良いサービスが運用できるように、改善を続けていきたいと思います。Backlogおよびヌーラボでは、サービスをより良くするエンジニアを募集しています。ぜひご応募ください。