概要
2014 年の 12 月アムステルダムで行われた DockerCon のキーノートのひとつ "State of the Art in Microservices" についてのまとめとメモ。
- 開発スピードをあげるための組織再編
- コンテナ化されたマイクロサービスアーキテクチャ
- Docker が普及したあとの開発スタイル
といった内容が盛り込まれている。元のスライドとビデオはこちら
内容は Adrian が話していることに加え自分が調べたり学んだ内容を補足やメモとして追加しているので間違った理解をしているなと思ったらぜひ編集リクエストください :)
キーノートをまとめることについては Adrian 本人に許可をもらえました!
Adrian Cockcroft
- @adrianco
- クラウドアーキテクトとして 6 年間 Netflix に勤めていた
現在は Battery Ventures という工業の会社のテクノロジーフェロー- 現在は Battery Ventures を辞めて AWS の VP of Cloud Architecture
クラウドの採用時期
クラウドによる変革の波がエンタープライズ領域に来ていて、これからエンタープライズ領域がアツい
開発スピードをあげるにはどうすれば良いのか
プロダクト開発プロセスはこのフィードバックサイクルを回していくことである。それがどうして難しいのか?
図のようにほとんどの組織が専門性によって分かれているからである。専門性によって組織を分けるとチーム同士でミーティングや調整を何度もする必要が出てくる。これは生産的ではない。(また専門性によってチームを分けると、次第に仕事の「義務」の要素が強くなり「情熱」を持って取り組みづらくなるという例もある。)
そこで職務横断型の組織を作ることも出来るが、この形にも問題がある。バックエンド(インフラ)側が共通化されていないのは非効率過ぎるのだ。だから本当にやりたい分け方はこうだ。
- インフラエンジニアはプロダクトチームに対して プラットフォームを提供する
- インフラエンジニアやオペレーション作業がプラットフォームの API の後ろに存在する 形になる
- オペレーションは、ミーティングやチケットでの依頼して行うものではなく API コールによって行われる
- マイクロサービスチームは、それぞれ 1 機能=マイクロサービスを担当し、それ関わること 全てを担当する(カスタマーサポート・内部ツール開発・DB スキーマの管理・テストなど)
この組織の再編が DevOps である。そして再編は簡単な物ではなく 1 年ほどを要するはずだ。(Netflix は 1 年半かかったそうだ)
モノリシックアーキテクチャとマイクロサービスアーキテクチャ
- 全員でモノリシックなアプリケーションを開発する
- 全員が同じ言語で開発する
- 全員が 1 本のデリバリーパイプラインからリリースする
この組織モデルはスタートアップなどの小規模な組織では有効である。(デプロイもスケールもオペレーションもシンプルになって良い)
しかし 開発者が 50-100 人ほどになると、ある開発者が 1 つのバグが他の開発者の機能の開発やデプロイを止めてしまう可能性が高くなりスピード感が落ちる。(これが Netflix が マイクロサービスアーキテクチャに変えていった一番の理由で、その前はデプロイに 2 週間かかるようになっていたそうだ)
もう1つは可用性の問題。1 つ問題があるとサービス全体が停止してしまう。
マイクロサービスアーキテクチャでは
- サービスそれぞれにプロダクトチームがある
- サービスそれぞれで開発言語が違う
- サービスはそれぞれ独立してパイプラインを持っているために独立してリリースができる
- あるサービスに障害があってもサービス全体は停止しないようにできる
開発言語や利用する技術が違う各チームが共通のインフラにデプロイするにはどうすれば良いか?
Docker を使えば共通の方法でのデプロイが可能になる。また DockerHub からイメージをダウンロードすることによって、全てを自分たちでビルドする必要はなくなる。よくメンテナンスされたものを取って来て必要な設定を加えて使う、といったことが可能になる。
Docker(とGolang)による開発スピードの向上
例えば Golang で Web API を開発し Docker コンテナとしてデプロイするとする。このとき
- 秒単位でアプリケーションのビルドが完了し
- 秒単位でコンテナイメージのビルドが完了し
- 秒単位でプラットフォームへのデプロイが完了する
"速い" というのは中毒性がある
ここまでで説明されたマイクロサービスアーキテクチャにより、
- 変更回数(チャレンジ)の増加
- コストとリスクの低減
という結果が得られる。
コンテナ化されたマイクロサービスによる継続的デリバリー
コンテナ化されたマイクロサービスをどう実現するか
Adrian のマイクロサービスの定義
訳すなら "許容範囲内のコンテキストによって緩く結びついたサービス志向アーキテクチャ" という感じだろうか。
- 緩く結びついた: 各サービスをいつでも独立してデプロイできないのであれば、緩く結びついているとはいえない
- 許容範囲内のコンテキスト: サービスを開発するのに関して知らなければいけないことがあまりにも多い場合は許容範囲内のコンテキストとはいえない
マイクロサービスに付随する懸念として注意すべきポイント
- 組織: コンウェイの法則に従いマイクロサービスを担当する小さなチームを分散的に置く組織にする。そして各チームがオーナーシップを持っている必要がある。
- 大きくて複雑な共通のデータベーススキーマを持つ: 数多くのサービスが共通のデータベーススキーマを共有すると疎結合ではなくなる。マイクロサービスアーキテクチャでは各マイクロサービスが独立したデータベーススキーマと接続先を持つ。そのため全体として正規化はしない。モジュール性や耐障害性を持つ。
- 集中型のメッセージキュー: 集中型のメッセージキューを持つとスケールの問題を抱える。マイクロサービスアーキテクチャではそれぞれのサービスが互いにコールし合う。(P2P)
- 柔軟性を持たないバージョニング: 各マイクロサービスは複数のバージョンを安定して提供できるようにする(後方互換性を保ちつつ改善を進める)
開発スピードの変遷
- データセンターを持っていた時代には数ヶ月かけてデプロイし、サーバは数年動いていた
- 仮装化とクラウドが出てくると数分でデプロイし、アジャイルなどの影響も有りサーバは数週間ほど動いているライフサイクルになった
- Docker/コンテナ技術によって数分でデプロイが完了し、コンテナ(サービス)は数分から数時間のライフサイクルになる
- AWS lambda によってデプロイは数ミリ秒になり、サービスは数秒のライフサイクルになる
コンテナ化されたマイクロサービスアーキテクチャを実現するには何にトライすればいいのか
コンテナ化されたマイクロサービスアーキテクチャは以下のコンポーネントを持つ
- Tooling
- Configuration
- Discovery
- Routing
- Observablity
- Ephemeral Datastore
- Orchestration and Deployment Infrastructure
- Development Languages and Container
Netflix の例
各ツールについては Netflix OSS を参照
Netflix のサーバ構成図
デススターと呼んでる(スターウォーズのあれ)
(こんな風にマイクロサービスアーキテクチャを可視化すると独特の形になることから "State of the Art in Microservices" というタイトルとしているのだと思う)
Twitter の例
Gilt の例
Hail の例
スケールしていくサービスは以下の特徴を持つ:
- 新しいマイクロサービスは頻繁に追加されるわけではない
- 各マイクロサービスの新しいバージョンを自動化された方法で頻繁に更新される
- 会社によって多様なマイクロサービスを扱うので汎用的なオーケストレーションよりも明確な目的をもったオーケストレーションが必要になる
- 数多くのマイクロサービス郡がアーキテクチャを構成する
- 各デプロイはそれぞれのサービスに合わせてかなりカスタマイズされる
今後の予測
- 標準的でポータブルなマイクロサービスベースのアプリケーションが作られるようになる
- オーケストレーションは自動化され標準化されていく(多様なオーケストレーションの中からベストプラクティスなオーケストレーションパターンが決まってきて皆がそれに乗り収束していくのだと思う)
- アプリケーション開発はマインクラフトみたいに、DockerHub に置いてあるイメージをブロックみたいに組み合わせてマイクロサービスを形作るようになる
- Docker Hub が有料アプリストアになる、可能性がある(Docker イメージを買うレベルに至るには販売元への信頼が必要になる。電子署名機能はここら辺で重要になってくる)
- データストアは、一時期に存在しオーケストレーション可能なもの、または Aurora のような DBaaS (=Database as a Server)
- Golang よい
- エンタープライズ領域にクラウドやリーンスタートアップの変革が来るよ
- マイクロサービスよい
メモと感想
マイクロサービスのデメリット
- オペレーションが めちゃくちゃ 大変
- 高度な DevOps スキルが必要、大変
- インターフェースの変更ができない大変
- 同じ物を開発してしまう大変(重複が起こる)
- 分散システムが複雑で大変
- 非同期システムを扱うの大変
- テストがしづらい大変
感想
この図は好きな領域であるオーケストレーション/スケジューリング・コンテナ化・ChatOps やインフラ側のエンジニアの担当範囲であるモニタリングやコンフィギュレーション、データの管理等自分が関わる技術領域が整理された図。マイクロサービスアーキテクチャではなくてもコンテナ化されたサービスを運用するために必要なコンポーネントでもあると思う。
DevOps の思想に共感し学んできたこともあり、その文脈も合わせて整理できたのも良かった。
また、
インフラエンジニアやオペレーション作業がプラットフォームの API の後ろに存在する 形になる
これに非常に賛同していて、 必要なツールや技術が揃い始めているので AWS や Heroku 等の IaaS / PaaS サービスのエンジニアに限らず各社にいるインフラ寄りのエンジニアはプラットフォームを開発し API を開発チームに提供するような機会が増えてくるんじゃないかと思っている。(使う際にミーティングとか申請が必要なプラットフォームとかじゃなくて)
新しく色々学べたし、非常に素晴らしい資料と発表でした!
データ層のコンテナ化をするには?
データ層のコンテナも他の層(フロントとか)のコンテナと同じように短命で捨てることが出来る。それにはデータを Cassandra のような分散データベースに格納することで実現する。データを複数のコンテナでレプリケーションすることで一台一台は気軽に捨てることが出来るというわけ。ただ、Cassandra やそれ相当の DB を運用するよりは Aurora や DynamoDB のような DBaaS を使う方が楽である。
REF
- Dockercon State of the Art in Microservices - slideshare
- State of the Art in Microservices by Adrian Cockcroft (Battery Ventures) - YouTube
- Migrating to Microservices - slideshare
- Goto Berlin - Migrating to Microservices (Fast Delivery) - slideshare
- Speeding Up Innovation - slideshare
- Microservices
- MicroservicePrerequisites
- "Microservices"を読んだ
- NetflixにおけるMicroservicesアーキテクチャ
- 急成長GitHubの経営陣が明かす、プログラマーのクリエイティビティを最大限に引き出す方法