責任共有モデルの視点から考える重要性

原トリ氏:世の中には、アプリケーション開発者はアプリケーションコードだけを書き、コンテナ化あるいはコンテナオーケストレーション周りのことはすべて運用チーム、会社によってはSRE(Site Reliability Engineering)という名前がついているチームがやっている会社がたくさんあると思っています。

冒頭で、「アプリケーション開発者はコンテナイメージの作成やECSタスク定義、あるいはKubernetesマニュフェストみたいなものを書いて、そこからデプロイをしたものを自分で運用するべき」という話をしました。

なぜそう考えるのかについては、当然さまざまな観点から説明可能ですが、今日はこれを責任共有モデルの観点から説明します。聞き覚えがない方は、責任分界点という言葉で考えてもいいかもしれません。

AWSはコンテナサービスに限らず、「お客さまがAWS上でシステムを動かす時に、AWSはクラウドそのもののセキュリティや運用に責任を持ちます」と表明しています。また、「お客さまは、AWSが責任を持っているクラウドの中で動かしているものの責任を持ちます」と。その分界点を定めたリンクをWebサイトの下に貼ってあるので、まだ読んだことない方はぜひ一度読んでみてください。

なぜこれが重要か。これが明示的に定義されていないと、AWS自身もお客さま自身も、どこまでが自分たちの責任範囲かわからなくなり、運用難易度が高まってしまうからです。

EC2に落とし込んだ場合の境界線

(スライドを指して)この責任共有モデルをEC2に落とし込んでみましょう。EC2の場合、下のほうに書いてある点線がAWSとお客さまの責任分界点です。

AWSは物理サーバーやハイパーバイザーに責任を持ち、お客さまはその上で動かすEC2 インスタンスなどの仮想マシン、その中のOSや、その上で動かすアプリケーションに責任を持つ。

少し考えてみてください。(スライドを指して)もし、この責任共有モデルの分界点の線が点線部分に引かれていたら困りませんか?

例えば、図のランタイムのあたりで何か障害が起こった時、どちらが対応すべきか非常にわかりにくい。誰が責任を持っているのか、誰が対応すべきかわからないということは、障害からの復旧に時間を要する可能性が高いということです。

複数の関係者が共同でシステムを組み上げて運用していく際に、中途半端な位置に責任分界点が設けられていては、うまくいくものもいきません。

コンテナワークロードは、ECSの場合、コンテナオーケストレータはAWSの責任範囲です。EC2から上がお客さまの責任範囲になるわけですが、いろいろなユーザーと話していると、(スライドを指して)この辺りに境界線を引いている方がたくさんいます。

Dockerファイルを書いたり、ECSタスク定義を書いたりするのは運用側。アプリケーションエンジニアは上のアプリケーションの部分で、コードを書いたり、あるいは言語ランタイムの部分もちょっとやったりする。

ここで1つ疑問が浮かびます。中途半端な責任共有モデルは問題解決のスピードを落とす、あるいはその妨げになると先ほど確認しました。なのに、なぜこんな境界線が許容できるのか。違和感がありませんか。

許容可能な境界はどこか

許容可能な、甘んじて受け入れられる境界はどこか。(スライドを指して)少なくともコンテナのレイヤーまでは開発チームが責任を持つ、という境界線になるはずなんです。この境界線は、仮想マシン時代には引くことが難しかったんです。言語ランタイムが仮想マシンに埋め込まれていることが普通だったので、非常に難しかった。

コンテナ時代だからこそ、素直にこんな位置に境界線が引けるわけです。つまりコンテナを使う選択をしたのであれば、こういうきれいな場所に責任共有モデルを実装できるんです。

そんな責任共有モデルに基づいて考えた場合、各チームの責任範囲はどう定義されるか。開発者はコンテナから上に責任を持ちます。Dockerファイルを書き、オーケストレータ用の定義ファイルを書きます。コンテナより上のレイヤーに運用責務を持って、オンコールも受け持ちます。

アプリケーションレイヤーがおかしいというアラームが起きたら、開発者が責任を持って対応すべきです。もちろん運用担当者が実装レベルで会話できて協力体制を組めるように、積極的に支援することも必要です。

運用チームは、コンテナより下に責務を持ちます。開発者が投入してくるコンテナが実行できる環境を維持することに、運用チームは責務を持つ。ただし、開発者が運用観点で設計やコード記述ができるように、運用チームは積極的に支援していかなければなりません。

開発・運用共通のゴール設定と責任の共有で、運用性に優れたソフトウェアが育つ

まとめます。アプリケーション開発者はECSやKubernetes、ひいては運用をどこまで知ればいいのか。運用性に優れたソフトウェアは、運用を無視した開発からは絶対に生まれません。大事なのは、ソフトウェアの価値がユーザーに届くのは運用のフェーズだということです。

だからこそ、運用性に優れたソフトウェアを作らなければいけない。開発と運用にどうしても明確な責任分界点が必要な場合は、コンテナから上を開発チーム、コンテナより下を運用チームの責任範囲としましょう。開発者はDockerファイルを書いて、コンテナオーケストレータの定義ファイルを書きましょう。オンコールを受け持って、障害対応や運用改善を行いましょう。

開発と運用が共通のゴールを設けて、システムを作って運用していく責任を共有することが、継続的なデリバリを前提とするソフトウェアの理想です。今日のセッションは個人的な意見も入っていますが、目指すべきかたちはこうだと常々考えていますし、僕自身は信じています。

当然、所属している会社あるいは組織的な制約によって、ここまでドラスティックなかたちを採ることは難しい方もいると思います。ですが、冒頭でも当社のCTOワーナーの話を引用したとおり、このかたちを目指すことで、運用性に優れたソフトウェアが育ち、それがシステムの開発と運用のよいサイクルにつながるはずです。

僕の想像も入りますが、そもそもSREという役割が生まれた背景あるいはそれが目指した世界は、コードによってシステムとその運用の継続性、信頼性を高めるというものではなかったのかと、思うことがあります。本日のセッションが、みなさんのソフトウェアに優れた運用性をもたらすきっかけの1つとなることを祈っています。以上です。