サーバレス時代のマルチテナンシーを考える ~ Thinking about multi-tenancy in the serverless era ~ #cm_showcase
こんにちはおんづか(@onzuka_muscle)です。
本記事ではMAD事業部として1年以上前から支援をさせていただいている京セラ様のセッションをレポートします!
セッション概要
サーバレス時代のマルチテナンシーを考える ~ Thinking about multi-tenancy in the serverless era ~
昨今、DX 言葉に代表されるように、ビジネスをデジタライズし、サービサーとしてソフトウェアを提供するニーズが高まっています。 しかし、サービスを効率よく提供し、スケールさせていくためのマルチテナント戦略は事業者のサービス開発にとって大きな壁として立ちはだかります。 このセッションでは、京セラの新規事業であるロボティクスで取り組んでいるマルチテナント戦略について、その考え方とアーキテクチャを紹介します。
スピーカー
京セラ株式会社 ロボティクス事業部 サービス技術開発センター アプリケーション開発チーム 責任者
巽 健人氏
クラスメソッド株式会社 CX事業本部MAD事業部 部長
動画リンク
最初にまとめ&見所
本セッションは以下の流れで進んでいきます。
- なぜマルチテナント戦略に取り組むのか?
- そもそもマルチテナンシーとは何か?
- サーバレスを使ったマルチテナンシーでやりたいことを実現する!
- 実際のアーキテクチャの紹介
なぜマルチテナント戦略に取り組むのか?
京セラのロボティクスチームが新規事業を立ち上げる中で、マルチテナント戦略がビジネスにも直結してくるという話がとても興味深いです。
そもそもマルチテナンシーとは何か?
マルチテナンシーの定義と有名なパターンを紹介します。
サーバレスを使ったマルチテナンシーでやりたいことを実現する!
マルチテナンシーを考えたそもそもの目的を達成しつつ、典型パターンでは満たせなかった課題に対しての解決策を打ち出します!
実際のアーキテクチャの紹介
実際に開発中のアーキテクチャ概要をご紹介します。
サーバレス系のサービスから、Organizationsまでフル活用したアーキテクチャになっています。
セッションレポート
Introduction
事業の紹介
https://www.kyocera.co.jp/robotics/
京セラの新規事業としてロボティクスに取り組んでいます。AIを用いてロボットを自律的に動作させることで、より簡単に、もっと様々なシーンで、ロボットを活用いただけるサービスを開発しています。
私たちのチームでは、その中でもクライアントのアプリケーションやクラウドの開発を担当しています。
セッションのテーマ
本セッションのテーマはマルチテナンシーです。
特にBtoBでサービスを提供しようと考えた場合に避けて通れないテーマの一つがマルチテナンシーです。
今回は京セラのロボティクスチームがどのようにマルチテナント戦略に取り組んでいるかを紹介させていただきます。
マルチテナントに取り組むモチベーション
私たちはロボティクスをBtoBのサービスとして提供したいと考えています。
ここでいう「サービス」は、ハードウェア、エッジコンピューティング、クラウドのアプリケーションといった、AIを使ったロボットを動かすために必要な要素を1パッケージでお届けしたいという考えを指します。
中でもクラウドを検討するにあたり、下記3つのポイントを初めに検討しました。
データセキュリティ
ロボットの主戦場は工場、産業の現場なので、まだ出荷前の部品などを取り扱うケースが出てきます。万が一、その情報が流出してしまうとお客様のビジネスに多大な影響を与えてしまうため、データセキュリティに万全を期する必要があります。
サブスクリプション
サービスをサブスクリプションで提供するにあたり、データやアプリケーションを一元的に管理していく必要があります。
スケーラビリティ
ビジネスに合わせてシステムがスケールしないと、それがビジネス拡大のボトルネックになってしまいます。
そもそもマルチテナンシーって何?
SaaSでは「マルチテナントアーキテクチャによって複数のユーザーがリソースやソフトウェアを共有する」とされています。
ソフトウェアビジネスの魅力の一つは、限りなく低い複製のコストでソフトウェアの複製を繰り返すことで、ビジネスを大幅に、急激に、スケールできることです。
しかし、ソフトウェアをサービスとして提供するSaaSの場合、その後ろ側にインフラや運用が必要となります。お客様から、このサービスを使いたい! というニーズがあっても、インフラや運用が追いつかないとサービスを提供できず、ビジネス拡大のボトルネックになってしまう...、つまりシステムがスケールしない=ビジネスがスケールしないということになります。
その解決方法の一つが「マルチテナンシー」という考え方です。
マルチテナンシーはインフラや運用を複数のテナントが安全に共用することで効率を最適化するテクノロジー、と位置付けられています。
では、マルチテナンシーには実際にどのようなプラクティスがあるのでしょうか? 有名な三つの類型を紹介します。
①Silo Isolation(サイロアイソレーション)
ユーザーごとにデータベースとアプリケーションを準備して、各々の環境をご利用いただくパターンです。VMでユーザーごとに環境を作り、ユーザが自分の環境へ接続して、その中に入っているアプリケーションやデータを利用するイメージです。
- アプリの開発
- データベースが分かれており、アプリの開発者はマルチテナントであることをあまり意識する必要がないため、効率よく開発できます。
- リソースの効率
- テナントごとにデータベース・アプリケーションが必要となるため、新しいテナントを一つ増やすと、その分リソースを用意しなくてはなりません。そのためリソースの効率はあまり高くないと言えます。
- 運用
- 例えば、新しいアプリケーションをデプロイする場合、各テナントに対して一つずつデプロイの作業が必要なり、煩雑な運用が発生します。
- また、テナントが増えるごとに運用リソースを追加する必要があり、スケールが難しくなります。
②Pool Model(プールモデル)
サービスをご利用いただく全てのお客様で、アプリケーション・データベースを共有いただき、それぞれ一つで運用しましょう、という考え方になります。
- アプリの開発
- データベースは一つのため、どのリクエストに対してどのデータを返すべきかを実装して作り込む必要があります。アプリの開発者はどのような方法でマルチテナントが実現されているのかをしっかり理解している必要があり、開発の複雑性が高くなってしまいます。
- リソースの効率
- 新しいテナントが増えた場合でも、サーバーのキャパシティーに余裕があればサーバーを追加することで対応できます。サービス全体で必要なリソースを用意すればよいため、リソース効率は高くなります。
- 運用
- アプリを一つのサーバ群にデプロイすればよいため、比較的簡単に、アジリティをもってアプリケーションを届けていくことができます。
- 一方、ミドルウェアなど、特定の要素に対して負荷が集中することになり、高度な運用スキルを持ったエンジニアのアサインが必要です。
③Bridge Model(①と②の複合)
三つ目の方法は① Silo Isolationと② Pool Modelを複合したパターンになります。
色々な方法がありますが、ここでは例として、データベースをユーザー別に分離し、アプリケーションを共有する手法を掲載しています。
- アプリの開発
- データベースが分かれているため、リクエストに対するデータのフィルタを作り込む必要はありません。しかし、データベース接続先の切り替えや物理ファイルの取り扱いを意識しながら開発をしなくてはいけません。つまり、マルチテナンシーを意識した開発からは逃れられません。
- リソースの効率
- DBはユーザーごとですが、アプリのサーバーは共用のため、一定のリソース効率化が実現できます。
- 運用
- ①と②の良し悪し半々といった感じです。
どれにしたら良いのか?
三つの類型を見てきましたが、それぞれに良し悪しがあり、判断は難しくなります。
- 新規事業、スモールスタートで最初にどこまで作り込むか?
- 今後どのくらいシステムが大きくなるのか?
といった観点で、最適な方法が変わってきます。
改めてマルチテナンシーの目的を考える
ここまでの例はサーバーを使ってどのようにマルチテナンシーを実現するかを示しています。それに対して京セラのロボティクス事業では、クラウドや、CI/CD、サーバレスなどの新しい技術を使って、もう少し良い方法が取れないものかと考えてきました。
- マルチテナンシーの目的(振り返り)
- システムのスケーラビリティ
- リソース効率化によって生み出される価格競争力
- マルチテナンシーの辛み
- アプリの開発、システムの運用の難易度が高い
- どこまでいってもリソースを最適な状態に合わせるのは難しい
- 今現在、システム全体でどれくらいのコンピューティングリソースを使っているのかが分かっていても、例えば今後テナントか増えるのか減るのか、お客様の繁忙期があるのかなどの要因で必要なリソースが変わってきます。今の状態が分かっていても、先を見据えながら判断していかなくてはいけないことになります。
- また、システムを止めるわけにはいかないので少し余裕を持って設定をしてしまおう、となり、最適な状態を維持するのは困難です。
そこで!
サーバレスを使ってマルチテナンシーが実現できないだろうか
まず、サーバレスを前提にマルチテナンシーを考えてみると、
- 従量課金なのでコストの効率は必然的に最適化されます。使ったら使ったぶんだけのコストになります。
- インフラや運用もAWSのサービスにある程度任せることができるので、比較的意識せずに運用することができます。
ただし、サーバレスアーキテクチャでマルチテナントを実装しようすると、まだまだ辛い点があります。
例えば、
- データを適切に出し分ける必要があり、設計・実装が煩雑になります。
- クォーター(AWSアカウント単位で管理されているリソース等の上限)に伴う制約が生じる可能性が高くなります。
これを解決するために、データやアプリケーションの部分をどのように分割しようかと考えた結果、ユーザごとにAWSのアカウントを分けてしまう方法を採りました。これによって、論理的にデータ・アプリケーションを分離できるようになります。
しかし、それでもまだSilo Isolationのモデルと同じ形になるので、運用に辛い部分が残ります。
そこでAWS Organizationsに着目しました。AWS Organizationsは管理アカウントの配下で複数のアカウントを統合して管理することができるサービスです。
また、セキュリティ・運用系のサービスではクロスアカウントをサポートしている機能が多々あるので、それらを利用して複数のアカウントの運用を一つのアカウントに統合していくことができるのではないかと考えました。
開発運用面でも、一つのソースを複数のアカウントにデプロイできるようにする必要があると考えました。デプロイする対象はアプリケーションのコードだけではなく、クラウドの構成を定義したIaCのコードも含みます。
サーバレスで構築するサイロテナント+アカウント管理基盤が実現できれば、マルチテナント戦略で私たちが目指していた効果を発揮できるのではないか?という考えに至りました。
サーバレスなのでリソース効率が最適化され、また、スケーラビリティがあります。従量課金なのでコストも最適化されて、価格競争力が出せることになります。
サーバレスの特性で、システム運用の一部をAWSに委ねることができる点もポイントでした。新規事業を進めている中で、最初から大規模な運用を回すのは体制的にも難しい私たちにとっては魅力的でした。
また、この方式ではマルチテナンシーをほとんど意識することなくシステムの開発ができます。フィルターの部分を作りこんだり、データベースを切り替えるような部分を作りこんだりせずに必要な機能にフォーカスして開発ができます。これはお客様のニーズに対して開発し、それをアジリティもって届けていく点で有効と考えています。
しかし、アカウント管理基盤を作っていこうと思うと、AWSの高度なナレッジが必要になります。例えば、「AWSアカウントをどういう風に管理するか」「クロスアカウントでデータを集約して運用するにはどのようなサービスを使えばいいのか」等等...
クラスメソッドの支援
そこでクラスメソッドの濱田さん率いるMAD事業部に支援いただきました!
アカウント管理基盤の検討からご参加いただき、ディスカッションさせていただきながら実際のアーキテクチャを構成してきました。IaCコーディングなど、構築でもご支援をいただいています。また、他にもアプリケーションのバックエンドやフロントエンドの開発など、さまざまな面でご支援をいただいています。
アーキテクチャの紹介
OU設計
こちらのブログで紹介しているAWSのベストプラクティスを参考にしつつ、京セラのロボティクスチームとクラスメソッドで最適な構成をディスカッションして決めていきました。
workload
図中のworkloadと書いてある部分が実際にユーザーにアプリケーションを提供するためのOrganizational Unit(OU)になります。
この中にユーザーごとのAWSアカウントがあり、それぞれにサーバレスで構成されたアプリケーションがデプロイされ、データを持っている構成となります。
core
workloadを支える基盤部分としてinfrastructure、security、deploymentがあります。
- infrastructure
- Route53のように、サービス全体で利用するサービスを置いています。
- security
- 各アカウントのログ集約やセキュリティ通知の運用を行っています。
- deployment
- workloadの各アカウントにアプリケーションを配布しています。
基盤部分のOUは今後、開発を進める中で追加していくかもしれません。
ここからは基盤部分の例として、CI/CDとセキュリティ運用を紹介します。
CI/CD
コードの管理にはGitLabを使っています。CI専用のアカウントを設けており、GitLabのCI基盤であるGitLab Runnerを構築しています。
この例では、CIの処理で作成されたArtifactはCDアカウントにレプリケーションされ、そのイベントをEventBridgeで拾ってStep FunctionsからCodeBuildを並列で実行、各アカウントにデプロイする流れになっています。
このような、一つのソースから複数のアカウントに対してデプロイをする構成も、クラスメソッドから提案いただき、議論しながら構築してきました。
Sec Ops
予防的措置
- AWS Organizationsの機能で、OUごとに配下アカウントのアクションを制限するSCPを利用しています。
発見的措置(リスクやインシデントの検知)
- Security Hubを用いて、セキュリティのプラクティスに沿っているか定期的にチェックしています。これも各アカウントで検知した結果を一つのアカウントに集約し、そこからSlackに通知する仕組みになっています。
- Security Hub以外のAWS Config RulesやGuardDutyの通知についても、一つのアカウントに統合する仕組みで運用しています。
また、通知があっても調査する時に各アカウントに入っての調査が必要になると、どうしても運用が大変になってしまいます。この構成では、CloudTrail、Config、アプリケーションのログなどを専用のアカウントに集約しており、調査の際に極力各アカウントへのログインが必要ないように構成しています。
Insecure API CallsやAbuse Reportなどのリスクを伴う特定のイベントについても、統合的に検知して通知する構成になっています。
マルチテナンシーを検討する中で感じたこと
一つ目は基盤を作るのは大きな労力がかかるという点です。
一つのテナントに一定規模のデータが存在する前提でこの構成を検討しましたが、例えば、テナントの数が多い、もしくは、BtoCか、それにに近い形でサービスを提供する場合など、それぞれのケースで必要なマルチテナンシーの形は変わってきます。
つまり、サービスの目的や規模に合ったマルチテナンシー構成を検討していくのが大事になります。
二つ目はこの構成はサーバレスが大前提になります。
例えば、アカウントが増えた時にその中にEC2があると、アカウントが増えた分EC2もどんどん増えてしまってコストの最適化はできないことになってしまいます。
アーキテクチャによっては技術的な制約が発生しうるという点を抑えておく必要があります。
最後に基盤構成の変更が難しいという点です。
例えば、SCPのアクション制約をアップデートしようとした場合、同じアカウントの構成を一通り作って検証する必要があり、とても大変です。また、途中でAWSのベストプラクティスを参考にした話が出てきましたが、検討中にも新しいベストプラクティスが出てきて軌道修正が必要になったこともありました。
一度構築した基盤部分を変えるのは大変ですが、クラウドも進化し続けるので常に最善とは限りません。それを前提に、できる限りの検討が必要になります。
「目的と用途に合った"マルチテナンシー"を探しましよう!」
参考
特にSaaSでよく使われるマルチテナント構成を紹介したブログや、ホワイトペーパー、GitHubのリファレンスアーキテクチャなどが公開されています。
京セラのロボティクスではGoogle Cloudも併用しています。Google Cloudでもk8sのnamespaceを使った方式や、プロジェクトを分割する方式が紹介されています。方式としてはAWSをご利用の方でもご参考になると思います。
Google Cloud k8s multi-tenancy
Google Cloud enterprise multi-tenancy
Happy Hacking!
QA
Q1.AWS Control Towerは使わない?
構成を変更したい場合に対応できないことが多い、というのが大きな理由になります。
例えば、ログの集約で単一アカウントに集約することは簡単にできるのですが、それが環境(SDLC + prodなど)別に集約先のバケット分けようと思うと、実現が難しくなります。
今後のアップデートでケアされるかもしれませんが、現時点で柔軟性の面で合わなさそうだと見送りました。
Q2.CIとCDアカウントを分けた主な理由はなんでしょう?
CIのアカウントとCDのアカウントでやりたいことがそれぞれ違うためです。
特にCDのアカウントには強い権限を持たせる必要があります。workloadアカウントにリソースを展開できるので、触れる人を限定したいと考えました。
またCIのアカウントについても、静的テストだけではなく、例えばAWSのリソースを暫定的に作ってテストをする処理を行っていたりします。これもアカウントを分ける理由になっています。
Q3.ユーザーのテナント追加はどのように行うのでしょうか?別途テナント追加のオペレーションがあることでしょうか?
そこまでアカウントが増えない間は手作業で運用して、そこで出てきたオペレーションを自動化していく形で進めていく予定です。
自動化の際は、テナントを管理するためのアカウントを設け、そこからアカウント追加ができる構成を考えています。
Q4.チーム構成として内製志向だと思うんですが、外部のベンダーに支援を依頼する事の意図やメリットをどう考えておられますでしょうか?
基本的に内製であることが望ましいと思っています。
アジリティーやアプリケーションに対してオーナーシップを持つなどの観点から、自分たちで開発していくことは重要だと考えています。
一方で、ずっと自分たちが作っているものをメンテナンスし続けると、技術的にサイロ化するリスクがある、とも思っています。
自分たちが今持っているコードや、扱えるアーキテクチャの範囲でサービスを考えるようになってしまう、もちろん勉強はしつつも、新しいものを取り入れるという判断は難しい面があります。
そこでAWS、Google Cloudにも詳しいクラスメソッドにご支援を頂いています。
色んな観点で技術に触れておられるエンジニアに入ってもらうことで、間口を広げられると思っており、実際にそういったご支援をいただきながら作ってきています。
メインは自分たちで担当しつつ、様々な観点からアドバイスをいただきながら作っていくことが理想と考えています。
Q5.技術的に難しい領域がたくさんあると思うのですが、チーム編成はどのようにすすめてこられたんでしょうか?
今のチームは2年前当初、私ひとりでスタートしました。その後、グループ会社からの出向や中途採用させていただいたメンバーで構成されています。
ゼロワンの開発というところに魅力があると思っており、「ぜひやりたい」という人に入って来ていただいて現在の体制になっています。
中途採用については、現時点でのスキルセットにこだわりすぎず、新しい技術をキャッチアップし続けていけるような行動特性を重視してきました。
Q6.多方面の技術領域を一貫して管理し推進していくなかで、気をつけていることがあれば教えて下さい
あまり制約を作らない、ということを考えています。
クライアントのアプリ、つまりUIを作るときの考え方やサーバーのアプリを作るときの考え方など、それぞれ違ってくるので、要件に対して最適な要素技術、最適な方法を採りたいと考えています。
例えば、「サーバーの開発にこういう言語を使いたい」といった話が出た時に、それが今考えられる最適解なのかとか、そういったところはディスカッションをしたりしますが、クライアントとのサーバの開発プロセスや観点を同一にするとか、そういうことはしないように心がけています。
Q7.コスト管理はどのようにしていますか?
AWS Organizationsのコスト集約機能で見ています。まだリリース前でそこまで詳細には考えられておらず、プレ運用などで集計して整えていく予定です。
ちなみに、サーバレスのボリュームディスカウントはOrganizations配下のアカウントでまとめて集計されるということなので、そういった点もこの構成をとった理由の一つになっていたりします。
レポート執筆者あとがき
私も支援に入っているプロジェクトであったため、セッションレポートに名乗りをあげさせていただきました。
セッションを視聴した私の感想は「今、そして先のことまで見据えて最新技術をフル活用しているすごい事例だ!」です。
またQ4でもありましたが「内製」に関して、MAD事業本部として理想の支援の形になっていると感じます。
私が今触っているアーキテクチャの部分に関して「ああ、そういう検討があってビジネス的な視点もしっかり取り入れつつ、その時考えられるベストな決断があって今のような形になったんだなぁ」と新たに知ってしみじみするポイントがたくさんありました。
とにかく非常に楽しいセッションでした。
私は主にアカウントの管理周り(新規作成したアカウントに対するリソース自動展開、チューニングなど)や、セキュリティ運用の部分をこれまで担当してきました。
マルチアカウントでセキュリティの集約をしたり通知を扱ったりするといったところはまだ情報もそこまで多くなく、検証も大変で、そのうちにどんどんとアップデートがくるという、なかなかのハードモードで苦戦を強いられるところも多々ありましたが、チャレンジを楽しめる環境なので全力で支援させていただいてきました。これからもチャレンジは続く予定です。
今回のセッションを受けて本プロジェクトをより俯瞰した視線で把握することができたので、これからもっとスケールしやすく運用がラクな構成にしてやろうと思います!