フューチャー技術ブログ

OpenSLOについて

はじめに

はじめまして、原木と申します。

皆さまはSRE NEXTをご覧になりましたでしょうか?

SRE NEXTは 先日実施された『信頼性に関するプラクティスに深い関心を持つエンジニアのためのカンファレンス』です。国内外のエンジニアが日々SRE(サイト信頼性エンジニアリング/Site Reliability Engineering)の実践手法を共有することで、Webサービスが今後運用、成長していくための次世代の信頼性を担おうとしています。

もしもWebサービスの運用を安定的に行う手法やそのためのチームビルディングに興味がある場合、SRE NEXTの動画セッションやスライドが公開されると思うのでご覧ください1

さて本ブログではそんなSREとも関係の深い、OpenSLOに関して取り上げたいと思います。

OpenSLOとは

最近、SLOモニタリングという言葉が注目を集めつつあります。例えば、GoogleCloudのCloud Monitoringではサービスモニタリングというサービス名をSLOモニタリングと改め、SLOを使った運用監視を強く推しています。

従来の運用監視とSLOでは何が違うのでしょうか?その手掛かりの一つにOpenSLOがあります。

OpenSLOとは、SLOを定義するためのオープンな仕様です。SLOのSaaSサービスを展開しているNobl9が中心となって策定し、先日バージョン1.0を迎えました。

https://github.com/OpenSLO/OpenSLO/releases/tag/v1.0.0

実際にOpenSLOの例を見てみましょう。

apiVersion: openslo/v1
kind: SLO
metadata:
name: slo-example
displayName: "ウェブサイトの可用性に関するSLO"
spec:
service: website-backend-service
# エラーバジェットの消費方法
budgetingMethod: Occurrences
# タイムウィンドウ
timeWindow:
- duration: 4w
isRolling: true
# SLI
indicator:
metadata:
name: error-count
displayName: ""
spec:
ratioMetric:
counter: true
good:
metricSource:
metricSourceRef: prometheus-datasource
type: Prometheus
spec:
query: sum by(handler)(rate(http_requests_total{code="200"}[1m]))
total:
metricSource:
metricSourceRef: prometheus-datasource
type: Prometheus
spec:
query: sum by(handler)(rate(http_requests_total[1m]))
# SLO
objectives:
- displayName: Total Errors
target: 0.98

OpenSLOを読み解くには、SREの知識が頭の片隅にあるとわかりやすいでしょう。そこでSREの概念をそれぞれ説明しながら、従来の運用監視とSLOの目指す姿の違いについてOpenSLOを通して理解を深めたいと思います。

SLOとは?

サービスレベル目標(SLO)とは、サービスの信頼性の目標レベルを指定します。

サービスの信頼性ってわかるようでわからないですね。

“実際、信頼性(reliability )は可用性(availability )だけではなく、品質(quality)、信頼性(dependability)、応答性(responsiveness)など幅広い含意を持つ言葉です。”

メーカーの工具から自分の友人に至るまでどれくらい信頼できるのかって聞かれても、なかなか即答って難しいかなと存じます。

それでも、あえて挙げるとするなら自分はImplementing Service Level Objectivesという書籍の定義が気に入っています。

The question “Is my service reliable?” is pretty much analogous to the question “Is my service doing what its users need it to do?”
「私のサービスは信頼できるか?」という問いは、「私のサービスはユーザーが必要とすることを行っているか?」という問いによく似ています。
https://learning.oreilly.com/library/view/implementing-service-level/9781492076803/ch01.html#service_truths

「私のサービスはユーザーが必要とすることを行っているか?」

この問いに答えるための材料として重要視されるのが、システムの可用性があります。

Googleでは、システムの可用性をSLOとして正確な数値目標に落とすことしました。

SRE は、可用性が成功の前提条件であるという考えが発端になっています。
可用性のないシステムはその機能を実行できず、デフォルトで失敗します。
SRE 用語における可用性の定義は、システムがある時点で目的の機能を実行できるかどうかです。
可用性測定の履歴は、レポートツールとしてだけでなく、システムが将来的に予想どおりのパフォーマンスを発揮する確率を示す指標としても使用できます。

GoogleはSREの用語を定義するにあたり、システムの可用性を正確な数値目標として設定したいと考えました。
この目標をシステムの可用性サービスレベル目標(SLO)と呼びます。
https://cloud.google.com/blog/ja/products/devops-sre/sre-fundamentals-sli-vs-slo-vs-sla

この数値目標がSLOの実態です。このSLOをOpenSLOでどのように定義しているのかは後述で解説するとして、試しにSLOを設定するために、極端なケース…例えばSLOを100%とします!!といった場合に何が起きるか考えてみましょう。

数値目標

なぜSLOではシステムの信頼性、可用性を測定するために正確な数値化が必要なのでしょうか。

SRE発祥の地でもあるGoogleの社内文化を色々な書籍を通じてみていると
この数値化に対してのモチベーションの根本に、多様性を肯定する社風が見えてきます。

