$30 off During Our Annual Pro Sale. View Details »

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

Yuya Takeyama
November 08, 2018

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

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

Yuya Takeyama

November 08, 2018
Tweet

More Decks by Yuya Takeyama

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

  3. 01
    02
    03
    04
    05
    Agenda | 自己紹介
    Quipper の紹介
    Kubernetes への移行
    Kubernetes の運用
    Microservices 化への道のり

    View Slide

  4. 01 自己紹介

    View Slide

  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 としてはまだまだ修行中

    View Slide

  6. @yuya-takeyama
    ➔ 好きな言語は Ruby, Go, TypeScript
    ◆ Elixir を勉強中, Rust は挫折気味

    View Slide

  7. 02 Quipper の紹介

    View Slide

  8. Quipper のプロダクト
    ➔ Quipper
    ◆ フィリピン、インドネシア、メキシコ、日本で展開する教育サービス
    ◆ 先生は宿題を出せて、生徒が問題を解くとその進捗が管理できる
    ➔ スタディサプリ
    ◆ 基本的に機能は Quipper と同じだが、日本ではスタディサプリというブラ
    ンドでやっている
    ◆ かつての受験サプリ。2016 年にリブランディング
    ◆ 日本では「神授業」の CM でおなじみ
    ◆ 漫画「ドラゴン桜2」にも登場

    View Slide

  9. Quipper とスタディサプリ
    ➔ ソースコード的にはほぼ同一
    ◆ 環境変数等のフラグでスタイルや機能の出しわけが行われている
    ◆ AWS のアカウント自体別で、別々のリージョンにデプロイ

    View Slide

  10. Quipper SRE チームの紹介
    ➔ メンバー
    ◆ 東京 3 名 (うち 1 名は Web Developer からのコンバート (私です))
    ◆ マニラ 1 名 (Web Developer からのコンバート)
    ◆ ロンドン 1 名 @masatomo (CTO/Engineering Manager)
    ➔ 役割
    ◆ Quipper のインフラに関わることは基本的に全て
    ◆ インフラ・クラウド周りのコスト管理、セキュリティ等

    View Slide

  11. Quipper SRE チームの紹介
    ➔ ツール
    ◆ 基本的にあらゆるリソースが GitHub 上でコード化されている
    ◆ Pull Request でのレビュー、マージによるデプロイがかなり徹底されてい

    ◆ Ansible/Ansible Tower/Terraform/CircleCI/Codenize.tools

    View Slide

  12. 03 Kubernetes への移行

    View Slide

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

    View Slide

  14. Quipper における Kubernetes 移行の位置づけ
    ➔ Microservices 基盤としての移行ではあるが、Microservices 化はこれから
    ➔ Kubernetes への移行が完了してからが本番!
    ◆ Microservices 化
    ◆ それに伴う様々な権限の開発者への移譲
    ◆ リソースや運用の最適化
    ◆ 様々な技術的チャレンジ

    View Slide

  15. Quipper とスタディサプリのインフラの変遷
    ➔ Quipper
    ◆ 2012(?)年~: Heroku
    ◆ 2018年2月~: Deis Workflow (Deis v2 にあたる)
    ◆ 2018年8月~: Kubernetes (本番も含めて移行済み、絶賛運用中)
    ➔ スタディサプリ
    ◆ 2016年2月~: Deis v1
    ◆ 2018年11月(?)~: Kubernetes (ステージングを移行中、本番も今月中)

    View Slide

  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) からいきなり移行するのに比べれば、段階的移行
    としての意味は十分あったと言える

    View Slide

  17. Deis から Kubernetes へ移行する/した理由
    ➔ Deis Workflow を使い続けるメリット自体薄いという判断
    ◆ Hephy という fork による後続プロジェクトも存在
    ◆ Deis Workflow は事実上 Kubernetes の超薄いラッパー
    ➔ Microservices をやる上では機能的に足りない
    ◆ リソース等含めた細かいコントロール・コード化
    ◆ アプリケーション単体ではなく集合としての管理

    View Slide

  18. 移行の流れ
    ➔ 基本的にはガッツと根性!そして粛々やり続けるだけ
    ➔ Dockerfile を書く
    ◆ 元が Heroku Buildpack なので変わったイメージはそんなにない
    ◆ Twelve-Factor App なのでアーキテクチャ的に変なやつも基本ない
    ➔ 環境変数を ConfigMap に切り出し
    ➔ 先にテスト用のドメインを別途 Reverse Proxy に追加して確認する
    ➔ 前段にある Reverse Proxy で Deis から Kubernetes にひとつずつスイッチ

    View Slide

  19. Monorepo への移行
    ➔ Quipper における現役のサービスのほぼ全てを含む巨大な単一リポジトリ
    ➔ Web Developer の @mtsmfm の意見を元に CTO が実現
    ➔ 元は個別リポジトリだったものを git subtree add でインポートしていった
    ◆ 便宜上元の個別のリポジトリを classic repos と呼んでいる

    View Slide

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

    View Slide

  21. 04 Kubernetes の運用

    View Slide

  22. 方針
    ➔ できる限り全てを GitHub リポジトリで管理
    ◆ Pull Request ベースのレビュー
    ◆ マージによるデプロイ (CircleCI)
    ➔ 大きなツールやミドルウェアの導入は本当に必要になるまで控える
    ◆ manifest は基本 YAML + kustomize
    ● Datadog Agent のようなカスタマイズがそんなにないものは Helm
    ◆ 負債化を避けるため (バランスは難しい)

    View Slide

  23. 方針
    ➔ 移行をやりきるまでは移行に集中!
    ◆ 現状は割とコスト度外視でじゃぶじゃぶ Node を投入している状態...

    View Slide

  24. リポジトリ
    ➔ quipper/kubernetes-clusters
    ◆ kube-aws で生成したクラスタ定義ファイル (CloudFormation の Stack
    Template 等も含む)
    ◆ Quipper 用、スタディサプリ用、それぞれのステージング・本番、それらの複
    数世代
    ◆ Deis 用のものも現状含まれている (もうすぐ消せる)
    ◆ 基本的に SRE のみでメンテナンス (Pull Request は誰でもウェルカム)

    View Slide

  25. リポジトリ
    ➔ quipper/kubernetes-clusters
    ◆ Jaeger や Datadog Agent のような各クラスタで共通となるコンポーネントの
    manifest
    ● 素の YAML, Helm, kustomize, envsubst
    ◆ それらを CD するためのデプロイスクリプト (Bash)
    ◆ Pull Request ベースでクラスタの構築や manifest の apply が行える

    View Slide

  26. リポジトリ
    ➔ quipper/monorepo
    ◆ 前述の「Quipper における現役のサービスのほぼ全てを含む巨大な単一リ
    ポジトリ」
    ◆ 基盤としては SRE が中心に構築しているが、中での開発は全ての開発者で
    行っていく
    ● Dockerfile/Kubernetes manifest 等は GitHub の CODEOWNERS に
    より SRE のレビューを必須とする

    View Slide

  27. リポジトリ
    ➔ quipper/monorepo
    ◆ Dockerfile
    ◆ 各サービスの Kubernetes manifest 及び kustomize overlays
    ◆ それらを Pull Request ベースで CI/CD するためのデプロイスクリプト
    (Bash)

    View Slide

  28. リポジトリ
    ➔ その他にも Ansible/Terraform/Codenize.tools 等のためのリポジトリがそれぞ
    れ存在

    View Slide

  29. クラスタ内のアプリケーションの配置
    ➔ 本番クラスタ
    ◆ 基本全サービスが単一の production Namespace 内に存在
    ◆ production 内には service-router と呼ばれるコンポーネントも存在
    ● 中身はただの Nginx
    ● 各サービスのアプリレイヤに近い部分の Reverse Proxy 的役割
    ● これまで SRE がメンテしてきた Reverse Proxy (Kubernetes 外) の一
    部を切り出して Web Developer に移譲していくため

    View Slide

  30. View Slide

  31. クラスタ内のアプリケーションの配置
    ➔ ステージングクラスタ
    ◆ Develop, release, pr-*** といった複数の Namespace 内に、全サービスが
    それぞれ存在
    ● これらを便宜上 Service Environment と呼ぶ (Quipper 独自の用語)
    ● develop: devlop ブランチをデプロイする環境
    ● release: release` ブランチをデプロイするリリーステスト環境
    ● pr-***: Pull Request を作るたびに作られるステージング環境

    View Slide

  32. クラスタ内のアプリケーションの配置
    ➔ ステージングクラスタ
    ◆ branch-router というコンポーネントが branch-router Namespace に
    ◆ URL を元に適切な Service Environment の Namespace 内の
    service-router に橋渡し
    ◆ これも中身はただの Nginx
    ● service-router から先は本番クラスタとほぼ変わらない
    ◆ Jaeger や Datadog Agent 等のコンポーネントについても本番クラスタと同

    View Slide

  33. View Slide

  34. クラスタのアップグレード
    ➔ 実は現状ほぼできていない (!!)
    ➔ ようやくアップグレードのための仕組み・運用方針が今週 (!!) 出来上がったとこ

    ◆ クラスタ毎に kube-aws のバージョンを変えて CD する仕組み
    ◆ クラスタに世代の概念を導入し、複数世代を並行して構築・デプロイ

    View Slide

  35. クラスタのアップグレード
    ➔ クラスタの世代
    ◆ クラスタ名の末尾に 01, 02 といった連番を付加
    ◆ クラスタ名の例: quipper-staging
    ◆ 世代番号を含む完全クラスタ名の例: quipper-staging-01
    ➔ サービスごとに前段の Reverse Proxy から切り替えたりする予定

    View Slide

  36. 現状の課題
    ➔ クラスタの継続的アップグレード
    ➔ Audit ありで Rails Console を解放するための仕組み (heroku run 的な)
    ➔ CI/CD パイプラインの改善
    ◆ デプロイスクリプト壊れやすい問題
    ◆ Spinnaker?
    ◆ 秘密情報の管理の改善

    View Slide

  37. 現状の課題
    ➔ リソースの最適化 (特にステージング)
    ◆ オートスケーリング
    ◆ ステージングデプロイ時、変更のないサービスは develop Namespace に
    Forward
    ➔ Service Mesh
    ◆ Observability の向上、認証・認可、Canary Release、Circuit Breaker、
    Fault Injection などなど...

    View Slide

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

    View Slide

  39. @mumoshu (Yusuke Kuoka) さんが Technical Advisor に!
    ➔ とはいえまだまだ深いところを議論していきたい!という話をご本人ともしている
    ◆ まずは移行を終わらせて時間と余裕を確保しなくては...

    View Slide

  40. 05 Microservices 化への道のり

    View Slide

  41. 組織構成
    ➔ Service Unit
    ◆ 主にビジネスごとに分割されたチーム (B2C, B2B2C, 拠点ごとのビジネス)
    ◆ Service Owner (= mini CEO), Product Manager, Developer, Designer
    ◆ Service Unit ごとに裁量を持つ
    ➔ Technical Project
    ◆ Data Restructure (データ処理基盤)

    View Slide

  42. 組織構成
    ➔ 現状は結局それぞれのチームが共通のコードベースをさわっている
    ◆ 分断されたモノリス

    View Slide

  43. 分断されたモノリス
    ➔ Quipper VPoE の @kyanny が Rails Developers Meetup 2018 において提唱し
    た概念
    ◆ Quipperにおける「関心の分離」の歴史
    https://docs.google.com/presentation/d/1ZNDGuDQGbq2TliUukExUmUi
    cKUJXjWejBD2zd_E8SFU/edit#slide=id.g357c6cbf64_0_63

    View Slide

  44. 分断されたモノリス
    ➔ 用途毎に (マイクロではない) サービスに分割されてはいるが...
    ◆ 学習者用サービス、先生用サービス、コンテンツ制作者用サービス、カスタ
    マーサポート用サービス...
    ➔ データベースは基本的に単一の巨大な MongoDB にそれぞれのサービスが依存
    している
    ◆ データベースを抽象化するモデル層も同様 (private な gem になっている)
    ➔ 分割が適切でないため、技術的負債および組織的課題となっている

    View Slide

  45. Microservices 化の状況
    ➔ Kubernetes 移行と同時に実験的にいくつかのサービスの切り出しを行った
    ◆ grpc-ruby による Microservices と、それを集約する API Frontend (Rails)
    ◆ 一部の API を新旧両方のレスポンスを比較しつつ移行
    ◆ GitHub の Scientist を用いて結果を比較、データベースに残してダッシュ
    ボードで見える化

    View Slide

  46. View Slide

  47. View Slide

  48. Microservices 化の状況
    ➔ Kubernetes 移行と並行して進む Technical Project
    ◆ Data Restructure
    ● サービスと分析の双方に信頼性の高い学習データを用意するための処
    理基盤
    ● Elixir/OTP/Amazon Kinesis/Amazon Aurora
    ◆ Kubernetes 移行として進む新規事業プロジェクト
    ● 前述のマイクロサービスを GraphQL で集約して API として利用

    View Slide

  49. まだまだ採用中
    ➔ Kubernetes や、AWS をはじめとしたパブリッククラウドに強い SRE・インフラエン
    ジニア
    ➔ Microservices やアーキテクチャのスペシャリスト
    ➔ その基盤上で最高の教育サービスを作っていきたい開発者 (Web・モバイル)
    ➔ Twitter で @yuya_takeyama まで DM くれれば話をしたり適切な人に繋いだりし
    ます

    View Slide

  50. View Slide