この記事はEnvoyの作者であるMatt Kleinさんの以下の記事を
The human scalability of “DevOps”
本人の許可をえて日本語訳したものになります。
Sure!
— Matt Klein (@mattklein123) 2018年9月7日
アメリカにはたくさんの急成長するスタートアップ企業があって、そういう所って、システム的/組織的な所の両面で、破綻させずにどうやってスケーリングしていくんかな〜と日々疑問に思っていて、この記事では主に組織的な所に関して色々と示唆があり、その内容から、やっぱアメリカ凄い(小並)ってのを感じたので、自分の中での腹落ち度合いを深めるためと、より多くの人の目に触れるといいなと思い、翻訳してみました。
以下、翻訳になります。
"DevOps" の人的なスケーラビリティ
最近Twitterに書いたように、"DevOps" の人的スケーラビリティに関して多くの時間を使って考えてきました。(Devopsをクォートで囲っているのは、その単語に様々な定義があるからです。その点に関しては後で補足します。) 考えた結果、DevOpsは小さなエンジニアリング組織でとても機能しますが、深い考えや慎重なマネジメントを入れずに、この手法を実践すると、人間/組織のスケーリングの問題に突き当たるのではないかという結論に至りました。
DevOpsとは?
DevOpsという単語は人によって解釈が異なります。本題に入る前に、私にとってDevOpsが何を意味するかを明確にするのが大事でしょう。
WikipediaではDevOpsを以下のように定義しています
DevOps("devlopment"と"operations"をくっつけた略語)は、software development (Dev)とsoftware operation (Ops) を統合していくこうという目的を持ったソフトウェアエンジニアリングの文化です。DevOpsのムーブメントの大きな特徴は、ソフトウェアの作成、インテグレーション、テスト、リリースとデプロイ、インフラの管理に至るまで、全工程の自動化とモニタリングを強く推奨していることにあります。DevOpsでは短い開発サイクル、頻繁なデプロイメント、より安定したリリースを目指しており、ビジネス要求を素早く実現することを目指しています。
私には、より狭義で少し違った解釈のDevOpsの定義があります
DevOpsはdeveloperが24/7でソフトウェアの運用に責任を持つ手法です。ここには共通のインフラを使った開発、テスト、on-call対応、reliability engineering、 disaster recovery、SLOの定義、モニタリングとアラートの設定、デバッグとパフォーマンス解析、障害時の原因究明、プロビジョニング、デプロイメントが含まれます。
Wikipediaの定義と私の定義の違い(開発における指針 vs 具体的な運用戦略)は重要で、私の個人的な業界での経験によって形作られています。DevOpsの"ムーブメント"の一部は、ゆっくりしか進まない"legacy"なエンタープライズ業界に、モダンで高度に自動化されたインフラと開発手法の利点を紹介することにありました。これは以下のような点を含みます: 疎結合なサービス、API、チーム; continuous integration; masterを使った小さなイテレートでの開発; アジャイルなコミュニケーションとプランニング; cloud nativeでelasticなinfrastructure; などです。
ここ10年くらいの私のキャリアとして、AWS EC2、上場前のTwitter、Lyftといった急成長したインターネット企業で働いてきました。それに加えて、Envoyを作って色んな所で講演を行ったことで、ここ2年くらいでは多数の急成長インターネット企業のアーキテクチャや組織構造について、実際に会って話を聞いて学ぶことがありました。それらの企業は全て、自動化、アジャイルな開発/プランニングを行い、他のDevOpsの"ベストプラクティス"を実践することは、プロダクティビティを向上させるために当然必要であるということをとてもよく理解していました。代わりに、それらのエンジニアリング組織にとっての挑戦は、急成長していくビジネス、人数の拡大、ビジネス面や採用面での競合との戦いのプレッシャーに耐えながら、どのようにシステムの安定性を担保していくかというところにあります。このポストの残りは、私個人の経験に基づいており、すべてのケースに当てはまらないというのは認識しています。特に、最近までクオーターに1回monolithicなアプリケーションをデプロイしていて、最近になってより迅速でアジャイルな開発手法に向かい始めたような動きの伝統的なエンタープライズには当てはまらないでしょう。
インターネットアプリケーションの運用の歴史のおさらい
ここ30年くらいをモダンインターネット時代と名付けると、インターネットアプリケーションの開発と運用は(私の考えでは)3つのフェーズを辿ってきました。
-
最初のフェーズでは、インターネットアプリケーションは"パッケージ"ソフトウェアと同じような方法で作られデプロイされていました。3つの区分けされた役割(開発、QA、運用)を持ったメンバーが、アプリケーションを開発から本番に持っていくまで、大体はとても長い時間をかけて、協働していました。このフェーズの時代は、アプリケーションは専用のデータセンターや自己所有の施設にデプロイされていたため、その環境のネットワーク、ハードウェア、システム運用に詳しい人間が今よりもずっと不可欠でした。
-
2番目のフェーズでは、90年代後半から2000年代前半のAmazonとGoogleが先陣をきる形で、急成長するインターネット企業は最近のモダンなDevOpsの流れに近い手法を取り入れるようになりました(疎結合なサービス、アジャイル開発とデプロイ、自動化など)。これらの会社は自分たちで(超巨大な)データセンターを運用していますが、求められるスケールがとても大きいことから、全サービス共通の課題(ネットワーク、モニタリング、デプロイ、プロビジョニング、ストレージ、キャッシュ、物理インフラ等)に取り組むためのインフラストラクチャーの専門チームを立ち上げることができたのです。しかしながら、AmazonとGoogleでは開発のjob roleを完全に統一することはありませんでした(AmazonではSystems Engineer、GoogleではSite Reliability Engineer という形です)。それぞれ別のスキルや興味が求められると認識しているのです。
-
3番目の、またはcloud nativeと呼ばれるフェーズでは、インターネットのアプリケーションは、主に"3大"パブリッククラウドによって提供される、elasticなアーキテクチャに依存する形で構築されるようになりました。スタートアップは失敗の確率が高いので、プロダクトをマーケットに少しでも早く投入することが常に最重要な目的であり続けたのですが、cloud nativeな時代になり、"箱から出すだけで"利用可能なこのベースとなる技術は、それまでは考えられないようなイテレーションの速さを実現させました。
この時代に始まった会社のもう一つの典型的な特徴としては、非ソフトウェアエンジニアのroleの人を雇わなくなった点があります。誰もが利用可能なインフラがとてもしっかりとしているので (この点については詳細に後で述べます) スタートアップの人件費はエンジニアリングとオペレーションを両方行うことが出来るソフトウェア開発者に使うべきであると考えています。
この第3時代の会社でのオペレーション専門の人を雇わないという流れはとても重要なポイントです。確かにそのような会社では、施設でマシンを管理するためのフルタイムのsystem administratorは不要ですが、そのような仕事をしていた人はそれ以外の20%の部分で、デバッグやパフォーマンスのプロファイリング、オペレーションの勘所のようなスキルを提供する存在でもありました。新しく立ち上がってきた会社は、この重要で容易に代えが見つからないスキルセットを持った人材を欠いた状態で作られているのです。
なぜモダンなインターネット企業ではDevOpsが上手く機能するのか?
Devopsは、私が先に定義(開発と運用の両方をするエンジニア)しましたが、最近のモダンなインタネット界隈のスタートアップではいくつかの理由からとても上手く機能しています。
-
私の経験では、成功するスタートアップの初期のエンジニアは特別培養されたようなエンジニアです。リスクを許容し、物事を学ぶスピードがとても速く、多少の技術的負債を許容しながらも製品を作りあげることに邁進し、大抵の場合は複数のシステムや言語を扱い、オペレーションやsystems adminの経験があるか、又は必要に応じて学ぶことを厭わない存在です。簡単にいうと、典型的なスタートアップのエンジニアは、DevOpsエンジニアという存在にぴったりとあてはまるのです。自分でそう名付けたいかどうかは別ですが(ちなみに私は嫌です😉)。
-
先に述べたように、モダンなpublic cloudはアプリケーションを乗せるのにとても素晴らしいインフラの基礎部分を提供してくれます。昔は必要とされた多くの基本的なオペレーションの作業は自動化され、MVPを出してプロダクトが市場に受け入れらるかどうかだけに集中できるようになったのです。
-
私自身は、開発者がon-callを持ち、自分の書いたコードへの責任を持つようになることで、システムが良くなると強く信じています。誰もアラートを受けるのは好きではありません。このフィードバックのループはより良い製品を作ることにつながり、また、1.で述べたように、初期のスタートアップで働くようなエンジニアはそのようなオペレーションの作業を学んで行いたいという気持ちがとても強いです。加えて、初期スタートアップのプロダクトではreliabilityが問題になることはほとんどないという側面もあります。reliablityはプロダクトがマーケットにフィットし、急成長のフェーズに入った段階で必要となるのです。
モダンなインターネット企業が急成長期に入ると何が起きるか?
ほとんどのスタートアップは失敗します。それが現実です。このため、どんな初期のスタートアップでも、Googleを目指してインフラを作り上げようとするのは完全に時間のムダです。私はいつもmonolithicなアーキテクチャのままでいいし、人的スケーラビリティの問題(コミュニケーション、プランニング、密結合など)が発生し、より疎結合なシステムを目指す必要が出てくるまでは、何の心配もすることはないと話しています。
では、成功して、急成長の時期に入ったモダンな(3段階目の)インターネットのスタートアップでは何が起こるのでしょうか?複数の興味深いことが同時に発生し始めます。
-
人数が急増し始め、コミュニケーションや開発効率に難しい問題が起こるようになります。ここのトピックに関しては"The Mythical Man-Month" (邦題:人月の神話) を一読されることをオススメします。初版が出されてから50年近く経過していますが、この本に書かれている多くのことは現代にも当てはまります。
-
上記の問題によって、開発チームの疎結合化と、コミュニケーションとエンジニアリングの効率性を求めて、ほとんどの場合、monolithicからmicroserviceのアーキテクチャへの移行が始まります。
-
monolithicからmicroserviceなアーキテクチャへの移行は、複数の面からインフラストラクチャーの複雑性を増やすことになります。ネットワーク、observability、デプロイメント、ライブラリの管理、セキュリティ、そして、それまではそんなに難しいことではなかったたくさんのことが解決すべき問題として上がってきます。
-
同時に、急成長ということは、トラフィックが増加し、スケーリングの問題が発生し始めることになり、また、大きな障害、小さなユーザエクスペリエンス問わずに世間の反響が出てしまうことになります。
中核となるインフラチーム
ほぼ普遍的な事実として、初期スタートアップのフェーズから、モダンな急成長企業になるにあたって、似たような組織構成ができる事になります。この構成には、中核となるインフラチームが存在し、チームをまたいでDevOpsの実践をサポートしています (彼らがその名称で呼んでいるとは限りませんが。)
中核となるインフラチームが共通してい存在している理由は、先に述べたように、急成長は、人の面でもベースとなるテクノロジーの部分でも大きな変化をもたらすことになり、現実的な問題として現時点でのcloud native technologyを用いて、ネットワーク、observability、デプロイ、プロビジョニング、キャッシュ、データストレージなどの共通の課題を、個々のチームが個別に使いこなすのはまだ相当に敷居が高いです。"serverless"テクノロジーが浸透すればエンジニアリング全体でビジネスロジックに集中することができると言われていますが、この技術を用いて、信頼性の高い、巨大な規模のリアルタイムなインターネットアプリケーションを堅牢に作るには、我々はまだまだ遠い位置にいるのです。
このようにして、cloud nativeなインフラの基本的な部分だけでは賄うことのできない、より大きなエンジニアリング組織の問題を解決するために、中核となるようなインフラチームが誕生するのです。GoogleのインフラチームはLyftのような会社よりも桁違いに大きなインフラチームを持っていて、これによって、データセンターレベルでの改善が必要な基礎的な問題の解決を行っていて、Lyftはこのようにして作られた利用可能なインフラを利用しています。しかしながら、両方のケースにおいて、中核となるインフラチームが必要となる理由は一致しているのです。application/product 開発者がビジネスロジックに集中できるように、できる限りインフラを抽象的な存在にすることです。
"交換容易性"という誤った考え
最終的に、私たちは"交換容易性"というアイデアにたどり着きます。それはエンジニアの数が増え組織がある程度大きくなった時に、純粋なDevOpsモデルを行っているとぶつかる大きな壁になるものです。交換容易性という考え方は、すべてのエンジニアが共通のスキルセットを持っていて、なんでも出来るという状態を目指すことを言います。明確な採用のゴールとして始まるにせよ(少なくともAmazonはそうしていますし、他の会社もそうだと思います)、エンジニアをチームやロールに当てはめずに"bootcamp"のような採用の中のプロセスを通してそうしていくこともあります。ここ10-15年程度、交換容易性はモダンなエンジニアリングの哲学の中で多くの会社で採用されているコンポーネントとなっています。これはなぜでしょうか?
-
先に述べたように、モダンなcloud nativeなテクノロジーと抽象化によって、とてもリッチな機能を持ったアプリケーションをどんどん洗練されている抽象化されたインフラの上で作れるようになりました。そうなると、データセンタのデザインやオペレーションといったような専門スキルは多くの会社にとって不要なものとなります。
-
ここ15年ほど、業界としてソフトウェアエンジニアリングが全ての領域に対しての根っこにあるという考えにフォーカスしてきました。例えば、Microsoftは従来のQAエンジニアを撤廃し、Software Test Engineerというポジションに置き換えました。その背景には手動のQAは効率的でなく、全てのテストは自動的に行われるべきだという考えがあります。同様に、従来の運用の役割は、Site Reliability Enginnering (または似たような別の名前の) という役割に置き換えられました。手動運用が効率的でなく、スケールするための唯一の方法はソフトウェアによる自動化によるものだという考え方があるからです。はっきりしておきますが、私はこれらのトレンドに賛成です。自動化はスケールしていく時にとても効率的な手段です。
しかしながら、このアイデアは極端に取られ、多くの初期スタートアップが行っているように、ジェネラリストなソフトウェアエンジニアばかりを採用し、その(DevOps)エンジニアがデプロイメントやQA、運用も行えるという考えで進んでいます。
"交換性容易性"とジェネラリストの採用は大体の初期スタートアップでは上手く機能します。しかしながら、一定規模を超えると、全てのエンジニアが交換可能であるという考え方は、次の理由によって不条理なものとなっていきます。
-
ジェネラリスト vs スペシャリスト。アプリケーションとアーキテクチャが複雑になるにつれ、成功にあたってはよりスペシャリストのスキルが必要となってきます。フロントエンド、インフラ、クライアントサイド、運用、テスト、データサイエンス等々いずれの領域においても当てはまります。このことは、ジェネラリストが不要である、またはジェネラリストはスペシャリストになるような学びが出来ないという意味ではなく、大きくなったエンジニアリング組織が上手くいくには、違うタイプのエンジニアが必要となるというだけのことです。
-
全てのエンジニアが、何でもやるというのが好きな訳ではないです。ジェネラリストであることが好きな人もいれば、スペシャリストになりたい人もいます。コードを書くのが好きな人もいれば、デバッグが好きな人もいます。UIが好きな人がいるし、システムが好きな人もいます。成長中のエンジニアリング組織でスペシャリストを育成するような場合においては、従業員の幸せは特定の問題に集中することにあり、他の事では実現できないものなのだということを理解する必要があります。
-
全てのエンジニアが、何でもやるのが得意な訳ではないです。私のキャリアを通じてたくさんのすごい人々に出会いましたが。空ファイルをIDEで開いてスクラッチで凄いシステムを作っちゃうような人もいました。ただ、そのような人はシステムを安定して動かす所や、どうやってデバッグするかという所、どのようにモニタリングするかといったことには興味がなかったりします。反対に、私が参加した面接の中で、デバッグやシステムを安定して動かす所に凄く長けている人たちが、"十分なコーディング能力"を示すことができずに落とされてしまい、腹を立てることも何度もありました。
皮肉なことではありますが、AmazonやFacebookのようなソフトウェアエンジニアの役割の中で"交換容易性"という点に重きをおいた会社でも、(一部重複する所はあるものの)開発と運用ではっきり分かれたスキルセットに価値を置いていて、それぞれに違うキャリアパスを提供しています。
破綻
どのようにして、どれくらいの大きさになった時に純粋なDevOpsは破綻してしまうのでしょうか?何が問題なのでしょう?
-
マイクロサービスへの移行。エンジニア組織が75人くらいの規模になるタイミングで、マイクロサービスの各プロダクトチームが必要とする共通の基盤を構築するための中核的なインフラチームがほぼ確実に存在するようになります。
-
純粋なDevOps。同時に、プロダクトチームはDevOpsを実践するように命じられます。
-
信頼性のコンサルタント。このサイズの組織になると、インフラ構築に引き寄せられるエンジニアは、過去に運用の経験があるエンジニアか、その分野に深い知識を持ったエンジニアと一致します。必然的に、これらのエンジニアがSRE / プロダクションエンジニアのデファクトとなり、組織全体のコンサルタントとなると共に、ビジネスを継続するために必要なインフラを構築を継続して行なっていきます。
-
教育の不足。業界全体として、採用する人材にはインターネットサービスの開発と運用の両方が行えることを期待しています。しかしながら、ほぼ普遍的な事実として、新規採用とそのために必要な継続的な教育の両面で、大きな失敗をしてしまうのです。教育することもなく、どうして運用の知識をエンジニアに期待できるのでしょうか?
-
サポートの破綻。エンジニア組織の採用が伸び続けると、どこかのタイミングで、中核的なインフラチームが、ビジネスの成功に必要なインフラを継続的な構築と運用と、プロダクトチームの運用作業をサポートの両方を行うことができなくなります。中核的なインフラチームにはこれまでの負荷に加えて、組織横断のSREコンサルタントという二重の責任を負わされるのです。全員が教育とドキュメンテーションはとても重要であると理解しているのですが、この2つに優先的に時間が使われることはほとんどありません。
-
燃え尽き症候群。さらに悪いことに、上記のような状況は人的な犠牲を生み出し、組織全体のモラル低下をもたらします。プロダクト側のエンジニアはやりたくもないし、ちゃんと教えられもしないことをやるように命令されてるような気持ちになります。インフラエンジニアは、教育とドキュメンテーションが大事と分かりながら時間が割けない状況でのサポートの提供と、会社全体が必要とする信頼性の高いシステムの維持の重みに耐えきれずに、燃え尽き始めてしまうのです。
一定規模のエンジニアリング組織では、バスからタイヤが落ちそうになるように、中核的なインフラチームのサポートの元に成り立つ純粋なDevOpsモデルは人的スケーリングの問題が起き始めます。そのサイズというのは、パブリッククラウドの熟成度にもよる所はあるでしょうが、現時点では100-300人程度が一つの目安になると思います。
"旧来のやり方"とDevOpsの落とし所はあるのか?
設立後10年程度の企業では、site reliabilityやproduction engineeringというモデルは共通のものとなりつつあります。実践の方法は企業によって異なりますが、そのアイデアは、reliabilityに集中するエンジニアを雇用し、プロダクトマネージャの配下に置かないというやり方です。と言いつつ、いくつかの実践方法の詳細に関しては対照的なやり方が存在し、以下のようなポイントが挙げられます
- SREのみがon-callなのか、ソフトウェアエンジニアがon-callの重荷を共有しているのか?
- SREが実際のエンジニアリングや自動化を行なっているのか、それともデプロイのような手動の繰り返し作業や、繰り返し発生するon-call対応などに追われているのか?
- SREが中核的なコンサルティング組織として存在しているのか、プロダクトチームに内包されているのか?
正しいSREモデルとは?
業界の中で大量に実践例があるとしても、この問いに関する正しい答えというのものは存在せず、どのモデルにも穴があり、結果として何らかの問題を引き起こします。私のここ10年の経験と観察結果からくる、私なりの最適解と思える形を以下に簡単にまとめたいと思います。
-
運用やreliability engineeringのスキルは別物として考える必要があり、とても貴重なものであるという認識を持つ。全てを自動化し、ソフトウェアエンジニアは交換容易であるべきという安易な考えは、ソフトウェアエンジニアリングと同様(それ以上ではないとしても)に大事なエンジニアリング力を過小評価してしまっています。ソフトウェアエンジニアがストレスのかかる障害中のデバッグや復旧に馴染めないように、運用エンジニアが空のソースファイルに馴染めなくてもいいのです。運用エンジニアとソフトウェアエンジニアはパートナーであり、交換可能な歯車ではないのです。
-
SREはon-call、ダッシュボードの諸々、デプロイをするためのお猿のような存在ではないのです。彼らはプロダクトに関するタスクではなく、信頼性に関するタスクにフォーカスするソフトウェアエンジニアなのです。理想的な構成では、すべてのエンジニアが、on-call、デプロイ、モニタリングといった基本的な運用タスクを行える必要があります。そして、このことは、reliablityエンジニアとソフトウェアエンジニアの線引きをなくし、ソフトウェアエンジニアがプロダクトの品質に責任を持つ風土を作るために、とても重要なポイントであると私は思っています。
-
SREはプロダクトチームに内包されるべきである、が、プロダクトチームのエンジニアリングマネージャーを上司とするべきではない。これによって、SREがチームの他メンバーと一緒に問題に取り組み、信頼関係を築き、同時にreliability vs featureの問題が起こった時に、しっかりと話し合うことが出来るようになります。
-
SREチームを内包する目的は、信頼性に関わる機能を追加したり自動化を推進することによって、プロダクトの信頼性を増すことや、チーム全体に運用のベストプラクティスを伝えて教育することにあります。そして、プロダクトチームとインフラチームを繋ぐ架け橋(ドキュメントに対するフィードバック、今のツラミ、必要とされる機能など)のような存在になってもらうことです。
-
成功しているSREは上記のような内容を成長フェーズの初期に行っており、同時に採用や継続的な教育とドキュメンテーションといった本物の投資を行い、エンジニア組織全体の底上げを行うとともに、先に述べたような人的スケーリングの問題の影響を軽減することができるのです。
結論
このポストの内容が直接当てはまる、急成長のフェーズまでたどり着ける会社はかなり限られています。多くの企業では、エンジニアの数や求められる信頼性、ビジネスに必要なイテレーションの頻度を考えると、モダンなcloud nativeのインフラの上に、純粋なDevOpsモデルを構築することで十分だと思います。
このポストの内容が当てはまる少数の企業にとってのkey takeawayは以下になります。
-
DevOpsスタイルのアジャイル開発や自動化は、生き残りたいテクノロジー企業には必須である。
-
誰もが利用可能なcloud nativeなインフラと少数の中核的なインフラチームによって、数百人規模まではエンジニア組織はスケール可能である。それを超えると、教育不足や解決にあたって特別なスキルが求められるような運用負債が表面化してくる。
-
運用の人的スケーリング問題に先手を打つには、採用や継続的な教育、ドキュメンテーション、そして、プロダクトチームとインフラチームの架け橋となるSREチームの構築という、本気の投資が必要となる。
モダンな急成長インターネット企業は、(私の見立てでは)残念ながら非常に多くの数の燃え尽き症候群を生み出しており、その理由は、プロダクト側の過酷な要求とインフラの運用への投資の少なさにあります。エンジニアリングのリーダシップによって、この流れを押し戻し、組織の安定基盤を揺るがさないようにすることは可能だと信じています。
一方で、新しい会社はcloud nativeな自動化によって、従来型の運用エンジニアは不要になったという幻想を見ているかもしれませんが、それは真実からは程遠い認識かもしれません。予測可能な範囲の未来では、その時点での最新の技術を使っているとしても、運用や信頼性に特化したエンジニアは、実務を通じてしか得られない重要なスキルセットを持っている存在として認識され、評価されるべきで、そのように重要な役割を持ったチームを成長フェーズの初期段階でしっかりと形作ることが大事です。