clock2020.12.22 08:35
SERVICE
home

少人数の開発で Kubernetes を活用するための設計戦略

AUTHOR :   ギックス

この記事は GiXo アドベントカレンダー の 22 日目の記事です。
昨日は、 ギックスの考えるデータサイエンスとは でした。

MLOps Div. の廣津です。最初に断っておきますが、タイトルは半分釣りのポエム記事です。

本アドベントカレンダーの中で、私の所属する MLOps Div. が開発を担当している、「トチカチ」や「機械学習基盤 “Refeed”」の裏側を紹介してきました。組織紹介の記事でも書いているとおり、我々の組織はフロントエンド2名、インフラ・バックエンド1名(私)という少人数での開発を行っています(2020年12月現在)。

少人数で効率よく複数のプロダクトを開発していくためには、技術選定はもちろんですが、プロダクトのアーキテクチャ設計が非常に重要だと私は考えています。本記事では、私が弊社で Kubernetes を使った複数のプロダクトの設計・開発に関わる中で Kubernetes をどのように活用してきたかについて、私なりの観点をまとめてみようと思います。ポエムなので、あまり細かいところは突っ込まずに温かい目で読んでいただけると幸いです…。

なお、以降の話は私のチームで利用している GCP を前提としている部分が多々あるので、 AWS や Azure ユーザの方は伝わらなかったらごめんなさい。

アーキテクチャを考える前に

クラウドサービスの普及に伴って多様なサービスが簡単に利用できるようになり、一昔前に比べると「とりあえず動くものを作る」という観点においてはかなり開発の敷居が下がったように思えます。しかし、それは同時にアーキテクチャを考える上で取り得る選択肢が大幅に増えたことも意味しており、本当に最適なアーキテクチャを考えるために求められるスキルはむしろ上がっているのではないかと感じます。

ところで、システムのアーキテクチャをゼロから考える際に、皆さんはどんなことを考えているでしょうか。機能/非機能要件を満たした上でコストを抑えることやセキュリティを担保することはもちろん言うまでもなく重要ですが、特に少人数(1人)の運用を前提とするシステムにおいては、以下を念頭に置いておく必要があると考えます。

  • 構成がシンプルであること
  • 運用負荷が可能な限り低いこと
  • 自動化されていること

こんなの少人数じゃなくても当たり前の話じゃないか、と思われるかもしれないですが、最初期に適切なアーキテクチャを設計しておかないと、システムの複雑化から来る運用負荷増大やバグ頻発などの負のループに陥って、人数が少ないとチームが崩壊してしまう恐れさえあります。少ないメンバーで日々上がってくる開発要望や改善業務をこなしながらも安定した運用を行うためには、シンプルさと運用負荷の低さは譲れないポイントです。

もちろん、サービスのグロースに伴ってアーキテクチャの刷新は段階的に必要となってくるものですが、最初からそれを想定しておくのとおかないのでは設計図も全く異なってくるかもしれません。逆に、市場やユーザに受け入れられるかも分からないものに過剰な将来設計をしても無駄になってしまう場合もあるので、その塩梅は設計段階で見極める必要があります。

コンピュートリソースの選定

ふわっとした話ばかり書いても仕方ないので、ここからはもう少し細かい話をしていきます。

何らかのロジックやアプリケーションをプログラムとして書いた後には、それを動かすための計算リソースが必要です。具体的な計算リソースの選定基準としては、例えば以下のようなものが考えられるでしょう。

  • 使用する見込みのリソースはどれくらいか
  • 垂直・水平スケールが必要か
  • コールドスタートを許容できるか
  • タイムアウトは何分まで許容できるか
  • 運用時に想定される負荷はどれくらいか

これらを正確に判断して実行環境を選定するには、利用可能な選択肢それぞれについて特性を理解しておくことが重要です。要件の中で譲れないポイントはどこであるのか優先度を整理してから、コスト、運用負荷、拡張性、構成のシンプルさなどを天秤にかけながら、要件を満たす最も有力な選択肢を選ぶことになります。どこから手を付けてよいか分からないという場合は、 GCP の場合はホスティングのユースケースとオプション一覧のページが一つの指針になります。以下の表は、本記事執筆時点で公開されているページから引用しています。最新の情報は公式ページをご参照ください。