メンバが多種多様な価値観や考え方を持つ中で、意思疎通を誤りなく行うには
客観的な指標と、なぜその数字を採用したのかという導出を誰でもわかる形で残すことは欠かせません。

そのような文化のなか、運用にも変化が生じました。

「私のサービスはユーザーが必要とすることを行っているか?」

この問いの中で、旧来の運用監視では損失だと思われていた指標を、機会投資の指標だと見なせないかと考えるようになりました。
ポジティブなフィードバックこそが明日のWebサービスを担う推進力であり、コンセンサスの源泉となるからです。

100%のSLO=絶対に壊れないシステム?

100%のSLOとは、先の定義によればユーザーが必要とするときにサービスが目的の機能を提供できる状態が完全無欠に保たれていることです。
ならばすべての目標値を100%にすれば、サービス運用は安泰ではないか、そういった軽重な考えに、
SRE の基本(2021 年版): SLI、SLA、SLO の比較では警告を鳴らしています。

サービスの信頼性が高いほど、運用コストが高くなることに注意してください。

各サービスのユーザーが許容できる最低レベルの信頼性を定義し、それを SLO として規定します。すべてのサービスには可用性 SLO が必要です。これがなければ、チームや関係者はサービスの信頼性を高める(コストを増やして開発を遅らせる)必要があるのか、あるいは信頼性を下げる(開発速度を上げる)必要があるのかを、原則に基づいて判断できません。過剰な可用性が期待されるようになり、それが問題になることがあります。

ユーザー エクスペリエンスにとって必要でなければ、システムの信頼性を過度に高くしないでください。常にそのレベルに到達することを確約するつもりがない場合はなおさらです。

SREのポジションにあるエンジニアは、次の1,2の間を調整することに大抵は苦労します。

  1. サービスを継続的に新規開発する速度
  2. その結果低下していくサービスの信頼性

どんな注意を払っても開発がある限り、サービスの信頼性に影響を及ぼすことは避けられません。

しかし、システムを塩漬けにして永遠に変わらない変化をもたらしたとしても「ユーザーが必要としていること」が満たされたままとは限りません。

どちらが正解なのか…

もしもそこにユーザーエクスペリエンスに繋がる指標が、蓄積された状態であったとしたらどうでしょう。ウェブサービスのSLOがほんの少し下がってもユーザーの顧客マインドに影響が及ぼさず、満足度を保ったままでいられることがわかりました。あえて余裕のある数値をSLOとして設けることで、それを満たしている間は、サービスを継続的に開発してもいいのではないか?という考えが生まれました。

エラーバジェットの誕生です。

可用性の担保について、ある程度のリスクを”予算”と見なすことで予算を超過しそうなら開発速度を抑えて、予算内であれば開発を促進するといったように、サービスを開発する速度をコントロールできるようにしたわけです。

OpenSLOにも budgetingMethod: Occurrences という項目があります。これは出現率法は、イベント全体に対してgoodイベントのカウントの比率をエラーバジェットの計算方法として使用するという意味です。

全体のイベントのうち、”良い”イベントの割合を指標として採用する考えはSLOとしてよく採用されています。

SREをダイエットで例えたら...

ダイエットにおいて食事制限は最も基本的なやり方です。食事を制限するために我慢を強いられる方も多いと思います。

例えば、ダイエットをするときの努力目標として1日1600kcalしか取らないと決めたとします。
一日で1600kcalしか取れないんだと思うよりも、1600kcalも食事をしていいんだって思った方がポジティブになれないでしょうか。

同じことがエラーバジェットにも言えます。

SLOとSLI

エラーバジェットを作るためには数値目標とそれを図るための測定手段が必要です。
サイトリライアビリティワークブックというSREの参考書では具体的な方法が記載されています。

例えば、Webサイトにおいて、ユーザーからの評価を良好に保つために読み込み時間を測定、SLOとして定めたとします。
これは「サイトリライアビリティワークブック」によれば、SLI specification (SLIの仕様)と SLI implementation (SLIの実装)として分解することができます。

  • SLI specification (SLIの仕様)
    • 100ms以内でホームページが読み込まれた割合。
    • ユーザーにとって重要だと思われるサービス評価の結果
  • SLI implementation (SLIの実装)
    • SLIの仕様を計測するための手段。例えば…
      1. サーバーログから計測したサーバー内の処理時間
      2. VM環境のブラウザで動くJavaScript製のプロバーによる測定時間
      3. ユーザーのホームページのリクエストのうち、読み込み時間が100ミリ秒未満のものの割合。

通常、SLIを測定するための手段である SLI implementation (SLIの実装)は複数あり、それぞれのトレードオフを踏まえた上で、今どの指標がユーザーの信頼を測定するために必要な指標か考える必要があります。

OpenSLOにおけるSLI仕様/SLI実装

