みんなでつくる Production Readiness

こんにちは。SRE の @chaspy です。

以前、Production Readiness Checklist に関する記事を書きました。

quipper.hatenablog.com

Production Readiness Checklist の運用開始から1年ほどの月日が経ち、27ものサービスが無事 Production へ出ていきました。

サービスを安心して Production へリリースするために役立っている Production Readiness Checklist ですが、Product Team がこの Check List を進める上でいくつか課題がありました。

本記事では、Production Readiness Checklist 運用開始後に、どのような改善が行われてきたのか、その内容と方法を説明します。また、1年以上の運用を通して、Production Readiness Checklist がどのような役割を果たしているかをあらためて述べます。

課題と改善内容

Issue Template の commit log を見ると、69 commit ありました。以下、大きな変更を見ていきます。

Design Doc の分離

当初は Architecture Diagram の作成と、SRE によるレビューが Production Readiness Checklist の中にありました。しかし、Production Readiness Checklist は "Production へリリースする前" に終わればいいというものなので、リリース直前に Architecture Review することがしばしばありました。もし アーキテクチャ上の問題があっても、そのような状況では改善することが難しく、Review の意味をなしていませんでした。

そこで Architecture Diagram や Stakeholder といった、サービスの検討初期に決められるものを Design Doc として分離しました。原則、(プロトタイピングを除いて)コードを書きはじめる前に作成される位置付けです。

以下が実際の Design Doc Template です。社内ドキュメントへの Link を除いたこと以外は実際に使用いるものです。

---
name: Design Doc
about: Design Doc
title: Design Doc for {NEW SERVICE}
labels: Design Doc, SRE Review
assignees: ''

---

# Design Doc for {NEW SERVICE}
See Document for background and purpose.

<!---
If you finished all the checks, ask SRE to review.
Of course, if you have any questions while doing it, always ask @sre-jp or @sre-global.

Besides, you are free to add any categories/items.
You can also skip any unnecessary categories/items. In that case, please put the reason.
-->

- [ ] Add a new line to the spreadsheet for this service to measure the time of the processes

## Motivation
Please write your motivation to create new service. It's better to include the following:
  - Background
  - What problems will be solved?
  - What value will it provide?

Please refer relevant link if any.

## Stakeholders

- [ ] Stakeholders
  - [ ] Developers: # Set @github-group as Technical responsibility of the service
  - [ ] Product Manager: # Set @github-group or individual user as Business responsibility of the service
  - [ ] Reliability:
    - [ ] Both @quipper/sre
    - [ ] JP @quipper/sre-jp
    - [ ] PH/ID/MX @quipper/sre-global
  - [ ] End Users: # i.e Students or Teachers. Please describe as much as possible.

## Architecture

