こんにちは!アドプラットフォーム事業部アド・プロダクト部でアルバイトとして働いているHonahukuです。今回は、アド・プロダクト部が運用しているGKEのクラスタに対して HTTP負荷分散用 GKE Ingress
(以下Ingress)を導入した話をしたいと思います。
Ingress導入の背景
アド・プロダクト部で開発している広告配信サーバーが呼び出している別のマイクロサービスにレイテンシ異常が発生したとのアラートが飛んできました。
このサービスは普段のレイテンシが20ms以下程度なのですが、問題発生時は80ms以上まで上昇していました。 これを解決するために以下の調査を行いました。
調査
問題発生前に事業部内でmergeされたmerge requestを確認しました。 MRを洗い出したところ
- SQLクエリの改修
- コードの書き方修正
- etc.
があり、内容を確認し必要に応じてRevertなどを実施しましたが状況は改善されませんでした。
CPU使用率とレイテンシ異常
調査を進めていく中で、リクエスト量とCPU使用率が一致していることがわかりました。
CPU使用率
リクエスト量
また、レイテンシ異常が発生している時もCPU負荷が連動して上がっていました。 どうやらトラフィックが綺麗に分散されておらず、一部のノードのCPU使用率が上がりレイテンシ異常が出ているようです。そこで広告配信サーバーとマイクロサービス間のルーティングを調査しました。
すると、数日前広告配信サーバーにメモリキャッシュを最適化するために導入したSession affinityの影響でマイクロサービスに想定以上の負荷の偏りが発生していることがわかりました。Session affinityを有効にすることで、同じクライアントからのリクエストは同じコンテナに転送されます。ですが、広告配信サーバーとこれが呼び出しているマイクロサービスの間で、HTTPによるTCPコネクションがkeep-aliveによって確立したままになっていました。これにより特定のマイクロサービスPodに負荷が集中しレイテンシ異常が発生していました。
この問題を解決するためにIngressを導入し、L7でロードバランシングすることで対処しました。
GKEのServiceとIngress
今回のプロダクトでは、ユーザーは広告配信サーバーの手前に設置されたGCLB(Google Cloud Load Balancing)へ通信を行い、リクエストは広告配信サーバーへと飛んでいきます。広告配信サーバーはHTTPでマイクロサービスと通信を行います。
また、広告配信サーバーとマイクロサービス間の通信はService(ClusterIP)でのロードバランシング(TCP(L4))が行われており、広告配信サーバーからマイクロサービスに対してKeep-Aliveが行われていました。
今回のレイテンシ異常は、GCLBと広告配信サーバーの間にSession affinityを導入し、広告配信サーバーの特定のノードにアクセスが集中したことが発端です。これにより広告配信サーバーとコネクションを貼っている特定のマイクロサービスPodとの通信が増え、マイクロサービスのCPU使用率とレイテンシが上がりました。 cloud.google.com
問題発生前。Session affinityは導入していない Session affinityを導入した後。広告配信サーバーに対してトラフィックが集中している
内部HTTP(S)負荷分散とIngress
先述の問題を解消するため、内部HTTP(S)負荷分散をするIngressオブジェクトを設定しました。Ingressを設定することでA-B間にロードバランサ(L7,HTTP)が作成されます。これがB宛てのトラフィックを捌いてくれます。 広告配信サーバーからマイクロサービスへのトラフィックをL7LB(Ingress)で受け止めて捌いている
こちらも詳しくはGCPのドキュメントをご覧ください。 cloud.google.com
Ingress導入の手順
内部負荷分散用Ingressを導入するためには、
- (推奨)静的内部IPアドレスの取得
- (必須)プロキシ専用サブネットの作成
- (必須)ファイアウォールルールの作成
を行う必要があります。このうちのひとつ、LB用の プロキシ専用サブネット
を作成する時にサブネット範囲が既存のVPCのサブネットと競合しないように気をつける必要があります。
Ingress導入前と導入後の比較
Ingress導入により最大で90msを超えていたレイテンシ異常が収まり、平均レイテンシも10ms→6ms程度に低下しました! Ingressを導入する前のレイテンシ Ingressを導入した後のレイテンシ Ingress導入前後のPodあたりネットワーク転送量
まとめ
今回は内部HTTP(S)負荷分散用のIngressを導入し、k8s内部のネットワーク負荷分散を行いました。導入から2ヶ月が経過しましたが今でも元気に動いています。
今回のIngress導入にあたり最初から最後までサポートしてくださったインフラつよつよのtakashiさん、同じく学生アルバイトでありながら幅広い知見で支えてくれたtokiさん、そしてアド・プロダクト部の方々、などみなさん本当にありがとうございました!
ピクシブではアルバイト社員を募集しています。PIXIVにエンジニアとして関わってみたい、という方はぜひ以下からの応募をお待ちしてます。