マルチAZ化から学んだ無停止でインフラを変更するために考慮すべき3点

OGP

はじめに

こんにちは。ブランドソリューション開発部の蔭山です。普段はFulfillment by ZOZO(以下FBZ)というサービスを担当しています。FBZはZOZOTOWNの倉庫や物流システムをブランドさんの自社ECでご利用いただけるサービスです。

先日、FBZが稼働しているシステムについて、サービスを停止することなくマルチAZ化しました。サービスを停止せずにシングルAZ環境からマルチAZ環境へ切り替えるため、様々な調査や事前準備をした結果、無事故で切り替えることができました。この記事では、実際に対応した事例を交えながら、無停止で大規模なインフラ変更するために重要だったいくつかのポイントをご紹介します。

稼働中のサービスで、マルチAZ化といった大規模なインフラ構成変更を検討されている方の参考になれば幸いです。

マルチAZ化とは

マルチAZ化とは、単一アベイラビリティゾーン(Availability Zone、以下AZ)内で構成されているAWSのリソースを、複数のAZにまたがるよう再構成することを指します。単一AZで動いている状態をシングルAZ、複数のAZで動いている状態をマルチAZと称します。複数のAZを使うことで、AZ単位での障害が発生した場合でもサービスを継続できるため、サービスの可用性向上に効果的です。FBZでは、東京リージョンの3AZにまたがるよう構成を変更しました。

マルチAZ化を実施した背景と課題

FBZは、LambdaやDynamoDBなどのフルマネージドサービスを用いたサーバーレスアーキテクチャで構成されたサービスです。構成の詳細についてご興味のある方は、以下の記事をご覧ください。 techblog.zozo.com

AWSのフルマネージドサービスを最大限活用して構築されたFBZですが、サービス構築当初から一部のAWSリソースに関してはシングルAZにのみ存在しました。構築当時は求める可用性としてそれで十分でした。その後、特に大きな問題もなくサービスを拡大してきましたが、拡大するにつれシングルAZ構成の部分を単一障害点として問題視するようになりました。

シングルAZで稼働しているFBZ構成図

FBZはZOZOTOWNを始め、ご利用いただいているブランドさまが管理されている多数のECシステムや基幹システムと密接に関わるサービスです。短時間でもサービスを停止してしまうと、数多くのブランドさまに影響が及んでしまいます。そのため、サービス停止なしでマルチAZ化を実施することにしました。

無停止で大規模なインフラ構成変更するために

このような背景からFBZのマルチAZ化を進めることになったのですが、当時3つの課題がありました。

  • Lambda、DynamoDBなど、主要なリソースはServerless FrameworkもしくはCloudFormationで管理されていたが、FBZ全体をIaCで管理できていなかった
    • VPCやElasticsearch Service、S3など
    • 設定値の情報もまとまっていない
  • どこがシングルAZで、どこが既にマルチAZなのか、AWSリソースの状態が完全に把握できていなかった
  • 切り替え時に発生するAWSサービスごとのダウンタイムが把握できていなかった

以上の課題に対し、様々な調査や事前検証を経て、最終的には無事故でFBZ全体をマルチAZ化できました。特に力を入れた3つのポイントについて、実例を交えながらご紹介します。

ポイント1:サービスの現状を徹底的に可視化する

現状の設定や仕様を把握せずに、大規模なインフラ構成変更を進めることはできません。利用しているAWSサービスについて、現状どのような設定がなされているのか、AZ毎にどう配置されているのかなどを可視化することにしました。

Former2を利用してIaC化する

まずは、FBZ全体のIaC化に着手します。AWSのコンソール画面を1つずつ調べる方法もありましたが、本件ではFormer2というツールを利用しました。

Former2は、AWS上に存在するリソース情報からCloudFormationやTerraformなどのテンプレートを作成してくれるOSSです。 これを利用してVPCやElasticsearch ServiceなどのIaC化されていないリソースを一括してCloudFormationテンプレートへ出力できました。

また、テンプレート出力後はCloudFormationの既存リソースのインポート機能を用いて、既存リソースをCloudFormationスタックに反映しました。

全リソースのCloudFormation管理が実現したことで、その設定値についてもコードで一覧できるようになりました。また、リソースをアップデートしやすい状態となりました。

公式ドキュメントからサービス仕様を把握する

