新規サービスを支えるための運用と、運用に使用する技術を考える

本記事は リクルートライフスタイル Advent Calendar 2019 22日目の記事です。
飲食領域で新規プロダクトを開発している伊芸です。

私はこれまではずっと大規模プロダクトのインフラの構築・運用を担当していました。今年になって初めて新規プロダクト開発を担当させてもらい、新たな環境・小さなチームで動くことになり、戸惑いや悩みが多々ありました。

この記事では、人的・時間的リソースが限られた中で、DevOpsの何にこだわり、何を妥協するのかを明確にするまでの葛藤と、そこから得られた学びについて、共有します。なお、以下で述べることは教科書的な話ではなく、同じ悩みを持つ読者に向けた一事例でしかないことをご了承ください。

今回担当した新規プロダクト開発チームの特徴

新規サービスを作る際にはMVPを作り小さく検証を繰り返すことはよく採られる手法かと思われます。その場合、できるだけ早くユーザのもとにサービスを届け、価値検証を行なうことが優先されることが多く、必要以上の品質を追求したプロダクト開発は必ずしも求められていることではない場合もあります。また、小さなチームで機動性高くプロジェクトを進める必要があったり、開発メンバーも大規模組織とは違い少人数でプロダクト開発に必要な作業をすべて完遂しなければならないことも間々あります。

私の属するチームは開発人数が少なく1人が複数の技術を触らなければなりませんでした。私の場合だとある時期はReactやSpring Bootを触り、後半では本格的なインフラ構築に向けてk8s manifestやTerraformを触る日々を過ごしておりました。このように自分の主担当外の領域にも柔軟に対応し、その都度必要なことをチームとしてやりきる動き方が求められていました。

少ないリソースで何をどこまでやりきるか

設計をする際にはまず脳内で理想的な設計を行ない、なんとか実現しようとする方もいらっしゃるのではないでしょうか。私はそのタイプで、「可能であればこの設計を実装に反映させ、イケてる運用にしたい!」といった考えが生まれ、そのことばかり考える癖があります。 しかし、どのようなプロジェクトでもあることですが、リソースが限られている中でプロダクトを作るとなると、何かにこだわるには何かを妥協しなければなりませんでした。私を含め、メンバー全員が可能な限りアプリケーション開発に集中できる環境にさせたいという思いとは裏腹に、アプリケーションを運用するとなると生まれる運用手法についての追求と妥協の選択を行なうような試行錯誤はほぼ毎日のように起きていたため、「このままでは効率が悪い」と思い、運用対象ごとに重要度を設定し、判断をしやすくしました。さらに具体的な方法論を以下のように整理し、どのような技術・ツールを使うかまでを決めました。

<前提>

  • サーバサイドのアプリケーションはSpring Bootを使用している
  • アプリケーションはすべてGKE上で稼働
  • インフラはGCPを使用し、Terraform管理
  • 以下評価はチームメンバーのこれまでの使用した技術をもとにした相対評価になります
    • 学習コスト: メンバーがこれまでその技術を活用したことがあるか否かで設定
    • 運用難易度: メンバーがその技術の理解度とその技術特有の異常が発生した際に早急に適切な対応が取れるかどうかで設定
  • テーブル内の"ステップ"は、DevOpsとアーキテクチャで定められている「コード・ビルド・テスト・パッケージ・リリース・コンフィギュレーション・モニター」において、今回検討余地のあった「ビルド・テスト・リリース・コンフィグレーション」に絞っています。
ステップ 検討優先度 理由
ビルド 頻繁に行なう
開発環境でartifactを確かめたい
テスト 頻繁に行なう
正常なartifactを扱いたい
リリース 多くて週に1度を想定
カナリアリリース等はまだ必要ない
直近A/Bテストの実施もない
手運用も複雑ではない
コンフィグレーション 更新頻度はアプリケーションと比べ少ないが、
手動で変更を繰り返すことによって
インフラリソースを管理しきれない状態にさせたくない

検討した手法

ステップ 検討した手法 学習コスト 運用難易度 採用
ビルド・テスト Jenkins
drone 採用(詳細は後述)
リリース Jenkins
Spinnaker
手動(kubectl 採用
コンフィギュレーション Terraform 採用(インフラ構成管理として)
Ansible 採用(VMのプロビジョニングツールとして)

個人的には判断軸を設定するとこだわる対象が決まり、期間内・資源内でやりきることに意識を集中できるため、この取り組みを行なってよかったなと思いました。社内には多くのエンジニアが在籍しており、今回使っていた技術スタックにも詳しい先輩エンジニアもいるため、相談できる環境であったこともあり、とても助けられました。

妥協したこと

ここまでの話だと順当に物事が進んでいったように映っているかもしれません。しかし、その裏では泥臭い検証を何度も行なっていたので、検討項目には挙がったが採用に至らなかった手法の経緯についても、せっかくなのでこの場でまとめます。ここでは検討した手法に加えて、採用すると決めたツールの運用品質向上に向けた検証も含めて列挙します。

検討項目 検討結果 経緯
CIとしてのJenkins Xの利用 同等の運用難易度なので、「これからナレッジを積みたいもの」が何かを考えた時、droneとなった - Jenkins/drone共に運用課題を認識しているメンバーがいたが、同じ辛さならdroneのほうが頑張れる
- droneだとRepositoryごとにコードで管理できるのでブラックボックスが少ない
CDとしてのJenkins Xの利用 Jenkins Xを運用するのはあり。しかし今ではない - メンバー全員が使い慣れているので有力候補だった
- なんでもできるので初期からJenkinsに頼りすぎると後々メンテナンス・かゆいところに手が届かない事例が増えそう
- 将来的にk8sのデプロイメントを扱うことを考えると、カナリアリリースなどに対応しづらそう
Spinnakerの導入 運用難易度が高いため不採用 - halyardサーバを持つ必要があった
- 識者がチームにも社内にも少なく、チャレンジポイントにするとリスクが高い
- spinnaker上で障害が置きたときに対応ができない
droneのk8s化 1インスタンスのスケールアップで対応 - ジョブを並列で走らせ、CI高速化を図りたかったが、思ったよりも構築に手間がかかった
- 運用するとなると気にすることが増え、リソースが割かれそう
インフラテストの導入 セキュリティ監視をしてくれるチームに作業を委譲 - 特にネットワーク監視をしたかったが、Serverspecなどのインフラテストツールはその確認には不向き
- インフラ構築経験のあるメンバーが少なかったため、メンテナンスが難しい
- 社内にクラウドシステムの監視を行なってくれるチームが存在していたため、初期は彼らに作業を委譲することのほうが担保してもらえる項目が多く、社内的に妥当なインフラテストを担保してもらえた

これらは「今後はずっと検討しない」というわけではなく、あくまで今のチームの技術力・フェーズにあっていないと判断したものだと思ってもらえると嬉しいです。サービスの成長に合わせ、運用も変化していくはずなので、その都度Opsで採用する技術や運用の仕方を調整していこうと思っています。

個人的な振り返り

開発者としては「この技術を使ってみたい・この基盤に仕上げたい」という気持ちだけで動かず、「今、サービスを成長させるために必要なことなのか?」という批判を頭の中で行なう癖がついたのはよかったなと思う反面、短期間に検証と導入を何度か繰り返して運用が何度も変わりメンバーに迷惑がかかったことは反省でした。これからもサービスの運用・拡大は行われるので、その都度ツールや品質についての調整を加えていければと良いなと考えています。