OpenSLOでは、SLI仕様/SLI実装に該当するのがobjectives(目標)とindicator(指標)という項目です。objectives(目標)では数値目標を記載し、indicator(指標)ではSLIの実装にあたるメトリクスの取得方法を記載しています。

OpenSLOの例を振り返ってみましょう。objectivesと indicatorの項目があることがわかります。

apiVersion: openslo/v1
kind: SLO
metadata:
name: slo-example
displayName: "ウェブサイトの可用性に関するSLO"
spec:
//略
indicator:
metadata:
name: error-count
displayName: ""
spec:
ratioMetric:
counter: true
good:
metricSource:
metricSourceRef: prometheus-datasource
type: Prometheus
spec:
query: sum by(handler)(rate(http_requests_total{code="200"}[1m]))
total:
metricSource:
metricSourceRef: prometheus-datasource
type: Prometheus
spec:
query: sum by(handler)(rate(http_requests_total[1m]))
objectives:
- displayName: Total Errors
target: 0.98

GoogleSRE Workbookなどによると、objectives(目標)について二つの数値の比率から導出できることがお勧めされています。

例えば、

  • 成功したHTTPリクエストの数/合計HTTPリクエスト(成功率)
  • 100ミリ秒未満で正常に完了したgRPC呼び出しの数/合計gRPCリクエスト

SLIは spec.indicator.specという項目から読み取ることができます。Pometheusから連携したメトリクスのうち、1分以内に受信したリクエストとそのうちステータスコードが200だったステータスをそれぞれSLIとしてカウントし、ratioMetricとしてその割合を計算していることがわかります。

そしてSLOにあたるのがspec.objectives になります。
エラーとなったステータスリクエストが全体の割合で2%を下回ることを求められています。

apiVersion: openslo/v1
kind: SLO
metadata:
name: slo-example
displayName: "ウェブサイトの可用性に関するSLO"
spec:
//略
objectives:
- displayName: Total Errors
target: 0.98

SLO/SLIをどのような周期で観測するか(そしてその期間を過ぎたらリセットするか)というタイムウィンドウに関する設定もあります。
下記の例では4週間を一定期間としてその特定の日数分だけSLOを評価していることがわかります。

apiVersion: openslo/v1
kind: SLO
metadata:
name: slo-example
displayName: "ウェブサイトの可用性に関するSLO"
spec:
budgetingMethod: Occurrences
 timeWindow:
- duration: 4w
isRolling: true

OpenSLOの現状

OpenSLO自体は単なる仕様であり、ドキュメントなので

  • 運用監視からの情報取得方法
  • そのSLO情報に変化があった場合に画面可視化を行うサービスへの連携

…など、いまだ周辺のエコシステムは拡張に向けた途上にあります。

現状あるツールを紹介します。

  • OpenSLO/oslo
    • SLOで書かれたYamlファイルのバリエーションチェックなどを行うCLIツール
  • OpenSLO/slogen
    • SUMO LogicというSaaSに提供するためのダッシュボード、運用監視対象の自動生成ツール
  • sloth/sloth
    • PrometheusのSLO設定を容易にするためのジェネレーターツール。チャットツールであるMattermostなどで活用されている。OpenSLOを限定的にサポートしている。

OpenSLOは、最終的にSLO-as-codeとしてサービスレベルが達成されているかどうかを確認するメトリックを簡単に収集できるようにすることを目的とし、開発が現在も積極的に行われています。

ITサービスのメトリクス自体はITシステムができた当初から、安定的な運用目的のために取得されてきた情報ですが、SREというフレームワークの大転換により、メトリクス情報がサービスが停止するという機会損失の指標から、新機能開発による機会創出の指標としてつなげられるようになったのはここ最近の変化です。その中心にSLOがあります。

OpenSLOのエコシステム拡充が進めば、これから先、運用監視ツールとして欠かせないものになっていくのではないでしょうか。

私的感想

まだ道半ばですが、generatorについてエコシステムが整うことで運用監視体制がそのままGitOpsとして管理できるような体制になると面白そうですね。その片鱗はすでに各所で起きています。

例えば、Preferred Networks Researchでは、Alertmanagerでシステムの異常検知を行った後、それをGitHubのissueとして自動的に起票できるようにするOSSを開発しています。
https://github.com/pfnet-research/alertmanager-to-github

例えば、GrafanaのThemaではCUELANGをベースに、ダッシュボードのコード化を進めようとしています。(既存でもJsonnetという仕組みがあるのですが扱いづらいということから生まれました)
https://github.com/grafana/thema

同様にOpenSLOの仕様書もGit上で管理されて、OpenAPIやIaCでは既に実践されていることではありますが、運用監視システムにCI/CDで動かしたgeneratorを通して組み込まれることで、SLOの棚卸しを気軽に行えるような体制が組めるといいなと思いました。


  1. 1.SRE NEXT様と筆者(そして多分弊社も...)の間には2022年現在何の関係もありませんが、好きなイベントなのでこの場をお借りして宣伝させていただきました。