Quipper のマイクロサービス化への道のり / Quipper's Road to Microservices

33685a20ded68e6861bec3c1bd7f0870?s=47 Yuya Takeyama
November 08, 2018

Quipper のマイクロサービス化への道のり / Quipper's Road to Microservices

Kubernetes Meetup Tokyo #14 における発表です
https://k8sjp.connpass.com/event/104450/

33685a20ded68e6861bec3c1bd7f0870?s=128

Yuya Takeyama

November 08, 2018
Tweet

Transcript

  1. Quipper のマイクロサービス化への道のり @yuya-takeyama

  2. ➔ 技術的にエッジな話は少なめかも... ➔ 本番運用にまつわる泥臭い話多め 今日話すこと

  3. 01 02 03 04 05 Agenda | 自己紹介 Quipper の紹介

    Kubernetes への移行 Kubernetes の運用 Microservices 化への道のり
  4. 01 自己紹介

  5. @yuya-takeyama ➔ 2015年9月~: Web Developer at Quipper ◆ Rails/Backone.js/React.js/React Native

    などなど ➔ 2018年4月~: SRE at Quipper ◆ Kubernetes への移行や Kubernetes の運用およびその効率化 ◆ Kubernetes 環境への移行に向けた開発者のサポートもミッション ◆ インフラ・SRE としてはまだまだ修行中
  6. @yuya-takeyama ➔ 好きな言語は Ruby, Go, TypeScript ◆ Elixir を勉強中, Rust

    は挫折気味
  7. 02 Quipper の紹介

  8. Quipper のプロダクト ➔ Quipper ◆ フィリピン、インドネシア、メキシコ、日本で展開する教育サービス ◆ 先生は宿題を出せて、生徒が問題を解くとその進捗が管理できる ➔ スタディサプリ

    ◆ 基本的に機能は Quipper と同じだが、日本ではスタディサプリというブラ ンドでやっている ◆ かつての受験サプリ。2016 年にリブランディング ◆ 日本では「神授業」の CM でおなじみ ◆ 漫画「ドラゴン桜2」にも登場
  9. Quipper とスタディサプリ ➔ ソースコード的にはほぼ同一 ◆ 環境変数等のフラグでスタイルや機能の出しわけが行われている ◆ AWS のアカウント自体別で、別々のリージョンにデプロイ

  10. Quipper SRE チームの紹介 ➔ メンバー ◆ 東京 3 名 (うち

    1 名は Web Developer からのコンバート (私です)) ◆ マニラ 1 名 (Web Developer からのコンバート) ◆ ロンドン 1 名 @masatomo (CTO/Engineering Manager) ➔ 役割 ◆ Quipper のインフラに関わることは基本的に全て ◆ インフラ・クラウド周りのコスト管理、セキュリティ等
  11. Quipper SRE チームの紹介 ➔ ツール ◆ 基本的にあらゆるリソースが GitHub 上でコード化されている ◆

    Pull Request でのレビュー、マージによるデプロイがかなり徹底されてい る ◆ Ansible/Ansible Tower/Terraform/CircleCI/Codenize.tools
  12. 03 Kubernetes への移行

  13. Quipper における Kubernetes 移行の位置づけ ➔ CTO の @masatomo がトップダウンで始めたプロジェクト ◆

    開発者への共有を GitHub Issues やオフライン・オフラインのセッションを 行いフィードバックを集めながら ◆ 現在はプラットフォームとしては CTO を含む SRE が中心となって進めて いる ➔ とりあえず既存のアプリケーションを Deis から Kubernetes にそのまま移行 ◆ Deis: OSS の Heroku クローン的なやつ
  14. Quipper における Kubernetes 移行の位置づけ ➔ Microservices 基盤としての移行ではあるが、Microservices 化はこれから ➔ Kubernetes

    への移行が完了してからが本番! ◆ Microservices 化 ◆ それに伴う様々な権限の開発者への移譲 ◆ リソースや運用の最適化 ◆ 様々な技術的チャレンジ
  15. Quipper とスタディサプリのインフラの変遷 ➔ Quipper ◆ 2012(?)年~: Heroku ◆ 2018年2月~: Deis

    Workflow (Deis v2 にあたる) ◆ 2018年8月~: Kubernetes (本番も含めて移行済み、絶賛運用中) ➔ スタディサプリ ◆ 2016年2月~: Deis v1 ◆ 2018年11月(?)~: Kubernetes (ステージングを移行中、本番も今月中)
  16. Deis から Kubernetes へ移行する/した理由 ➔ Deis が既にメンテ終了!!! (2018年3月) ◆ Quipper

    の Heroku -> Deis Workflow の移行計画は 2017 年 3 月から進 んでいた ◆ 同じく 2017 年時点で Microservices 基盤としての Kubernetes の検証も CTO による R&D プロジェクトとして平行して進んでいた ◆ 結果的に Deis Workflow EOL 直前というタイミングでの Deis Workflow 環 境のリリースになってしまった... ◆ Deis v1 (非 Kubernetes) からいきなり移行するのに比べれば、段階的移行 としての意味は十分あったと言える
  17. Deis から Kubernetes へ移行する/した理由 ➔ Deis Workflow を使い続けるメリット自体薄いという判断 ◆ Hephy

    という fork による後続プロジェクトも存在 ◆ Deis Workflow は事実上 Kubernetes の超薄いラッパー ➔ Microservices をやる上では機能的に足りない ◆ リソース等含めた細かいコントロール・コード化 ◆ アプリケーション単体ではなく集合としての管理
  18. 移行の流れ ➔ 基本的にはガッツと根性!そして粛々やり続けるだけ ➔ Dockerfile を書く ◆ 元が Heroku Buildpack

    なので変わったイメージはそんなにない ◆ Twelve-Factor App なのでアーキテクチャ的に変なやつも基本ない ➔ 環境変数を ConfigMap に切り出し ➔ 先にテスト用のドメインを別途 Reverse Proxy に追加して確認する ➔ 前段にある Reverse Proxy で Deis から Kubernetes にひとつずつスイッチ
  19. Monorepo への移行 ➔ Quipper における現役のサービスのほぼ全てを含む巨大な単一リポジトリ ➔ Web Developer の @mtsmfm

    の意見を元に CTO が実現 ➔ 元は個別リポジトリだったものを git subtree add でインポートしていった ◆ 便宜上元の個別のリポジトリを classic repos と呼んでいる
  20. Monorepo への移行 ➔ 現状は Quipper は Monorepo で完結、移行が完了していないスタディサプリは classic repos

    で開発中 ➔ Classic repos で行った変更は日次で monorepo に同期 ◆ git subtree pull を全サービスに対して実行 ◆ Jenkins Job から Pull Request が作られ、マージすると同期が完了 ➔ Monorepo -> classic repos への同期はなんかうまくいかないのでできていない ➔ どうせ移行が完了したら monorepo に一本化するので放置
  21. 04 Kubernetes の運用

  22. 方針 ➔ できる限り全てを GitHub リポジトリで管理 ◆ Pull Request ベースのレビュー ◆

    マージによるデプロイ (CircleCI) ➔ 大きなツールやミドルウェアの導入は本当に必要になるまで控える ◆ manifest は基本 YAML + kustomize • Datadog Agent のようなカスタマイズがそんなにないものは Helm ◆ 負債化を避けるため (バランスは難しい)
  23. 方針 ➔ 移行をやりきるまでは移行に集中! ◆ 現状は割とコスト度外視でじゃぶじゃぶ Node を投入している状態...

  24. リポジトリ ➔ quipper/kubernetes-clusters ◆ kube-aws で生成したクラスタ定義ファイル (CloudFormation の Stack Template

    等も含む) ◆ Quipper 用、スタディサプリ用、それぞれのステージング・本番、それらの複 数世代 ◆ Deis 用のものも現状含まれている (もうすぐ消せる) ◆ 基本的に SRE のみでメンテナンス (Pull Request は誰でもウェルカム)
  25. リポジトリ ➔ quipper/kubernetes-clusters ◆ Jaeger や Datadog Agent のような各クラスタで共通となるコンポーネントの manifest

    • 素の YAML, Helm, kustomize, envsubst ◆ それらを CD するためのデプロイスクリプト (Bash) ◆ Pull Request ベースでクラスタの構築や manifest の apply が行える
  26. リポジトリ ➔ quipper/monorepo ◆ 前述の「Quipper における現役のサービスのほぼ全てを含む巨大な単一リ ポジトリ」 ◆ 基盤としては SRE

    が中心に構築しているが、中での開発は全ての開発者で 行っていく • Dockerfile/Kubernetes manifest 等は GitHub の CODEOWNERS に より SRE のレビューを必須とする
  27. リポジトリ ➔ quipper/monorepo ◆ Dockerfile ◆ 各サービスの Kubernetes manifest 及び

    kustomize overlays ◆ それらを Pull Request ベースで CI/CD するためのデプロイスクリプト (Bash)
  28. リポジトリ ➔ その他にも Ansible/Terraform/Codenize.tools 等のためのリポジトリがそれぞ れ存在

  29. クラスタ内のアプリケーションの配置 ➔ 本番クラスタ ◆ 基本全サービスが単一の production Namespace 内に存在 ◆ production

    内には service-router と呼ばれるコンポーネントも存在 • 中身はただの Nginx • 各サービスのアプリレイヤに近い部分の Reverse Proxy 的役割 • これまで SRE がメンテしてきた Reverse Proxy (Kubernetes 外) の一 部を切り出して Web Developer に移譲していくため
  30. None
  31. クラスタ内のアプリケーションの配置 ➔ ステージングクラスタ ◆ Develop, release, pr-*** といった複数の Namespace 内に、全サービスが

    それぞれ存在 • これらを便宜上 Service Environment と呼ぶ (Quipper 独自の用語) • develop: devlop ブランチをデプロイする環境 • release: release` ブランチをデプロイするリリーステスト環境 • pr-***: Pull Request を作るたびに作られるステージング環境
  32. クラスタ内のアプリケーションの配置 ➔ ステージングクラスタ ◆ branch-router というコンポーネントが branch-router Namespace に ◆

    URL を元に適切な Service Environment の Namespace 内の service-router に橋渡し ◆ これも中身はただの Nginx • service-router から先は本番クラスタとほぼ変わらない ◆ Jaeger や Datadog Agent 等のコンポーネントについても本番クラスタと同 様
  33. None
  34. クラスタのアップグレード ➔ 実は現状ほぼできていない (!!) ➔ ようやくアップグレードのための仕組み・運用方針が今週 (!!) 出来上がったとこ ろ ◆

    クラスタ毎に kube-aws のバージョンを変えて CD する仕組み ◆ クラスタに世代の概念を導入し、複数世代を並行して構築・デプロイ
  35. クラスタのアップグレード ➔ クラスタの世代 ◆ クラスタ名の末尾に 01, 02 といった連番を付加 ◆ クラスタ名の例:

    quipper-staging ◆ 世代番号を含む完全クラスタ名の例: quipper-staging-01 ➔ サービスごとに前段の Reverse Proxy から切り替えたりする予定
  36. 現状の課題 ➔ クラスタの継続的アップグレード ➔ Audit ありで Rails Console を解放するための仕組み (heroku

    run 的な) ➔ CI/CD パイプラインの改善 ◆ デプロイスクリプト壊れやすい問題 ◆ Spinnaker? ◆ 秘密情報の管理の改善
  37. 現状の課題 ➔ リソースの最適化 (特にステージング) ◆ オートスケーリング ◆ ステージングデプロイ時、変更のないサービスは develop Namespace

    に Forward ➔ Service Mesh ◆ Observability の向上、認証・認可、Canary Release、Circuit Breaker、 Fault Injection などなど...
  38. @mumoshu (Yusuke Kuoka) さんが Technical Advisor に! ➔ kube-aws をはじめとした、Kubernetes

    エコシステムの数多くのOSSに貢献 ➔ 世界に 5 人、日本に 1 人しかいない AWS Container Heroes の 1 人 ➔ Kubernetes に関するあらゆることの相談、議論、レビュー ➔ Quipper では珍しい副業という関わり方でバリューを 出してもらっている
  39. @mumoshu (Yusuke Kuoka) さんが Technical Advisor に! ➔ とはいえまだまだ深いところを議論していきたい!という話をご本人ともしている ◆

    まずは移行を終わらせて時間と余裕を確保しなくては...
  40. 05 Microservices 化への道のり

  41. 組織構成 ➔ Service Unit ◆ 主にビジネスごとに分割されたチーム (B2C, B2B2C, 拠点ごとのビジネス) ◆

    Service Owner (= mini CEO), Product Manager, Developer, Designer ◆ Service Unit ごとに裁量を持つ ➔ Technical Project ◆ Data Restructure (データ処理基盤)
  42. 組織構成 ➔ 現状は結局それぞれのチームが共通のコードベースをさわっている ◆ 分断されたモノリス

  43. 分断されたモノリス ➔ Quipper VPoE の @kyanny が Rails Developers Meetup

    2018 において提唱し た概念 ◆ Quipperにおける「関心の分離」の歴史 https://docs.google.com/presentation/d/1ZNDGuDQGbq2TliUukExUmUi cKUJXjWejBD2zd_E8SFU/edit#slide=id.g357c6cbf64_0_63
  44. 分断されたモノリス ➔ 用途毎に (マイクロではない) サービスに分割されてはいるが... ◆ 学習者用サービス、先生用サービス、コンテンツ制作者用サービス、カスタ マーサポート用サービス... ➔ データベースは基本的に単一の巨大な

    MongoDB にそれぞれのサービスが依存 している ◆ データベースを抽象化するモデル層も同様 (private な gem になっている) ➔ 分割が適切でないため、技術的負債および組織的課題となっている
  45. Microservices 化の状況 ➔ Kubernetes 移行と同時に実験的にいくつかのサービスの切り出しを行った ◆ grpc-ruby による Microservices と、それを集約する

    API Frontend (Rails) ◆ 一部の API を新旧両方のレスポンスを比較しつつ移行 ◆ GitHub の Scientist を用いて結果を比較、データベースに残してダッシュ ボードで見える化
  46. None
  47. None
  48. Microservices 化の状況 ➔ Kubernetes 移行と並行して進む Technical Project ◆ Data Restructure

    • サービスと分析の双方に信頼性の高い学習データを用意するための処 理基盤 • Elixir/OTP/Amazon Kinesis/Amazon Aurora ◆ Kubernetes 移行として進む新規事業プロジェクト • 前述のマイクロサービスを GraphQL で集約して API として利用
  49. まだまだ採用中 ➔ Kubernetes や、AWS をはじめとしたパブリッククラウドに強い SRE・インフラエン ジニア ➔ Microservices やアーキテクチャのスペシャリスト

    ➔ その基盤上で最高の教育サービスを作っていきたい開発者 (Web・モバイル) ➔ Twitter で @yuya_takeyama まで DM くれれば話をしたり適切な人に繋いだりし ます
  50. None