Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
数時間かかる週一リリースを毎日何度も爆速でできるようにするまで / CI/CD Confere...
Search
Takashi Kokubun
September 03, 2021
Programming
21
14k
数時間かかる週一リリースを毎日何度も爆速でできるようにするまで / CI/CD Conference 2021
CI/CD Conference 2021
Takashi Kokubun
September 03, 2021
Tweet
Share
More Decks by Takashi Kokubun
See All by Takashi Kokubun
YJIT Makes Rails 1.7x faster / RubyKaigi 2024
k0kubun
7
12k
Ruby JIT Hacking Guide / RubyKaigi 2023
k0kubun
2
9.4k
YJIT: Dive into Ruby's JIT compiler written in Rust / Rust.Tokyo 2022
k0kubun
1
2k
Towards Ruby 4 JIT / RubyKaigi 2022
k0kubun
3
11k
Optimizing Production Performance with MRI JIT / RubyConf 2021
k0kubun
1
410
Why Ruby's JIT was slow / RubyKaigi Takeout 2021
k0kubun
3
1.8k
Ruby 3 JIT's roadmap / RubyConf China 2020
k0kubun
0
760
Ruby 3.0 JIT on Rails
k0kubun
9
9.1k
JIT ロードマップ / Ruby 3 さみっと
k0kubun
2
1.4k
Other Decks in Programming
See All in Programming
CSC509 Lecture 13
javiergs
PRO
0
110
ヤプリ新卒SREの オンボーディング
masaki12
0
130
ECS Service Connectのこれまでのアップデートと今後のRoadmapを見てみる
tkikuc
2
250
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
330
3rd party scriptでもReactを使いたい! Preact + Reactのハイブリッド開発
righttouch
PRO
1
600
弊社の「意識チョット低いアーキテクチャ」10選
texmeijin
5
24k
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
110
Creating a Free Video Ad Network on the Edge
mizoguchicoji
0
120
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
430
watsonx.ai Dojo #4 生成AIを使ったアプリ開発、応用編
oniak3ibm
PRO
1
140
CSC509 Lecture 09
javiergs
PRO
0
140
Jakarta EE meets AI
ivargrimstad
0
570
Featured
See All Featured
The Language of Interfaces
destraynor
154
24k
Designing Experiences People Love
moore
138
23k
We Have a Design System, Now What?
morganepeng
50
7.2k
Making the Leap to Tech Lead
cromwellryan
133
8.9k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
329
21k
For a Future-Friendly Web
brad_frost
175
9.4k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Thoughts on Productivity
jonyablonski
67
4.3k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
How STYLIGHT went responsive
nonsquared
95
5.2k
Transcript
数時間かかる週一リリースを 毎日何度も爆速で できるようにするまで @k0kubun / Takashi Kokubun - CI/CD Conference
2021
自己紹介 • GitHub, Twitter: @k0kubun • Treasure Data ◦ API:
プラットフォーム 1年 ◦ SRE: デプロイ 1年 ◦ Backend: ストレージ 2年半
None
今日話すこと • なぜ継続的にリリースすべきなのか • 継続的リリースのために必要なこと ◦ リリースのリスク最小化 ◦ オペレーションの自動化 ◦
デプロイの高速化
なぜ継続的にリリースすべきなのか
背景: 私が入社した時のリリースフロー • リリースマネージャが変更をcherry-pick • リリースノートにオペレーションを手動で記録 ◦ チケットにリリースタグを追加 ◦ stagingデプロイ後、最低2時間、通常1日待つ
◦ 定期実行される結合テスト結果を記録 • 全台sshか30分おき定期実行でのChefによるリリース
何が困るか • 面倒な手動オペレーションが多く、リリース頻度が減る ◦ 結果、毎回のリリースの変更粒度が大きく、問題の切り分けが困難に • リリースマネージャとのコミュニケーションコストが大きい ◦ 時差が分かれてると返事を見るのが1日後とかになる •
様々な依存のあるChef実行はランダムで失敗し、時間もかかる
弊社のデプロイターゲット数 • productionのAutoScalingグループの数: 約600 • 手動作業が多いほど、本質的作業に費やせる時間が減る • サービスが多いほど、それぞれのリリースを安全にする必要性は高 まる
入社時のチームのリリース • 待ち時間: 2〜24時間 • デプロイ時間: 40分 • リリース頻度: 週1回
現在のチームのリリース • 待ち時間: 10分 • デプロイ時間: 5分 • リリース頻度: 週28回とか
(週による)
継続的にリリースできると何が嬉しいのか • 要望に対応するまでの時間が短くなり、顧客満足度が上がる • リリースごとの影響範囲を小さくし、低リスク化しやすい • リリース待ちの変更が少なくなり、調整コストが減る
継続的リリースのために必要なこと • リリースのリスク最小化 • オペレーションの自動化 • デプロイの高速化
リリースのリスク最小化
デザインレビュー • アーキテクチャの改善によりリスクを早いフェーズで減らせる ◦ スケーラブルな設計、障害発生ポイントの最小化 • サービスが満たすべきチェックリストを作り、漏れを防ぐ • システムの本番投入はセキュリティデザインレビュー必須 ◦
顧客情報流出を防ぐため
タイムアウト、リトライ、サーキットブレーカー • タイムアウト: スレッドが1つの処理に占有されるのを避ける • リトライ: 一時的故障のクライアント影響の最小化 ◦ POST的な操作も含め、全てをリトライ可能なように作る •
サーキットブレーカー: 故障時に望ましい挙動を実装する ◦ 旧実装に切り替えたり、低速化している依存先を呼ぶのを避けレイテンシを抑 える、等
結合テスト • 単体テストではサーバーの設定起因のバグをキャッチできない ◦ なので、stagingにデプロイしたサーバーに対してのテストを行なう • この仕組みは元からあったが、結合テストが一切ない機能などで障 害が起きる傾向にある ◦ 最近はQAチームがテスト要件のドキュメントを書き、そのレビューを行なったり
している
SLOとエラーバジェット • コンポーネントごとにService Level Objectiveを設定、監視 ◦ リリース品質に関する顧客満足度のプロキシになる ◦ 具体的な目標があると、その差分のための計画を立てられる ◦
例えばSLOを満たしていない時はリリースを控えてリスクを減らすなど
デプロイとリリースの分離 • デプロイには時間がかかるし、影響範囲の粒度も大きくなる • Feature Flagでコードの変更と機能追加のタイミングを分ける ◦ リスクの高い変更のリリース待ちで他がブロックされなくなる • フラグを増やすとテスト対象が増えることに注意
◦ フラグ同士で依存関係がある状態は避けるか、有効化順序を自動で強制
段階的リリース • 変更の影響範囲が大きい場合、デプロイ対象サーバー数やユー ザー数で範囲を絞り、徐々にリリースする ◦ テスト時に予期していなかった問題や、本番でのみ発生する問題は、リリース 対象を小さくすることでしか制御できない • 壊れるリスクが高い新機能は、それが欲しいユーザーにベータリ リースを検討
リリース告知 • 非互換や、ダウンタイムが必要な変更は事前に通知 ◦ 無告知で非互換をいれると、クライアント側が壊れてそこが障害になることが ある
アラート • SLO違反だけでなく、その要因となるメトリクスの劣化を自動検知 ◦ ユーザーより先に自分たちが問題に気付くことが大事 • サービスのタイプごとにアラートをパターン化し、新サービスでの漏 れをなくす ◦ HTTPサーバーではtoo
many 5xx、too large p99 latencyなど
ダッシュボード • false positiveがあるメトリクスの監視や、障害時のデバッグ用 ◦ 4xxレスポンスが増えても必ずしも障害とは限らないが、リリース時に増えると リリース関連の障害の可能性が高い ◦ モニターが多すぎると監視が大変になるので、リリース時に見るべきものとデ バッグ用のものはセクションを分ける
• 依存しすぎるとモニタリングが属人化していくので、可能な限りア ラート化する
オペレーションの自動化
結合テストの自動実行 • 2時間おきに定期実行される結合テストを、mainブランチのコミット からトリガーするように変更 ◦ 使うリソースにCIのジョブIDをいれるなど、並列実行しても動くように工夫が必 要 • 丸1日結合テストを流し続けてからテスト、をやめた ◦
同じ実装に同じテストを何回も走らせる意義は薄い ◦ 社内検証時間はFeature Flagで社内へ公開する形で、より長く確保する
リリースノート作成と通知の自動化 • コミット履歴からリリース対象チケットのタグ付けを自動化 ◦ パッケージ名にコミットのshaをいれ、diffに含まれるコミットメッセージからチ ケット名を抽出 • コンプライアンス上、各コミットにチケット名が入るのは必須になって いる •
安易に手動のチェックリストを増やさない
サービスクラスタ作成ツール • YAML 1枚書いてSlackにコマンドを書くと、クラスタができる ◦ SlackコマンドはAWS LambdaからPythonでAWS SDK (boto3) を叩く実装
◦ 現在のリソースとYAMLを比較し、必要な差分を作るようになっている ◦ ASG, Launch Config, Lifecycle Hook, ALB, Route53, CodeDeploy • 本番の作業と同じようにオンデマンドクラスタを作れる ◦ 開発中ブランチのテストやベンチマークに便利
Terraform • オンデマンドクラスタに不要なリソースをTerraformで管理 ◦ 主に複数クラスタから共有されるリソース: IAM, Security Group, RDS, DynamoDB,
Kinesis • モニターやアラートの定義も最近ほぼTerraform化された • 入社した時はこのあたりが大体手動管理だった
CodeDeploy • S3にzipを置いて、各インスタンスのagentがpullしてシェルスクリプト がデプロイ ◦ 全台同時sshより安定する ◦ デプロイサーバーにあたる部分がマネージドなので便利 • 元々デプロイに使われていたChefの変わりに、mitamaeやChef
Soloが使われることも
ライフサイクルフック • 以前はインスタンス停止オペレーションは毎回手動だった • ローテーションの手間が増え、オートスケールの妨げになるので自 動化した ◦ ただし、48時間以内に強制停止されるので、それまでに安全に停止できるも のしか使えない
オートスケール • ほぼ全てのサービスがAutoScalingグループを使っているので、 AutoScalingポリシーを設定するだけ ◦ APIベースのはALBのインスタンスあたりリクエスト数が一番安定する ◦ ワーカーベースのものはSQSベース ◦ 両方ハマらない時はCPUベースだが、外部依存の遅さやリトライでブロックし
てる時にスケールアウトされない • キャパシティプランニングの労力やスケーリングの手間が軽減
AMIの自動更新 • SREが全サービス向けのAMIをメンテナンス、結合テストが通ったら リリース • サービスによってはAMIを自動更新し、AutoScalingグループのMax Instance Lifetimeで自動ローテーション • システムライブラリの定期更新のために手動ローテーションすること
がほぼなくなった
デプロイの高速化
なぜデプロイは速くなくてはならないか • モニタリングしなければいけない時間が長くなる • ロールバックにかかる時間が長くなり、障害のインパクトを大きくして しまう
CodeDeploy: Traffic Controlは必要か • ALBのBlock/Allow TrafficがCodeDeployのボトルネックになる • とはいえ、サーバーのgraceful restartは意図しない状態が残りがち なので避ける
• 適当に停止してデプロイ中意図的に502を出すことによって、クライ アントがリトライを適切にしているかのテストになる
CodeDeploy: ALBヘルスチェック/タイムアウト変更 • Block/Allow Trafficにかかる最低時間はヘルスチェックやタイムア ウトの設定で決まる • 必要以上に安全にしようとすると、時間を浪費することになる
CodeDeploy: 同時デプロイ割合の変更 • In-placeデプロイの場合、大きなクラスターでOneAtATimeデプロイ をすると時間がかかる • HalfAtATimeを利用したり、最大25%や10%デプロイするカスタム設 定を用意する
CodeDeploy: Blue-Greenデプロイ • そもそもIn-placeデプロイは途中台数が少なくなったり、サーバーの 状態が使い回しになるのが不便 • Blue-Greenデプロイなら、台数を減らさずデプロイ可能 • AutoScalingグループの名前がデプロイの度に変わることに対応が 必要
今後の課題
結合テストのfalse positive/negative減らし • リリースの待ち時間を最小にするために、以下を両方減らす必要が ある ◦ false positive: 外部依存や外的要因による、actionableでないテスト失敗 ◦
false negative: 書かれていないテストや、関連しているがリリース前確認に含 まれないテスト
インターナルな結合テストの自動実行 • 自動でkickする結合テストは基本CircleCI上で行なっている • ストレージ最適化など、インターネット越しに観測が難しいテストはそ れが使えない ◦ 結合テストシステム自体はあるが、自動でkickしないと手動オペレーション増 加に繋がる
デプロイツールのメンテコスト改善 • 自社デプロイツールのメンテコストが高い ◦ なるべくコミュニティが使うツールに寄せ、自社独自要件のみ実装するようにす る • 議論されたアイデア: ◦ Terraformだけでは達成できない要件も、Terraformを薄くラップして実現
◦ その他OSSのデプロイツール (Spinnakerなど) を利用
AWS Lambda, KDA, EKSへのリリース自動化 • 一番スタンダードなデプロイ方法しか自動化できていない ◦ ほとんどのサービスはEC2 AutoScaling Groupにデプロイしているため
• デプロイ基盤の整備具合から、新サービスのインフラに妥協が入る ことも ◦ CodeDeployにdocker saveしているものは、EKSの方が楽にデプロイでき、リ ソースも柔軟にコントロールできるようになる
まとめ • リリースの安全性確保が第一 • あとは好きに自動化・高速化し、たくさんリリースする ◦ 高速な価値提供だけでなく、リリースの低リスク化にも繋る