Upgrade to Pro — share decks privately, control downloads, hide ads and more …

fourkeys基盤を構築した話

uncle
September 12, 2022

 fourkeys基盤を構築した話

uncle

September 12, 2022
Tweet

Other Decks in Technology

Transcript

  1. fourkeys基盤を構築した話 Kyash TechTalk #4 - Serversideと新しい挑戦 2022-09-12 @uncle__ko

  2. 自己紹介 kohei ouchi(@uncle__ko) 主にお金周りのシステムを作ってた 今はTechチームの生産力向上のために頑 張ってる プライベートでは5歳児のパパとして育児に励 んでる

  3. Agenda • 生産性の可視化 • fourkeys基盤の概要 • デプロイ頻度の計測 • リードタイムの計測 •

    Incident flowの整備 • incidents view • merged_pull_requests view • 変更障害率の計測 • サービス復元時間の計測 • さいごに
  4. 生産性の可視化

  5. そもそもなんで計測するの? KyashのTechチームでは生産力を3倍にするという目標を置いてる Techチームの価値は、最終的に「世の中=ユーザ」に何を届けたかだと思っている 技術的負債の解消、Incident件数の含めて生産力を上げていく 3倍にするにあたり、現状の課題や生産性を可視化する必要があると考えた

  6. そもそもなんで計測するの? 計測するにあたり指標をどうするかを考えfourkeysを採用した 理由は下記 • 定量的に計測できる ◦ 定義を明確にすれば計測できる • 世の中の水準で現状を評価できる ◦

    Google Cloudで実行されているDevOps組織の有効性を評価する にもあるように、それぞれの KeyごとにElite、High、Medium、Lowの4レベルで評価できる • 自動化できる ◦ GitHubやSlack、CircleCI等のAPIを使って自動計測が可能
  7. Google Cloud で実行されている DevOps 組織の有効性を評価する より引用

  8. 計測対象 fourkeysのそれぞれの定義は各社・各Teamで決めてよいとされてるが、Kyashでは DORA(DevOps Research and Assessment)に合わせて下記のように定義してる 指標 概要 デプロイ頻度 組織による正常な本番へのリリース頻度

    変更のリードタイム commitから本番環境稼働までの所要時間 変更障害率 デプロイが原因で本番環境で障害が発生する割合 (%) サービス復元時間 組織が本番環境での障害から回復するのに掛かる時間
  9. 詳しくはBlogを書いてるので、興味があれば読んでみてください https://blog.kyash.co/entry/2022/06/15/170000 そもそもなんで計測するの?

  10. fourkeys基盤の概要

  11. fourkeysの概要 Kyashでは https://github.com/GoogleCloudPlatform/fourkeys をforkして使っている 理由は下記 • GCPのfourkeysが普通にイケてる • GitHub,CircleCi,Tekton,Cloud Build,PagerDutyのイベントハンドリング処理がす

    でに用意されている • Terraform管理されてる • あまり工数を掛けずに自分たちで構築できそうであった
  12. アーキテクチャ

  13. Dashboard

  14. あえてイケてないところをあげるなら • 比較的あたらしいRepoなので小さなバグは多い • チームメンバー含めてPRを5つくらい上げてるけど反応が遅い • 今はShell Scriptとterraform二つ使っているが、terraform側に寄せようとしてい る?ようで、今後大きな変更が入る可能性が高い

  15. デプロイ頻度の計測

  16. デプロイ頻度の計測 デプロイ頻度とは本番環境へリリースした回数 以下の条件に合致するのもをデプロイと判断 • branchがmain or master • job名(GitHubActionsの場合はcheck_run.name、CircleCIの場合はjob.name)に Deploy

    or deployが含まれている
  17. deployments View スキーマはこんな感じ

  18. Query SELECT TIMESTAMP_TRUNC(time_created, DAY) AS day, COUNT(distinct deploy_id) AS deployments

    FROM four_keys.deployments GROUP BY day;
  19. 過去分のイベント 過去分のイベントが取れると生産性が上がりましたと言いやすい トランクベース開発はすでに始まっていたりする 期間を指定すると、その期間内のデプロイをfetchしてBigQueryにinsertするGoの Scriptを作ったりもした

  20. リードタイムの計測

  21. リードタイムの計測 リードタイムとはcommitが本番環境にデプロイされるまでの時間の中央値 Mergeでのpushイベントに、そのpushに含まれるcommit配列がある。それぞれの commitのpushした時刻との 差を取ればいい pushイベントのcommitsとはなにか? • https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-paylo ads#push なので、deployments.changesにあるcommitはmainへのmerge用PRに出てくるdiffのcommitと同じ

  22. changes View スキーマはこんな感じ

  23. SELECT day, IFNULL(ANY_VALUE(med_time_to_change)/60, 0) AS median_time_to_change, # Hours FROM (

    SELECT d.deploy_id, TIMESTAMP_TRUNC(d.time_created, DAY) AS day, PERCENTILE_CONT( # Ignore automated pushes IF(TIMESTAMP_DIFF(d.time_created, c.time_created, MINUTE) > 0, TIMESTAMP_DIFF(d.time_created, c.time_created, MINUTE), NULL), 0.5) # Median OVER (PARTITION BY TIMESTAMP_TRUNC(d.time_created, DAY)) AS med_time_to_change, # Minutes FROM four_keys.deployments d, d.changes LEFT JOIN four_keys.changes c ON changes = c.change_id ) GROUP BY day ORDER BY day; Query
  24. Incident Flowの整備

  25. KyashではwikiツールとしてKibelaを使っている https://kibe.la/ incidentはもともとKibelaにまとめられていた GoogleCloudPlatform/fourkeysはGitHub/GitLab/PagerDutyに対応してる Kibelaもparserさえ作れれば対応自体はできる が、KibelaのAPIでは更新された場合を考えると少し貧弱であったためGitHubのIssue にしたかった Incident Flowの整備

  26. なにをしたのか 有識者を集めてIncidentフローにGitHub Issueをいれたい もしくは自動計測しやすいなにかにしたい旨のMTGを開催 理想はGitHub Issueへの統一だったが、Engineer以外がGitHubのアカウントをもって いないこともありKibelaに概要を、詳細はGitHub Issueにまとめる運用になった

  27. 実際に作ったIssue Template Kyash/incidentというIncident管理用のRepoを作成

  28. 実際に作ったIssue Template

  29. incidents View

  30. incidents View view自体はevents_rowから下記条件で取得 - sourceがgithub - repoがKyash/incident - actionがclose 正規表現で時刻やPRを習得している

  31. incidents View 一応ReOpenの考慮も入れている マイクロサービスごとに集計するためにincident issueにlabelでマイクロサービス名を付 与してもらう運用 from句で下記のようなことをしたり select句でこんなことしたりしてる

  32. incidents View スキーマはこんな感じ

  33. merged_pull_requests View

  34. merged_pull_requests View 本家ではIssueの中に原因となったcommit hashを含めよ的なノリ https://github.com/GoogleCloudPlatform/fourkeys/blob/main/queries/incidents.sql# L25 しかし、IncidentがIssueとKibelaに別れて面倒になってるのにcommit hashまで取って くるのはさすがに... 原因になったPRのリンクだけ貼ってもらいcommit

    hashは別途たどるために本家には ないviewを追加
  35. merged_pull_requests View # Merged Pull Request Table SELECT JSON_EXTRACT_SCALAR(metadata, '$.pull_request.html_url')

    AS url, PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%SZ',JSON_EXTRACT_SCALAR(metadata, '$.pull_request.created_at')) AS time_created, PARSE_TIMESTAMP('%Y-%m-%dT%H:%M:%SZ',JSON_EXTRACT_SCALAR(metadata, '$.pull_request.merged_at')) AS time_merged, JSON_EXTRACT_SCALAR(metadata, '$.pull_request.merge_commit_sha') AS commit_sha, JSON_EXTRACT_SCALAR(metadata, '$.pull_request.base.repo.name') AS repository FROM `four_keys.events_raw` WHERE source = 'github' AND event_type = 'pull_request' AND json_extract_scalar(metadata, '$.pull_request.merged') = 'true' AND json_extract_scalar(metadata, '$.action') = 'closed' GROUP BY 1,2,3,4,5
  36. merged_pull_requests View スキーマはこんな感じ

  37. 変更障害率の計測

  38. 変更障害率の計測 本家はcommit単位で計測している が、現状のKyashには明確なcommit単位の基準が存在しないので人によってブレる可 能性がある そのためKyashではDeploy単位での集計とした (incident数)/(本番へのdeploy数)

  39. Query SELECT TIMESTAMP_TRUNC(d.time_created, DAY) as day, IF(COUNT(DISTINCT d.deploy_id) = 0,

    0, SUM(IF(i.incident_id is NULL, 0, 1)) / COUNT(DISTINCT d.deploy_id)) as change_fail_rate, d.repository as metric, FROM four_keys.deployments d, d.changes LEFT JOIN four_keys.merged_pull_requests m ON changes = m.commit_sha and m.repository = d.repository LEFT JOIN four_keys.incidents i ON i.cause_pr_url = m.url GROUP BY day, d.repository ORDER BY day
  40. サービス復元時間の計測

  41. サービス復元時間の計測 サービス復元時間とは障害の発生時間から収束時間までの中央値 この発生時間から収束時間というのは機械的に計測できる場合もあるが、パターンに よっては難しい場合もある(PRに起因してない障害等) そのため、Incidentレポート用のIssueに人の手で記載してもらう Incident IssueがCloseしたタイミングでIssueをParseして計測する

  42. Query SELECT day, label as metric, daily_med_time_to_restore FROM ( SELECT

    TIMESTAMP_TRUNC(time_created, DAY) AS day, label, #### Median time to resolve PERCENTILE_CONT( TIMESTAMP_DIFF(time_resolved, time_created, HOUR), 0.5) OVER(PARTITION BY TIMESTAMP_TRUNC(time_created, DAY), label ) AS daily_med_time_to_restore, FROM four_keys.incidents, UNNEST(label_names) AS label ) GROUP BY day, label, daily_med_time_to_restore ORDER BY day
  43. さいごに

  44. さいごに やっと生産性を推測ではなく、計測できる状態が作れた GCPのfourkeysはイケてる部分が多いので、forkして自分たちに合うように微調整すれ ば使える 今後はこのfourkeys基盤をもとに分析していくフェーズ TryとしてSprintのはじめに分析する時間を設けるようにしている 可視化することで改めてわかってくることもある 推測ではなく計測した結果で生産性向上のための策を打っていく

  45. ご清聴ありがとうございました