少し話題が逸れますが、クラウドサービスは仕様の変更や新しいサービス・機能の追加が次々と行われていくものなので、常にキャッチアップを怠らないことが重要になってきます。 GCP の場合は、以下の RSS を Slack などに登録しておいてウォッチしておくのも1つの手です。
https://cloud.google.com/feeds/gcp-release-notes.xml

ここまで色々書いてはきましたが、結局の所は要件に合わせて考えてね、というのが結論です。

Kubernetes という選択肢

本アドベントカレンダーでも紹介してきたトチカチや Refeed といったプロダクトは Kubernetes をメインのコンピュートリソースとして使用しており、開発環境やその他のプロダクトも含めると、私1人で現在5つの Kubernetes クラスタの面倒を見ています。ここまで読んできた方は、 Kubernetes は運用負荷が高いので少人数の開発で用いるのは得策ではないのではと思われるかもしれません。

では、実際に Kubernetes を使う場合に運用にどれくらいの手間がかかるのでしょうか。Kubernetes の運用で大変になってくるところは、更新頻度の早さから来る最低でも3ヶ月に1度のクラスタアップグレードの手間や、管理対象が多種に及ぶことなどが挙げられると思います。

前者のクラスタアップグレードに関しては、 GKE の場合は Release Channel や Surge Upgrade といった機能を駆使することによってユースケースに合わせたアップグレード戦略を設定できるため、適切な設定でクラスタが構築されていれば、基本的に Google に運用をお任せすることができます。私のチームでは Terraform を使って全ての Kubernetes クラスタの設定を管理しているため、クラスタの構築段階でこれらの設定を行うようにしています。

後者の管理対象の問題については、アーキテクチャ次第で如何様にも工夫できる部分です。少人数で Kuberenetes を使う上で重要なのは、ここで Kubernetes を使い倒しすぎないことだと私は考えています。多機能であるが故に色々なことを Kubernetes 上で実現したくなってしまうかもしれませんが、他のマネージドサービスで簡単に達成できることにまで手を出すべきではありませんし、可能な限りシンプルな構成にできれば運用負荷も軽減できます。

以下は以前の記事でも紹介した Refeed とトチカチのアーキテクチャ図ですが、ここでは Kubernetes は Job を実行するだけの基盤として使用する設計としています。(厳密にはそうではない部分もありますが省略します)

他に私が複数のプロダクトを設計・開発する中で工夫してきた点としては、上の2つのアーキテクチャ図のように構成をテンプレート化したことも挙げられます。プロダクトの性質によって上手く行かない場合や最適化できない場合もあるかと思いますが、 Terraform を使ってリソース管理を行っている場合、コピペしながら一部の設定を変えていくだけで同様のアーキテクチャを簡単に構築することができます。これは構築の手間だけでなく、運用面においてもプロダクト間の差分によるコンテキストスイッチを防ぐメリットもありました。

おわりに

結局何を伝えたいのかよく分からない内容になってしまいましたが、少人数のチームでの開発・運用であっても、 Kuberenetes は十分に選択肢となり得るということが伝わっていれば幸いです。今回は Kubernetes を推しているような記事になってしまいましたが、私が弊社で開発してきたプロダクトでは要件上他の選択肢がなかっただけであり、 Cloud Run などをメインに使用する案も要件によっては十分に考えられます。前半にも述べたとおり、要件に応じて最適なアーキテクチャを検討していくことが何よりも重視されるべきです。

明日は MLOps Div. Lead の堀越より、「React で作る中規模 SPA のレイヤードアーキテクチャ」を公開予定です。


Masaaki Hirotsu
MLOps Div. 所属 / Kaggle Master
機械学習・データ分析基盤の構築に関わる事例や、クラウドを活用したアーキテクチャについて発信していきます

SERVICE