完成したCloudFormationテンプレートを元に、各AWSサービスの公式ドキュメントを調査し、どのリソースをマルチAZ化すべきか対象のサービスを絞りました。最終的にFBZでは以下のリソースを変更することにしました。

  • VPC
    • 1AZに集中しているサブネットを3AZに拡張する
  • Lambda
    • 関数の起動対象となるサブネットを変更
  • Elasticsearch Service
    • ノードの追加

ポイント2:切り替えるタイミングでの挙動を事前に試す

調査の次に重要なのは、事前検証です。サービスを無停止で事故なくインフラ構成を変更するためには、事前に本番相当の検証環境で挙動を確かめておくことが大事なポイントです。どのように検証したのかを実例を通してご紹介します。

VPCの場合

FBZでは、既存のVPCリソースにはほとんど手を入れず、サブネットやNATゲートウェイ、ルートテーブル、VPCエンドポイントなどのリソースをそのまま別のAZにも作成することとしました。実際にはこのような構成で設計しました。

マルチAZで稼働しているFBZ構成図

この時点で、既存リソースをCloudFormationスタックにインポートしていたため、構成変更にあたっては既存リソースへ影響を与えないよう注意深くテンプレートを記述しました。結果としては既存のリソースに影響はなく、新規リソースのみ作成できました。

Lambdaの場合

FBZでは、Serverless Frameworkを利用してLambda関数やDynamoDBなどの設定を管理しています。LambdaのマルチAZ化においてはServerless Frameworkでの設定値を一部変更するだけで対応できました。

具体的にはserverless.yaml内の、provider.vpc.subnetIdsに今回追加したプライベートサブネットのIDを追加するのみとなります。以下にサンプルを記載します。

provider:
  name: aws
  (略)
  vpc:
    securityGroupIds:
      - sg-xxxxxxxx
    subnetIds:
      - subnet-xxxxxxxx1
      - subnet-xxxxxxxx2 # 今回追加したプライベートサブネットID1
      - subnet-xxxxxxxx3 # 今回追加したプライベートサブネットID2

また、設定変更時もLambda関数の実行が継続すること(呼び出しが瞬断しないこと、異常終了しないこと)を確かめるため、本番環境で実際に発生する量のトラフィックを流しつつ、Serverless Frameworkでリリースする検証しました。結果として同期呼び出し・非同期呼び出しともに、問題ありませんでした。サブネット設定の変更をしたその次の関数呼び出しからマルチAZにて関数が起動します。そのため、起動中の処理には影響が無いことがわかりました。

Elasticsearch Serviceの場合

Elasticsearch Serviceには、Blue/Greenアップデートで設定を展開していく仕組みがあります。これによってサービス停止することなくマルチAZ化できることがわかりました。 こちらもAWS Lambdaと同様に実際のトラフィック量を流しつつ設定変更時の挙動を検証しましたところ、エラーなく切り替えできることが確認できました。

ポイント3:サービス無停止を実現するための分割リリース設計

調査、検証ときて、最後に重要なのはリリース設計です。どのような順番であればサービスを停止せずに済むのか、また有事にロールバックできるのか、その一連の流れを設計することが大事なポイントです。以下のようにリリースを数回に分けて実施しました。

  1. VPCリリース
  2. サービス全体に影響が出ていないか検証、数日間監視
  3. Elasticsearch Serviceリリース
  4. Elasticsearch Serviceに関連する処理で影響が出ていないか検証、数日間監視
  5. 疎通検証用Lambdaを新しく追加したAZでリリース
  6. 疎通検証用Lambdaで各種リソースの疎通確認
  7. FBZを構成しているLambdaをリリース
  8. サービス全体に影響が出ていないか検証・監視

一度に全部の構成を変更するのではなく、一部のみを変更し、検証・数日間監視するといったリリースフローとしたことにより事前検証で検知できなかった不測のエラーに備えました。結果としてはいずれも問題なくリリースできましたが、このように万が一に備えたリリースフローを組むこともサービス停止させないために大切です。

まとめ

現状の可視化・検証・リリース設計を重点的に実施することにより、サービスを停止することなく大規模なインフラ構成変更を実現しました。以上の3点は、決して特別なことではないものの、実際にそれらを丁寧に実施することでその重要性を改めて感じました。

ZOZOテクノロジーズでは、一緒にサービスを作り上げてくれる仲間を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください!

tech.zozo.com

カテゴリー