本記事は、22卒1年目の成長シリーズ 2日目の記事です。
こんにちは、株式会社CAM SRE Team の岡(@mugiokax)です。
新卒1年目の SRE がこの1年間でどのような課題に直面し、どう解決していったかについて紹介します。
「株式会社CAM SRE Team」について
弊社はスタートアップに特化した IU の中でも特にメディア運営・コンテンツ制作事業に注力しています。
CAグループの子会社の中でも最も歴史が長く、2000年の創業からエンタメコンテンツ、ビジネスバラエティメディア、ライフスタイルメディアを主軸に、現在30以上のプロダクトを展開しています。
それらプロダクトの運用が SRE Team の業務の1つになっています。
SRE Team のチーム構成はマネージャー1人、プレイヤー3人となっており、少人数で複数プロダクトを運用しています。
直面した課題
先述したように弊社には複数のプロダクトが存在し、ファンビジネスが主戦場となっているため「チケット先行販売」、「限定グッズ先着販売」などのイベントによる高トラフィックが定期的に発生します。
下記は、通常時100rps ほどのだったサービスへのリクエスト数がイベントにより 100 倍以上に跳ねている様子になります。
このような性能要件の高いプロダクト開発を行うために、独自の負荷試験環境の構築も行いましたが、負荷試験では想定していなかったリクエスト数になった場合に、サーバーが過負荷になってしまうという課題がありました。
Envoy Global rate limiting
サーバーを過負荷状態にさせない・過負荷状態から回復させるために、rate limit 機能を Envoy の Global rate limiting を用いて実装しました。
rate limit を実施する際に、HTTP level の情報(ヘッダー、パス)を元に rate limit 対象を選定するために、HTTP level rate limit filter を使用しています。
実装例
弊社では GKE 上に、Istio を導入しサービスメッシュを実現しているため、rate limit service と Envoy Filter を用いて実装しています。
各種セットアップ方法については 公式ドキュメント をご参照ください。
ここからは、実際に導入している rate limit の設定を紹介します。
:authority 擬似ヘッダーによる rate limit 対象の選定
istio-proxy を経由する通信には :authority、:path など envoy によって追加、変更される擬似ヘッダーが存在します。擬似ヘッダーはコロンで 始まります。
:authority ヘッダーは HTTP/1 Host ヘッダーと同義です。Host ヘッダーでも rate limit 対象の選定は可能ですが、:authority ヘッダーを使用する理由は2点あります。
- HTTP/2 通信の場合、Host ヘッダではなく :authority ヘッダーを用いた通信を推奨しています。そのためHTTP/2 通信の場合、Host ヘッダーが存在しない可能性があります。
Clients that generate HTTP/2 requests directly SHOULD use the ":authority" pseudo-header field instead of the Host header field.
- Envoy が内部的に HTTP/1 Host ヘッダーを表現するために、HTTP/2 :authority ヘッダーを使用しているため、Host ヘッダーに対して match などを実施する場合は :authority ヘッダーの使用を推奨しています( 参照 )。
Internally, Envoy always uses the HTTP/2 :authority header to represent the HTTP/1 Host header. Thus, if attempting to match on Host, match on :authority instead.
下記が istio-ingressgateway で TLS の通信が終端され
- https://hoge.example.com/ratelimit?query=1 に 100rps
- https://hoge.example.com/ratelimit?query=2 に 200rps
の rate limit を設定する際のコード例です。
istio-ingressgateway の route(hoge.example.com:443 用)に rate limit 設定を追加する Envoy Filter
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: istio-ingressgateway-rate-limit-hoge
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: VIRTUAL_HOST
match:
context: GATEWAY
routeConfiguration:
vhost:
name: "hoge.example.com:443"
patch:
operation: MERGE
value:
rate_limits:
- actions:
- header_value_match:
descriptor_value: request-to-hoge
headers:
- name: ":authority"
exact_match: "hoge.example.com"
- request_headers:
header_name: ":path"
descriptor_key: "PATH"
rate limit service の設定
apiVersion: v1
kind: ConfigMap
metadata:
name: global-rate-limit-istio-ingressgateway
namespace: istio-system
data:
config.yaml: |
domain: global-rate-limit-istio-ingressgateway
descriptors:
- key: header_match
value: "request-to-hoge"
descriptors:
- key: PATH
value: "/ratelimit?query=1"
rate_limit:
unit: second
requests_per_unit: 100
- key: PATH
value: "/ratelimit?query=2"
rate_limit:
unit: second
requests_per_unit: 200
導入効果
上記は通常時 P95 のレイテンシが 30ms ほどのワークロードが想定以上の高負荷により 8000ms ほどになってしまった際、rate limit を設定することで過負荷状態からの回復が行えた様子です。
弊社では異なるプロダクトを安定して同居させるため、 プラットフォーム戦略をとっています。
さまざまなプロダクトが1つの Kuberneets クラスターで動作し、マイクロサービスアーキテクチャをとっているため、1つのプロダクトが過負荷になってしまった際、他のプロダクトにも影響が出てしまう場合がありました。
Envoy Global rate limiting を用いることで、過負荷になってしまった際の影響範囲を極小化でき、過負荷からの回復もすることができるようになりました。
まとめ
今回はマルチテナント・マイクロサービス環境の Kubernetes クラスター上で、過負荷時の影響範囲の極小化・回復を Envoy Global rate limiting を用いて実現する方法を紹介しました。
今後の展望としては、「Kubernetes 環境の運用高度化を進め Developer Experience を向上させる」を1つのミッションとして取り組んでいるため、プロダクトの可用性向上はもちろんのこと、開発サイクルレベルでの最適化や運用の高度化なども行なっていきます。
一緒に働くエンジニアを募集しています
25卒以降の学生を対象としたプレエントリー受付中。
選考情報などをいち早く受け取れます。
24卒も一部職種は現在も受け付けておりますので、こちらよりご確認ください。
また、社会人向け新卒採用制度「Re:Career」や、キャリア採用の求人一覧、カジュアル面談もございます。
インターンシップも!
サイバーエージェントでは、現在インターンシップの募集をしております。
どのインターンシップも共通している特徴は4つ!
- 社員が全力
- 社員との接点が多い
- 視座の高い仲間に出会える
- 交通費支給・宿泊場所手配
内容も数日で終わるものから2週間のもの、職種や難易度もさまざまなので、
自分に合うものを見つけてぜひエントリーをお待ちしております。