こんにちは。ソフトウェアエンジニアの坂井 (@manabusakai) です。
カミナシでは RDB に Amazon Aurora MySQL を使っています(以下 Aurora と略します)。また、データ保護の追加レイヤーとして KMS を使って DB クラスターを暗号化しています。
ここまでは良いのですが、KMS キーに AWS マネージドキーが設定されていました。普段から AWS を使っている方であれば「あちゃ〜」と思われるでしょう。
なぜ Aurora の KMS キーに AWS マネージドキーを使うのが「あちゃ〜」なのか
KMS キーには、AWS マネージドキーとカスタマーマネージドキーの 2 種類があります。 AWS マネージドキーはユーザーに代わって作成されるキーで、RDS の場合は aws/rds
というエイリアス名が付いています。 Management Console から Aurora クラスターを起動しようとすると、デフォルトでこのキーが選択されます。
KMS のことがよく分かっていなくてもすぐに使えるので便利な一方、このキーで暗号化してしまうとアカウント間でスナップショットなどのリソースが共有できないという大きな制約があります(キーの管理は AWS が行っているので、ユーザー側でキーポリシーの変更ができません)。
入社直後にこの問題に気付いていましたが、Aurora の KMS キーは後から別のものに変更できないので、対応コストが重くなかなか着手できずにいました。
しかし、元々ひとつだった AWS アカウントも AWS Organizations を軸としたマルチアカウント構成に移行し、その一環としてデータ分析基盤を刷新しようとする中でこの問題がブロッカーとして立ちはだかりました。
今後のサービスの成長を考えると早いうちに対処すべきなのはハッキリしていたので、重い腰を上げて AWS マネージドキーをカスタマーマネージドキーに差し替えることにしました。
Aurora で KMS キーを変更する 2 つの方法
先ほど書いたとおり、既存の Aurora クラスターの KMS キーを変更することはできません。設定できるのは起動時のみで、起動したあとは Reader インスタンスやスナップショットを含めて同じ KMS キーが使用されます。
なので、KMS キーを変更するには必ずダウンタイムが発生することになります。その上で、Aurora で KMS キーを変更するには次の 2 つの方法があります。
スナップショットをコピーする
1 つ目が、スナップショットをコピーするときに変更する方法です。元になるスナップショットは自動スナップショットでも手動スナップショットでも大丈夫です。
ドキュメントにも次のように明記されています。
同じ AWS リージョン 内で暗号化されているスナップショットをコピーする場合、元のスナップショットと同じ KMS キーを使用してコピーを暗号化できます。または、別の KMS キーを指定することもできます。
ただし、この方法で本番クラスターの KMS キーを変更するのは難しいでしょう。なぜなら、次の作業を短時間で終わらせる必要があるからです。
- メンテナンス中に Aurora へのアクセスを完全に止める
- 手動スナップショットを取得する(ここに時間がかかる)
- スナップショットをコピーし KMS キーを変更する
- そのスナップショットから Writer インスタンスを起動する
- 必要に応じて複数の Reader インスタンスを起動する
- アプリケーションに設定しているエンドポイントを変更する
Aurora のクローン作成でクラスターを復元する
2 つ目が、RDS の中でも Aurora だけが使えるクローン作成を使ってクラスターを復元する方法です。カミナシが採用したのもこちらの方法になります。
こちらもドキュメントに明記されていますが、クローンを作成する際は新規で Aurora クラスターを起動するのと同じように設定できるので、このときに KMS キーを変更できます。
[その他の設定] で、Aurora DB クラスターに通常行うような設定を選択します。
(中略)
暗号化は、その他の設定で利用可能なスタンダードオプションです。
詳細は公式ドキュメントに譲りますが、クローンで作成した新しいクラスターは元のクラスターと同じデータを共有するものの、個別の独立したボリュームを持つ新しいクラスターとして作成されます。そして、ボリュームのページに変更があったときに初めてコピーされます(これを Copy On Write プロトコルと呼びます)。
なので、クローンの作成はボリュームサイズに関係なく、インスタンスを起動する数分の時間で完了します。そのため、スナップショットをコピーするやり方と比べると、作業時間を大幅に減らすことができます。実際に 2 番のステップは数分で完了しました。
- メンテナンス中に Aurora へのアクセスを完全に止める
- クローンを作成する(このときに KMS キーを変更する)
- 必要に応じて複数の Reader インスタンスを起動する
- アプリケーションに設定しているエンドポイントを変更する
クローン作成で差し替えるときに気をつけること
データベースへの書き込みを確実に止める
Aurora のクローン作成は、RDS Blue/Green Deployments のようにバイナリログレプリケーションするわけではなく、作成した時点で新旧のクラスターが別のものになります。
そのため、クローンして旧クラスターを停止するまでの間はすべての書き込みを確実に止める必要があります。もし誤って新旧どちらにも書き込んでしまうとデータを復旧させることが困難になります。
カミナシでは API サーバのほかに非同期処理やバッチ処理もデータベースに書き込むため、メンテナンス中はそれらも漏れなく停止させて後からリカバリーを行いました。
また、メンテナンス中に想定外のバッチ処理などがデータベースに書き込んでしまうことを防ぐために、クローンを作成したら即座に旧クラスター(KMS キーを変更する前のもの)を停止させました。
バッファプールがリセットされる
別の観点として、クローン作成で新しいクラスターを起動するということは、MySQL のバッファプールもリセットされることを意味します。特に API コールのたびに参照されるようなテーブルだとバッファプールが温まっていないと障害に繋がるかもしれません。
カミナシは BtoB サービスのためリクエストの傾向がハッキリしており、朝の 8 時ごろに最初のスパイクがやってきます。そのため、翌朝のピーク時間帯にクエリが詰まる可能性を考慮して、深夜メンテナンスに参加するメンバーと早朝にモニタリングするメンバーに分かれて対応しました。
幸い、今回は何事もなくピークを乗り越えました。
おわりに
ずっと気になっていた積年の課題をひとつ解決することができ、データ分析基盤の刷新プロジェクトのブロッカーも解消することができました!
スタートアップの初期フェーズは少ない人数で開発していることもあり、こういった設定ミスは少なからず発生してしまうと思いますが、サービスの成長に合わせてちゃんと向き合っていきたいですね。
最後に宣伝です 📣 カミナシでは絶賛採用中です! 一緒に強いチームを作っていく仲間を募集しています!