- [ ] Create architecture diagram
  - You can use any tool to describe the diagram. There are useful toos (i.e. [Mermaid](https://mermaid-js.github.io/mermaid-live-editor/) and [PlantUML](https://www.planttext.com/))
  - Please determine the traffic pattern.
    - Who is end user?
    - What components does the service depend on?
  - Include it as component in the diagram
    - Application(Pod)
    - Datastore(RDS/Elasticsearch)
    - Reverse Proxy
    - CDN
    - Jenkins
    - Object Storage(S3)
- [ ] Note for the Architecture
  - Please explain why you chose this architecture
- [ ] Architecture review with SRE
  - Comments from SRE

## Service Level

Please see the Document

<!---
Here is example SLI/SLO. You can update the below example.
-->


Category | SLI | SLO
-- | -- | --
Example: API Service |   |  
Availability | The proportion of successful requests, as measured from the Reverse Proxy metrics. | 99.9% success
Latency | The proportion of sufficiently fast(defined as < 500 ms) requests, as measured from the Reverse Proxy metrics. | 99% of requests < 500 ms

- Are there additional metrics that need to be measured?: yes/no
  - [ ] Be able to measure it @quipper/sre


If you check all items, you can close the issue. :wink:

Design Doc の作成が負荷とならないように、最小限の項目に絞るように心がけています。

Production Readiness Checklist になかった項目として、Motivation と Service Level があります。

新しいサービスをリリースするということは何らかの解決したい課題があるはずです。それを理解しないまま(例えそれが技術的なレビューだったとしても)正しくレビューすることは難しいと考えています。この説明によって、暗に「潜在的な課題は何だったのか」「どの組織・チームが関わるのか」「どのプロダクトと関係があるのか」「対象のユーザは誰でどの程度の負荷が予想されるのか」といったことが伝わります。これらは後続の Architecture Review や Production Readiness Checklist を行っていく上で有用な情報となるでしょう。

Design Doc に関しては mercari merpay SRE ✕ microservices platform meetup@deeeet さんに Design Doc の実際の内容を見せていただいたことが大きなきっかけとなりました。この場を借りてお礼申し上げます。

Service Level の検討

上記 Design Doc で掲載されているように、Design の段階で Service Level Indicator/Objective(以下 SLI/SLO) を検討しています。

以前は Service Level に関して一切定義も測定もできていませんでしたが、この半年間で SLO の定義を各チームで取り組んできており、そのおかげもあって、新サービス検討時にも自然と Service Level の議論ができるようになってきました。

SLO に関する取り組みは以下の記事をご覧ください。

quipper.hatenablog.com

基本的な SLI に関してはまずここからはじめようという Default の SLO を提案しています。設計段階ではどうしても Production に出してみないとわからない部分があるからです。

このあたりの考えは@deeeet さんの SRE Practices in Mercari Microservices で発表された "SLI specification(what) & implementation(how)" を分離するという考え方を参考にしています。Design Doc 段階では specification を決定し、もしそれに新たな実装が必要であれば、Production への リリースまでに計測可能にするために SRE と協力して行うという意図があります。

決めた SLO は Datadog で管理されており、Datadog SLO の作成と Dashboard への追加を Production Readiness Checklist で行います。

## SLIs/SLOs (Service Level Indicators / Service Level Objectives)

Please see the Document

- [ ] Set SLOs to Datadog
- [ ] Add SLOs widget to DataDog Dashboard

ドキュメントの拡充

この改善を行う期間、たくさんドキュメントの作成・改善を行いました。

Checklist 形式の Template は非常に便利ですが、「なぜその項目が必要なのか」「(詳細な)手順はどうすればいいのか」といった点はカバーできません。

具体的には以下のカテゴリのドキュメントがあり、もともとあったものを分かりやすく改善したり、新規に作成しました。

  • How to add a new service: Kubernetes
    • monorepo で新規サービスを作成するためのガイド
  • How to create RDS
    • Terraform や script で AWS Aurora を作成するためのガイド
  • Environment Variables
    • Configmap あるいは Secret(aws-secret-manager) を用いて環境変数をアプリケーションに設定するためのガイド
  • CPU / Memory allocation
    • Kubernetes における resource requests / limits の設定ポリシー
  • Design Doc
  • Production Readiness Checklist
  • Monitoring
  • Service Level Objective
  • Horizontal Pod Autoscaler

今回話題にしている「Design Doc」「Production Readiness Checklist」そのものについても、なぜ、なんのためにやるのかについて記載されたドキュメントは今までありませんでした。今回新規で作成することで、あらためてやる意義を再確認するとともに、SRE チーム内でどのようにレビューしたら良いか?ということを考えることができました。

ドキュメントは何でも書けばいいというわけではありませんが、誰かがわからないことはきっと他の誰かもわからないので、質問を受けた際には、回答するとともに「ということがどこかに書いているか!」と考え、なければ加筆するよう心がけています。

このあたりは @koudaiii さんの Design Proposal は文化を創る に影響を受けています。この場を借りてお礼申し上げます。

Kubernetes Readiness / Liveness Probe の設定ポリシー

最初は単に「Readiness / Liveness Probe を設定せよ」でしたが、直近は明確にポリシーを指定することにしました。(Kubernetes Readiness / Liveness Probe については Official Document を参照ください)

以下、Production Readiness Checklist から該当部分を抜粋します。

- [ ] Set Readiness Probe

  - ref: [Configure Liveness and Readiness Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
  - Basically Do NOT set Liveness Probe to avoid cascading failure. Use in situations where a restart is the only solution, such as Deadlock. See also: [
LIVENESS PROBES ARE DANGEROUS](https://srcco.de/posts/kubernetes-liveness-probes-are-dangerous.html)
  - Do set Readiness Probe and include the connection if it is necessary for using the application (i.e. Data Store). To avoid cascading failures, do NOT include ALL dependencies. If you are not sure, ask SRE.

原則、Readiness Probe を設定し、Liveness Probe は設定しないことになりました。どちらもカスケード障害を回避するためです。しかしこれらは飽くまで基本方針であり、白黒つけられるものではないので、Developer 自身がこれらの Health Check 機構がどういうものかを理解した上で、対象のサービスや依存先のサービスのことを考慮しながら適切な設定を目指すべきだと考えています。

どのように改善してきたか

さて、上記であげた3点以外でも、細かい文言の修正や、わかりにくい点にコメントで補足するなど、様々な改善を行ってきました。

これらの取り組みはもともと SRE である私が中心に導入、運用を行ってきたものです。しかし、「SRE が Developer にお願いするもの」ではなく、新サービスを作る Developer 自身が「必要だと思うからやる」ものであってほしいと思っています。

そのため、こちらから一方的に押し付けるようにならないよう、実際にこれらのプロセスを体験したチームにインタビューを行い、フィードバックをもらうことにしました。

合計6サービス分(内訳は日本4、フィリピン1、インドネシア1)のインタビューを実施したところ、概ねこれらの存在には肯定的な反応をもらえました。以下、いくつか紹介します。

Positive Point

  • Design Doc
    • Architecture 上のボトルネックになるであろう点が洗い出される
    • 将来発生するかもしれないことを現時点で検討できるので安心できる
    • Architecture や Motivation を明文化して共有できる
    • Production Readiness Checklist と分離した点もよかった
    • チーム内でのサイロ化を和らげることができる、最低でも SRE(チーム外)に共有することができる
  • Production Readiness Checklist
    • 満たしたら安心感を持って Production に出せる
    • 必要最小限の項目になっている点が良い
    • Monitoring / Logging の設定や Resource 量の調整など、やっていく中で学びが多いので1度は経験すると良いと思う
    • Fill in blank / Checklist 方式はとても進めやすい

懸念していた Design Doc / Production Readiness Checklist の内容量も重すぎない範囲で保てているようです。また、やる意義も感じてくれているようで安心しました。

もちろん初見のひとでも簡単にできるかというとそうではないかもしれませんが、過去の Issue を参照しながら、リンクされているドキュメントを参照しながら進めることができているようです。

Improvement Point

  • SRE に Review / Check を依頼するタイミングが不明瞭 -> 明記し、SRE Team 内でも再度運用方針を共有しました
  • Kubernetes Resource requests / limits の設定方針が分からなかった -> 方針をドキュメントに明記しました
  • サービスのルーティングに関する情報がなかったので戸惑った -> 新サービス作成時のドキュメントからルーティングに関するドキュメントへリンクを貼りました
  • Monitoring 設定の流れがあると助かるかもしれない -> Monitoring 全般の考え方や設定方法のドキュメントを書きました
  • Prototype なアプリケーションでもやるべきかどうか迷った -> 基本的にはやる方針で、Service Level を設定しない、低くする、項目を削減するという対応をしていけば良いと説明しました

ここであげた以外にもたくさんの Feedback をもらい、修正できるものはその場で修正してもらったり、逆に Pull Request を送ってもらったりして解消していきました。

おわりに

今回、Production へ新サービスを出す際に取り組んでいる Design Doc と Production Readiness Checklist について、Developer 目線で改善点を検討するとともに、その意義について確認しました。

こういったプロセスは場合によっては「やること」そのものが目的となってしまい、生産性を下げる存在になる危険性を孕んでいると思います。そうならないためにも、実行主体の Developer と SRE で目線を合わせることができた良い機会でした。

今後も Production Readiness のために意義のあるものをいい感じにやっていけるよう、みんなで改善していけたらいいなと思います。

Quipper では世界の果てまで学びを届けたい仲間を募集しています。

おまけ:Production Readiness Checklist の現在

Note: 社内ドキュメントやリポジトリへのリンクは外してあります。実際はもう少し親切です。本物や、これを使った実際の Issue を見たいひとは @chaspy までリプライか DM をください!

---
name: Production Readiness Checklist
about: This checklist is your guide to the best practices for ensuring stability,
  scalability, and reliability of a new service in the production environment.
title: Production Readiness Checklist for {NEW SERVICE}
labels: Production Readiness CheckList, SRE Review
assignees: ''

---

# Production Readiness Checklist for {NEW SERVICE}
See Document for details.

<!---
If you finished all the checks, ask SRE to review.
Of course, if you have any questions while doing it, always ask @sre-jp or @sre-global.

Besides, you are free to add any categories/items.
You can also skip any unnecessary categories/items. In that case, please put the reason.
-->

## Design
- [ ] Design Doc
- [ ] Update `<service name>/microservices/service.yaml` for Service Dependency graph
  - [ ] app1
  - [ ] app2

## Monitoring / Logging

- [ ] Synthetic: Notify a synthetics error (Pingdom)
  - Is it published on internet? yes / no
  - Endpoint: https://foobar.quipper.com/ping
- [ ] Application: Notify an application error(Sentry)
  - Visit [sentry.io](https://sentry.io/organizations/studysapuri) to create a project for your new service.
  - Please note that it is enough to create one or two sentry project per service since the exceptions that are reported to sentry can filter by environment parameter.
    - e.g. `one project for production and another environments`, or `1st one is for production and 2nd one is for another environments`.
  - url:
- [ ] Application Monitoring([NewRelic](https://docs.newrelic.com/docs/agents/manage-apm-agents/installation/install-agent))
  - url:
- [ ] Create datadog dashboard
  - See How to create a new dashboard?
  - url:
- [ ] Set metadata labels of service in monorepo for owners and slack notification.

## Security

- [ ] Setup dependabot
  - Add your service to .dependabot/config.yml

## Compute Resources

- [ ] Access load is predicted: yes / no
  - [ ] comment:
- [ ] Load test
  - result: Please create another gitHub Issue for the testing and link to the url
  - comment: Please decide whether to perform a load test based on the return on investment. If you do not perform a load test, please write the reason for your decision.
- [ ] Set Resource(Memory/CPU) limit/request of pods
  - ref: CPU / Memory allocation

## Others
- [ ] Set Readiness Probe

  - ref: [Configure Liveness and Readiness Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
  - Basically Do NOT set Liveness Probe to avoid cascading failure. Use in situations where a restart is the only solution, such as Deadlock. See also: [
LIVENESS PROBES ARE DANGEROUS](https://srcco.de/posts/kubernetes-liveness-probes-are-dangerous.html)
  - Do set Readiness Probe and include the connection if it is necessary for using the application (i.e. Data Store). To avoid cascading failures, do NOT include ALL dependencies. If you are not sure, ask SRE.
- [ ] Check if database connection does not exceed maximum connection
  - ref: If you use aurora, the default maximum connection is determined by Instance Type [Aurora Postgres](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Managing.html) / [Aurora MySQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Performance.html)
  - If it is not enough, increase the number of connection(`max_connections`) by [Terraform](https://www.terraform.io/docs/providers/aws/r/db_parameter_group.html)

## SLIs/SLOs (Service Level Indicators / Service Level Objectives)

Please see the Document

- [ ] Set SLOs
- [ ] Add SLOs widget to DataDog Dashboard

## Release Cycle

Choose one:

- [ ] Same Weekly Release with sapuri/quipper
- [ ] Individually / Arbitrarily Release

## Release date

`Release` means "End User can access to the app."

- [ ] desired: 20yy-mm-dd
- [ ] finished readiness check: 20yy-mm-dd
- [ ] review from SRE: 20yy-mm-dd
- [ ] actual release: 20yy-mm-dd

If you check all items and release to production, you can close the issue :wink: