昨今では自社のプロダクトやシステムのエンゲージメント向上のために、「DevOps」や「アジャイル」といったキーワードのもと、大小さまざまな企業がシステムやアプリの開発手法の改善を試みています。その中において、最近だと「SRE」というキーワードを聞く頻度も多くなってきたかと思います。
しかしアジャイルやCICDなどと比べ、SREについては「言葉は知ってるけど具体的になんなのかはよくわからない」という方もいるのではないでしょうか?ここではそんな方々向けに、SREの最初の一歩となる概要について、独自の解釈を交えつつまとめていきます。
ここで話すこと
- SREって何?
- なぜSREが必要?
- SREってどんなことするの?
ここで話さないこと
- SREの技術の具体的なところ(k8sやAPMの導入手順、設定方法など)
- プラクティスの実践例・具体例(アーキテクチャ、各種設定値、モニタリング指標など)
TL;DR
SREとは?
SREというのは、Google社が提唱した運用のプラクティスのことです。
世の中ではSREのプラクティスを導入してアプリを運用する部隊をSREチームと呼んだりします。
SREとは”Site Reliability Engineering”の略です。Google翻訳さんいわく日本語だと「サイト信頼性エンジニアリング」です。まんまですね。
提唱者のGoogleはSRE本で以下のように述べています。
My explanation is simple: SRE is what happens when you ask a software engineer to design an operations team.
SREは、ソフトウェアエンジニアに運用チームの設計を依頼した時にできあがるものです。
引用:https://sre.google/sre-book/introduction/
運用の設計を依頼というのがポイントです。「ソフトウェアエンジニアが運用するんだ」というイメージを持った方もいるかと思いますが、そういう捉え方よりも**「ソフトウェアエンジニアリングの技術をもって運用の信頼性を担保していくぞ!」**というイメージの方が実態に近いと思います。必ずしも現在のロールがソフトウェアエンジニアである必要はないということです。
具体的にどんな技術を持ってSREを実現するのかは後ほどお話します。
SREの背景
そもそもなぜSREという概念が生まれたのでしょうか?従来のシステム開発における課題から紐解いてみます。
従来のシステム開発の課題
当たり前ですが、システム開発の目的は「顧客により良い価値を提供する」ことです。しかしその目的を実現するために、開発チームと運用チームはそれぞれ異なるミッションを持っています。
- 開発チーム:どんどん新しい機能をリリースしてユーザーによりよい体験を届ける(イノベーション重視)
- 運用チーム:ユーザーがきちんとサービスを利用できるようにシステムを安定運用する(信頼性重視)
要は「新機能の追加・変更をガンガンしつつ、システムを安定運用する」ことができれば目的を達成できるのですが、従来の手法ではこれがなかなかうまくいきませんでした。
様々な要因があったりしますが、主に運用チーム側の負担が大きくなることによるチーム間の対立が挙げられます。
<運用チームの声>
- システムのアップデートにはダウンタイムが必要なのがデフォ
- 切り戻しにも結構時間がかかるし、手間もかかる
- ちゃんと開発側が試験できているか不安
- そもそも今の環境を安定運用するのに精一杯で、そんな頻繁なリリースなんて対応できない
運用チームがわがまま言っているように聞こえるかもしれませんが、かなり切実な叫びです。
そんな疲労困憊した運用チームを見て、Googleのソフトウェアエンジニアが「俺たちの技術力で運用を変えてやる!」と運用チームのあるべき姿を設計したのがSREの始まりです。
これまでの人手での運用作業から脱却し、ソフトウェアエンジニアリングの力によって信頼性を担保する。そうすることでシステムのイノベーションの加速と信頼性の担保を両立し、「対立」を「協力」へと変化させ目的を達成する。そのためにSREが生まれました。
ですので、SREは**「顧客により良い価値を提供するため」**という当たり前な目的を達成するために必要なプラクティスなのです。
DevOpsとの違い
ここまで聞くと、「それってDevOpsと何が違うの?」と思った方もいるのではないでしょうか?
認識の通り、DevOpsとSREは密接に関わっています。
DevOpsというのは、開発チームと運用チームが相互に協力し合いながら開発を行い、迅速・高頻度にシステムをリリースすることでビジネスの価値を高めていく概念です。一方でSREはそのDevOpsな状態を実現するための取り組み(プラクティス)になります。
似たところで言うと「アジャイル」と「スクラム開発」のような関係に近しいと思います。
SREの実践
これまでふわっとした言葉でSREを説明してきましたが、じゃあ具体的にどうやるんだってところが気になるかと思います。
実際の方法をお話する前に、SREを実践する上で大事な考え方をお伝えします。
エラーバジェット(Error Budget)
SREは信頼性とイノベーションの両方を支えるために、エラーバジェットという考え方を採用します。エラーバジェットとは、SLO(Service Level Objective)で定めた値を、そのプロジェクトの「予算」として捉える考え方です。
例えば、あるシステムのSLOを「年間の可用性99.9%」と定義します。すると、年間で8.76時間までの停止を許容できると解釈できます。これまでの運用では「可用性は100%が当たり前だが、万が一トラブルが起こっても年間8.76時間までなら許される」といった考えが主流だったと思います。
しかしエラーバジェットにおいては「年間8.76時間までなら止まってもいいから、この時間を上手く使ってガンガンリリースして行こう」という考え方になります。
SLOの余剰分を「万が一の時の保険金」ではなく、「有効活用するための予算」として捉えるのがエラーバジェットです。
つまり、このエラーバジェットは開発チームとSREチームが共同で持っている資産だと言えます。
開発チームがリリースを要請し、それに応えるべくSREチームがシステムを停止しアップデートする。するとシステムを停止した分だけエラーバジェットが消費されていきます。
またシステムトラブルやバグが原因でシステムが停止した場合も、復旧までの時間がエラーバジェットとして消費されます。
最終的にエラーバジェットが枯渇すると、開発チームがせっかく作ったものもリリースができなくなってしまいます。そのため、SREチームと開発チームは協力してこの予算をやりくりしていく必要があるのです。
これまではリリースにかかる予算と故障対応の予算は別のものと考えられてきましたが、どちらもひとつの指標で管理することで、イノベーションと信頼性を両立していこうということです。
しかし、このエラーバジェットの考え方だけを導入しても、従来の運用方法ではすぐに予算が枯渇してしまい、攻めのリリースができなくなってしまいます。そこでエラーバジェットを有効活用するべく、SREではソフトウェアエンジニアリングを活用するのです。
SLOの定義
エラーバジェットの活用に向けて、まず最初に行うのはSLOの定義です。
先述しましたが、エラーバジェットはSLOを指標値として評価・計算するため、まずはSLOの定義から実施しましょう。
SLI/SLO
SLO(Service Level Objective)は、SLI(Service Level Indicater)と呼ばれる指標と、具体的な目標値からなります。
たとえば、リクエストのレイテンシーや可用性、エラー率などがSLIの候補としてあげられます。
それに目標値を定め、「可用性99.9%」や「リクエストの99%がレイテンシー0.5秒以内」といった形にすることでSLOが定義できます。
言葉にすると簡単ですが、このSLOを定めることに多くの人はかなりの時間を費やします。
SLOは技術ベースで決めるのではなく、ビジネスや製品の特性から定めることが求められるからです。
「エラー数が計測できるからエラー率をSLIとする」のではなく、「ビジネスに◯◯といった影響が出るからエラー率をSLIとする」といったロジックで定義する必要があるということです。そのためにはシステムやアプリケーションがビジネスにどういった価値を与えるもので、何が不足するとその価値が提供できなくなるのかを正しく理解する必要があります。
SLOの定め方については様々な方が記事にまとめていますので、最初は自分のシステムの特性と近しいものからピックアップする形でもいいかと思います。
SLI/SLOの詳しい説明やビジネスの価値をベースとしたSLIを定める必要性については、以下のサイトがわかりやすくまとまっています。
https://cloud.google.com/architecture/defining-SLOs?hl=ja
SLOの測定
無事にSLOが定義できたら、次に現状SLOがどれくらい満たせているのか、すなわちエラーバジェットがどれくらい余っているのかを常に把握できる状態を作ります。
モニタリング
SLOの計測には、一般的にモニタリングツールを導入してシステムの状態を把握できる環境を整えることが推奨されています。
モニタリングツールは昨今様々な機能が具備されてきていますが、SLOという観点で言うと従来のシステム監視だけでなく、APMも重要な機能となっています。
APM
APMとは「Application Performance Monitoring」の略で、その名の通りアプリケーションの性能を監視する機能です。
これまでのシステム監視は主に開発者・運用者目線で必要なメトリクス(CPU/メモリ使用率、プロセス監視など)の収集が主な目的でしたが、APMはアプリケーションの応答時間やアプリケーションに関わる様々な要素のパフォーマンスを監視することで、ユーザーの利用体験にどのような影響があるのかを確認することができます。
SLOはビジネスの価値に関係するものを選択する関係上、ユーザー目線でのモニタリングが非常に重要になります。そのため、SLOをきちんと定義できていれば自然とAPMの導入に舵が切られると思います。
システム監視
もちろん、APMだけでなくこれまでのシステム監視も重要な機能です。
ただしコンテナプラットフォームやパブリッククラウドなど、クラウドネイティブな環境におけるシステム監視は従来の監視方式と異なる点が多いため、APMの導入と並行して改めて監視設計を実施してください。
モニタリングに関してはまた別の記事にあげようと思います。
エラーバジェットの有効活用
SLOの定義と計測が、エラーバジェットを活用するための土台であることは理解いただけたかと思います。
ここから本格的にソフトウェアエンジニアリングを使って運用を効率化していきます。
運用対処時間の短縮
まずは運用対処時間の短縮です。運用担当者の多くが突発的な運用対処に人員が割かれ、リリースを延期した経験があると思います。そのためSREではこの対処時間を短縮することが求められます。
運用対処にはリソースの増強や故障の復旧対応、人為ミスの切り戻しなどがあります。これらにかかる時間が短縮できると、結果的にリリースに支えるエラーバジェットが増えることになります。
そこで有効なアプローチがシステムの自律化です。
自律化
自律化とは、「発生した事象を正しく理解し、対処策を判断し、実行するまでの一連の動作を自動的に行うこと」を指します。一方で、「事象の理解と対処策までを人間が行い、実行をボタン一つで処理すること」を一般に自動化と言います。
運用対処において自律化には以下のようなことが期待されます。
発生する事象 | 自律化による効率化 |
---|---|
急激なアクセス増によるリソース枯渇 | 自動でスケーリングして対処できる |
サーバー故障によるシステムダウン | 正常なサーバーに自動的に移動し再起動 |
リリースしたアプリにバグがあり、切り戻しが必要 | 自動で故障を判断し、切り戻しを実施 |
これらを簡単に実現するために、コンテナやコンテナプラットフォームを採用することが推奨されます。
コンテナプラットフォームとは、コンテナ化したアプリケーションのデプロイ、スケーリング、オートヒールなどの各種管理を実現するプラットフォームです。現在では**Kubernetes(K8s)**が主流となっています。
コンテナプラットフォームの主な特徴は以下の通りです。このほかにも様々な周辺機能を備えています。
コンテナプラットフォームの特徴
機能 | 概要 |
---|---|
コンテナイメージのデプロイ | コンテナイメージの実行環境へのデプロイを自動的に実行 |
オートヒーリング | 障害などでコンテナがダウンした場合にも自動的に復旧 |
NW/ボリューム管理 | 煩雑なコンテナ周りのNW構築・ボリューム接続を簡易に実施 |
オートスケール | アプリケーションの負荷に応じてコンテナ数を自動的にスケール |
コンテナ/Kubernetesを前提とした環境を構築することで、数々の自律化を実現し、運用対処の時間を短縮することができます。
自律化では対処できない場合
無論、自律化だけで全ての事象が解決できることが理想ですが、ほとんどの場合、人による判断の元トラブルの事象を解析し、対応するケースが発生します。そうなった場合、エラーバジェットの消費を抑えるためにはどれだけ早くトラブルに気づき、対処が打てるかが重要です。
アラート疲れからの脱却
早くトラブルに気づくためには、先述したモニタリングが有効です。ただし、むやみやたらに監視項目を増やし全部アラートを飛ばしていると、アラートの分析に稼働がとられ所謂「アラート疲れ」が発生してしまいます。疲れるだけならまだしも、本当に対処が必要なアラートを見逃してSLOが下がってしまうと本末転倒です。
トラブル事象を早期に発見し、かつすぐに対処策を講じれるよう、開発チームと連携して本当にアラートが必要な事象は何なのか、またどういったメッセージをアラートに乗せるといいのかを検討してください。
よくある「アラート疲れ」を引き起こすアラート設計を以下にまとめます。
アラート設計 | 効果 |
---|---|
コンテナが落ちる度にアラート | Kubernetesでオートヒールするため効果がないことが多い |
Nodeダウンのアラート | マネージドなKubernetesサービス(EKS/GKEなど)を利用の際は不要 |
レスポンスタイムが閾値を超える度にアラート | スパイクの可能性が高いため、平均値を取るなどして効果的なアラート設計にするべき |
オートスケール関連のアラート | コストの観点で可視化は必要だが、システムの信頼性に影響がないためアラートを飛ばす必要はない |
リリース時の停止時間の短縮
SLOを消費する原因のもうひとつが、リリース時の業務停止です。システムの都合上どうしても業務停止が伴うことがあるかもしれませんが、一方で単純にリリースする手順や方法が未熟なために停止時間を設けている場合も多くあると思います。
SREではそういった要因をできる限り排除し、エラーバジェットの消費を防ぐことが求められます。そこで無停止でのデプロイ手法の採用が解決策になります。
無停止でのデプロイ手法
無停止でのデプロイ手法をいくつか紹介します。
Blue/Greenデプロイ
Blue/Greenデプロイとは、現行バージョンと新バージョンの2つのシステム環境を準備し、ルーティングの切替で瞬時にリリースする手法です。
あらかじめシステムをデプロイしておき当日はルーティングを切り替えるだけなので、ダウンタイムを最小に留めることができます。
しっかりとデプロイの準備をしたい複雑な構成の場合に利用します。環境を2面作る必要があるので、その分コストが上がります。
カナリアリリース
一部のユーザーにだけ新バージョンを提供し、フィードバックを確認した上で全ユーザーにリリースする手法です。
万が一新バージョンで不具合が発生しても、影響のあるユーザーを一部に限定できることから、試験的な新機能のリリースに適しています。
ローリングアップデート
システムを少数ずつ新バージョンへ切り替える手法です。一般的に全てのリクエストが2つのバージョンのどちらにもルーティングされます。
システムリリース時の負荷やバグによる影響を局所化し、無停止でのリリースを実施します。
軽微なバグFIXやUI改善など、N-1のバージョン差分を許容できる場合に利用します。
上記のようなリリース時の停止時間を最小限に留めるためのデプロイ手法を採用することで、エラーバジェットの節約につながります。ではこれらの手法を採用するためにどのようなソフトウェアエンジニアリングが必要でしょうか?じつはこちらも**コンテナプラットフォーム**を活用することで解決できます。
コンテナプラットフォームとしてKubernetesを導入することで、様々なデプロイ戦略を採用することができるようになります。
ここでは具体的な方法や手順は述べませんが、そのうち上記デプロイのKubernetesでの実現方法を載せようと思います。
高頻度のリリース(イノベーション)実現に向けた戦略
ここまで、運用担当としての側面からエラーバジェットをいかに効率よく使っていくかを述べてきました。次に検討するのが、高頻度リリース実現に向けた開発側の改善になります。いくら運用側が故障を早期対処やリリース時間の短縮を図っても、開発側のリリースが半年に一回しかできないような状態だと意味がなく、ビジネス価値向上はできません。そのため、実はこの開発側のプロセス改善もSREの大きな業務のひとつになります。
ではどんな状態だと高頻度リリースが実現できていると言えるのでしょうか?
早く・正確に開発
当たり前ですが、高頻度のリリースをするにはそれだけ早く新機能を開発し、かつバグのない状態にする必要があります。そのためにSREはソフトウェアエンジニアリングの活用でこの環境を実現します。それは開発工程の自動化です。
昨今ではウォーターフォール開発よりもアジャイル開発が主流になってきていますが、そのアジャイル開発を支えるために重要なのが開発工程の自動化です。
ウォーターフォール開発ではきちんと時間をかけて試験項目表と睨めっこしながら試験を実施していましたが、アジャイル開発では開発したらすぐ試験し、問題があればすぐ直してまた試験と、開発工程内でいかに高速なフィードバックループを回せるかが鍵となります。そのためにはビルド→試験の開始→完了→マージまでの一連の動作を自動化することが求められます。
リリース作業時間の短縮
早く開発ができても、リリース作業自体に丸1日かかるとなると高頻度リリースは実現できません。つまりリリース作業時間の短縮も必要になります。そのためには開発工程と同様、リリース工程の自動化も必要になります。
リリース工程の自動化というのはつまりデプロイ(デリバリー)の自動化です。膨大なリリース手順を作成しマシン室にこもって1日中デプロイ作業を行うのではなく、ボタンひとつで自動的にアプリケーションをデプロイすることが求められます。
これら2つの工程の自動化を実現する技術としてCI/CDツールがあります。
CI/CD
CI/CDとは「Continuous Integration/Continuous Delivery」の略で、継続的なインテグレーションとデリバリーを実現する手法です。
CIでは開発者がソースコードをPushするとビルドが走り、試験が実施され、問題なければマージするといった作業の自動化を行います。CDではCIが完了したあと、こちらも自動的に適切な環境にアプリケーションをデプロイすることを指します。それぞれを自動化することで、高頻度で(=継続的に)インテグレーション・デリバリーを行える状態を作ることで、早く・正確に開発を進めることが可能になります。
このCI/CDを実現するために様々なツールが存在します。
CI/CDの両方を実現するものもあれば、CI・CDのどちらかに特化したツールもあります。自分たちの環境やスキルに応じて適切なツールを選択して下さい。以下に一例をあげます。
ツール名 | 概要 |
---|---|
Jenkins | CI/CDパイプラインを構築し、ビルド・デプロイを自動化する。CI/CD黎明期を支えたツール |
GitHub Actions | GitHubとの連携が簡単で、GitHub上の様々なアクションを設定可能。GitHubを使ってる人におすすめ |
GitLab-CI | GitLabとの親和性が高い。GitLab利用者ならまずはこちらの利用を検討してみてほしい |
CircleCI | Jenkinsに次いで有名なCIツール。ネットに情報が多いためベストプラクティスを参照しやすい |
Tekton | KubernetesネイティブなCIツール。KubernetesやOpenShift利用者ならこちらの利用を検討してみては? |
ArgoCD | KubernetesネイティブでCDに特化したツール。差分検知など、CIツールにない機能が魅力 |
AWS CodeBuild | AWSのマネージドなCIツール。ビルド時のリソースを気にしなくていいのでAWSが主流の環境ならおすすめ |
GCP CloudBuild | GCPのマネージドなCIツール。GCP利用者かつコンテナ環境なら親和性が高い |
Kubernetesとの親和性
CI/CDツールはKubernetesとの親和性が高く、一般に「Kubernetes環境を使ってる」というと、「CI/CD環境が整っている」と認識されることが多いです。TektonやArgoなど、Kubernetesネイティブを謳うツールも出てきているところから、CI/CDの実現のためにKubernetesを採用する企業が増えてきたのかなと思います。
ソフトウェアエンジニアリングの活用に向けて
さて、ここまでSREがどのような技術を活用して信頼性とイノベーションを実現していくのかを説明しました。
- SLOの評価および故障の早期発見のために、APM・インフラモニタリングを導入する
- 無停止でのデプロイや環境の自律化のために、**コンテナプラットフォーム(Kubernetes)**を導入する
- 開発工程、リリース工程の自動化のためにCI/CDツールを導入する
しかし、これらをただ導入しただけでは期待する成果はあげられません。当たり前ですが、これらをうまく活用するために様々な作業が必要になります。
以下は各技術の作業のほんの一例です。
- APM/モニタリング
- SLOの定義
- 監視項目の設計・設定
- エージェント導入・疎通確認
- ダッシュボード作成・更新
- アラート設計・設定
- コンテナプラットフォーム
- サーバ/NW設計・構築
- クラスタインストール
- Namespace設計・設定
- Quota設計・設定
- 権限管理
- CI/CDツール
- パイプライン設計・作成
- ツールインストール・各種設定
これら以外にも、システムのアーキテクチャ検討や、商用環境への適合などに関する開発チームへのコンサル、事務処理やミーティング、トレーニングなど作業は多岐に渡ります。
そしてこれらの作業が通常の運用作業とは別にSREとしてのやるべき作業として積まれていくわけです。これら全てを手当たり次第にこなしていると時間がいくらあっても足りません。そこでSREは**「トイルの削減」**を行います。
トイルの削減
トイル(Toil)とは、「苦労」や「労力」のことです。苦労や労力の削減と聞くと漠然としちゃいますが、提唱者のGoogleはSRE本でトイルを以下のように定義しています。
Toil is the kind of work tied to running a production service that tends to be manual, repetitive, automatable, tactical, devoid of enduring value, and that scales linearly as a service grows.
トイルとは、プロダクションサービスを動作させることに関連するもののうち、手作業で繰り返し行われ、自動化することが可能であり、戦略的で長期的な価値を持たず、作業量がサービスの成長に比例する傾向を持つもの
要は以下の要素を持つ作業のことをトイルと定義します。
- 繰り返しやる作業
- 自動化できそうな作業
- そんなにビジネス価値向上につながらない作業
- システムが大きくなればなるほどボリュームが増えそうな作業
個人的には、繰り返し行うことが多く、自動化できそうな作業はトイルと認識してもらって問題ないと思います。これらのトイルを削減することで空いた時間を、どんどんSREの本来業務である信頼性とイノベーションの両立に活用していくことが求められます。
ではトイルの削減はどうやって行うのか?一番わかりやすく効果的なのが作業の自動化です。
実は今回紹介したソフトウェアエンジニアリングの活用もこのトイルの削減に当たります。
モニタリングは有人で画面にべったり張り付くのをアラートの実装やダッシュボードによって効率化し、CI/CDは普段のテストやリリースといった繰り返し作業を自動化します。コンテナプラットフォームは基本的に定義ファイルをシステムにアップロードすることで設定を反映させるため、画面でぽちぽちボタンを押して設定していたこれまでと比べて自動化がかなり容易になりました。自律化自体もトイルの削減につながっています。
ただ自動化だけでは対応できない範囲もあったりします。例えば新人の育成やチームマネジメントです。こういった作業はカリキュラムを整えたり、チームメンバの評価制度を可視化したりシステム化することで地道に削減していく必要があります。
それらに加えて、環境構築や、監査対応、作業承認など、他にもトイルとして削減可能なものはたくさんあります。
基本的にトイルは一度対応すれば完了ではなく、環境や世の中の変化に応じて新たに発生したり変化していくものです。
そのため、常に身の回りの作業を省みて効率化できそうな部分はどんどん変えていく。SREにはそういったマインドを持って仕事を進めていくことが求められます。
ちなみにひとつ勘違いしてはいけないのが、単に自動化できそうなものを片っ端から自動化していくのはNGです。その作業をトイルと認識して自動化に取り組む前には、かならずその作業が繰り返し発生するもので、自動化によってSREの稼働の効率化につながるのかを確認してください。
総括
以上がSREのざっくりとした全体像です。これまで説明した内容はSREというプラクティスのほんの表層に過ぎません。実際にSREに取り組んでみると分かりますが、プロジェクトの事情やチームメンバのスキルによってSREのアプローチの方法は千差万別です。「SREってこう言われているからこうしなきゃ」という考えに囚われず、「イノベーションと信頼性の両立」を実現するためにはどんなことをすればいいのかといった観点をブラさずに推進していってもらえたらと思います。
最後までお読みいただき、ありがとうございました。