CLOSE

ヤフー/ゼットラボのステートフルアプリケーションへの挑戦(全2記事)

Kubernetesでステートフルアプリケーションを動かす ヤフーにおけるCaaSを利用した実用例

KubeFest Tokyo 2020は Kubernetesを利用している人、これから導入したい人が新しいことを学んだり、ネットワーキングすることを狙いとして開催するワンデイのオンラインイベントです。ヤフー/ゼットラボの技術者が、Kubernetesでステートフルアプリケーションを動かす知見を語ります。後半はCaaSを利用したステートフルアプリケーションの事例について。前回の記事はこちら

CaaSを利用したステートフルアプリケーションの事例

坂下幸徳氏(以下、坂下):では次にヤフーの飯田より、CaaSを利用したステートフルアプリケーションの事例を紹介してもらいます。では飯田さんよろしくお願いします。

飯田諒氏(以下、飯田):では後半パートということで、ヤフー株式会社の飯田よりステートフルアプリケーションの導入事例について紹介したいと思います。

まず簡単に自己紹介です。飯田と言いまして、2015年にヤフーに新卒で入社しました。経歴としては広告やニュース記事向けの内製検索エンジンの開発や運用を経験して、2018年から広告配信プラットフォームの開発運用を行なっています。Kubernetesの利用歴は広告配信プラットフォームの業務に携わってからで、およそ1年半くらいです。

先ほど前半パートでも紹介があったと思いますが、本日自分がお話したい内容としては、ディスプレイ広告へのCaaS導入事例の紹介と、そのCaaS移行について苦労した点と課題があったので、そちらについて紹介できればと思っています。

広告配信システムの仕組み

まず簡単にディスプレイ広告について紹介させてください。ディスプレイ広告、YDNと呼ばれているものですが、設定されたユーザー数に対して広告が配信可能なサービスです。画像やテキストや動画といったようなさまざまな形式でYahoo! JAPANのコンテンツページをはじめとした提携サイトのコンテンツページに配信できるサービスとなっています。

このようなサービスを裏で支えている広告配信システムの概要について説明します。主に2つの側面がありまして、1つは広告主が広告に関するデータを入稿する入稿システム、それからユーザーが広告配信されるコンテンツページを閲覧したときに広告を引き当てるクライアント側があります。

そして真ん中に広告検索システムがありまして、このリクエストに対してマッチングを行うといった仕組みになっています。

このような広告配信システムの検索システムでは、リクエストに応じて最適な広告を高速なレスポンスで返却するという要件が要求されます。そこで我々が開発運用しているシステムでは、現在、検索エンジンVespaというものを利用して、このような要件を実現しています。Vespaについてはのちほどもう少し紹介するので、ここではそういったものを使っているんだということを知ってもらえれば大丈夫です。

広告検索システムの課題

こういった広告検索システムを運用していますが、現行はbaremetal、物理機とVMで稼働しておりまして、次のような課題点がありました。

1点はマシンリソースをうまく使えていないという問題です。こちらに関して言うと、ライブテストなどに使うテスト環境を別に用意しておりまして、物理機ということもありますので余分にリソースを確保しておくという状態が必要になっています。

もう1つはサーバー故障時の運用が面倒というところです。サーバーに故障があったときにサービスアウトから筐体調査、サービスインまでの手間がけっこうかかっていました。それなりのサーバー規模で運用しているので、こちらのコストもけっこう高い状態となっています。

もう1点としては、リリースに時間がかかるというところで、こちらは最初の話にも関連しますが、ほかの環境もメンテナンスし続けなければならないので、リリース全体にかかる時間がけっこうかかってしまっているというところがありました。

検索エンジンVespaをCaaSで動かす

こういった背景もありまして、今回、検索システム部分、Vespaを使っている部分にCaaSを導入しようということになりました。今回の移行の概要としましては、広告の配信システムで利用している検索エンジンVespaの部分をCaaSで動かすというふうに捉えていただければと思っています。

これまで何度かVespaと説明してきましたが、Vespaを初めて聞く方もいると思いますので、Vespaについて簡単に紹介させてください。VespaはOSSで公開されている検索エンジンで、2017年9月にOath社が公開しています。Yahoo! JAPANでもほかのサービスでもいくつか利用実績がある検索エンジンです。

機能、特徴としては、スケーラブルで大規模なデータを高速で処理できる、多様なランキング機能などもあります。もっと特徴があるのですが、今回はスペースの都合などで全部書けないので気になる方はぜひ調べてみていただけると嬉しいです。

Vespaのすべてについて詳細な説明はちょっと時間の都合もあってできないのですが、今回はステートフルアプリケーションということもあるので、データをどのように管理しているかという点に着目してもう少し説明します。

まずVespaを構成する要素の1つですが、Vespaサーバーというものがあります。実際のドキュメントではNodeと表現されていますが、今回はわかりやすさの都合上サーバーと表現しています。

こちらのVespaサーバーが分散してデータを……検索エンジンではドキュメントと呼ぶことが多いのでドキュメントと言いますが、ドキュメントを分散して管理しているという感じです。そしてVespaサーバーの集合をVespaクラスタとして構成しておりまして、このVespaクラスタ全体でドキュメントの分散管理を行っているという感じです。

またVespaのもう1つの特徴としては、ドキュメントを分散管理する際にドキュメントの集合をbucketという1つのかたまりにして、そちらを動的にVespaサーバーに配置して分散処理を実現しているという点もあります。

この図で言いますと、今回、冗長性2の例を示していますので、同一bucketが2つあって動的に2つのサーバーに分散しているというイメージをもっていただければと思います。

ステートフルアプリケーションをKubernetesで管理運用するシステム構成

Vespaのデータ管理の説明は以上です。次からはこういったデータ管理をしているステートフルアプリケーションをどのようにしてKubernetesで管理運用しているかというシステム構成について説明していきたいと思います。

こちらは周辺のコンポーネントを含めた全体図です。まず開発メンバー、サービス側がアプリケーション、システムの中心となるVespaクラスタをKubernetesにデプロイしています。今回はステートフルアプリケーションのため外部のストレージを利用するようになっています。

そしてアラート検知やメトリクス監視ではPrometheus、Alertmanager、Grafanaを利用しています。ここで開発側は基本的にメトリクスの追加や監視ルールなどの設定変更を行うのみとなっていて、こちらは前半パートでも紹介があったと思いますが、Prometheus、Alertmanager、Grafana自体はAddon-managerが提供してくれているので、こういったことが実現できているという感じです。

もう1つの特徴としては、ログ管理プラットフォームを使っておりまして、アプリケーションログなどをログ管理プラットフォームからログ検索できるような仕組みにもなっています。ログ管理プラットフォーム自体の基盤作りはCaaSを含めた社内のプラットフォームのチームが実現しています。

ざっと全体像を説明しましたが、もう少しVespaクラスタの部分について詳細を説明します。こちらは先ほどの図を拡大したもので、今回はステートフルアプリケーションということもありまして、ステートフルセットを使って、1Vespaサーバー:1Podになるような構成を取っています。

そして1Vespaサーバーが1つのPersistent Volumeに紐付くという構成です。StorageClassに関しても、再登場になりますがAddon-managerで提供されるため、サービス側はどのようなストレージの種類やプロビジョナーを利用するかといった点はほとんど意識する必要はありません。

またもう1つこちらで説明しておきたいこととして、運用しているVespaサーバーの数があります。現在は、30Vespaサーバーで1Vespaクラスタとした構成を取っています。

こちらのVespaサーバーの数については、検索するPodや更新するPod、ドキュメントのデータ件数とか、そういったところに応じて決めていくものなんですが、Kubernetesを利用したことによって柔軟に変更できるようになったのも便利な点かなというふうに考えています。

システムの運用体制

ここで一旦システムの概要の説明は以上としまして、ここからは、こういったシステムをどのようにして運用しているかという体制について紹介します。

Kubernetes側で言いますとCaaS管理者と利用者が関わってくるんですが、CaaS管理者のほうがKubernetesクラスタの構築運用をメインでやってくれます。クラスタの構築から払い出しまでをしてくれて、Kubernetesの古いバージョンのメンテナンスなども実施してくれます。

ほかにもたくさんの作業を実施していただいていますが、今回はスペースの都合上ピックアップしています。

利用者側としてはNodeのスケールイン/スケールアウト、アプリケーションのデプロイが主な作業となります。

ストレージ側の話になりますと、基本的にストレージの構築から運用まではストレージ管理者のチームがおりまして、ストレージ自体の管理は、利用者があまり意識しなくてよい体制となっています。

やる作業としてはPersistent Volumeの作成・運用程度になっているという感じで、非常にアプリケーションの開発に集中しやすい運用体制になっていると思っています。そして3者の相談支援ということでゼットラボ社が居るという感じです。

CaaS移行で苦労した点

Caas移行したシステムまわりの話は以上です。ここからCaaS移行で苦労した点、出てきた課題点について紹介したいと思います。

まず1点目がストレージ関連の問題です。こちらに関しては2つピックアップしました。まず1点目に出てきた課題点として、Node側とストレージ側のボリューム上のデータ削除が同時に行われず非同期に行われるといった課題に直面しました。これによって、Node側とストレージ側でディスク使用量に差が生じるという問題が発生しました。

現在はStorageClassにmount:discardのオプションを設定することで、ストレージ側の削除がほぼ同期で行われるようになっておりまして、問題自体は解決しています。先ほどVespaクラスタのサーバー台数でも説明しましたが、それなりの負荷をかける場合に起きやすい問題だと考えています。

また1点の注意点としましては、こちらはthin provisioningをストレージの方式として取っている場合に起きうる問題ということは注意していただければと思います。

続いてもう1つのストレージ関連の問題です。今回はそれなりの規模のアプリケーションを稼働させることになったため、IOPSがボトルネックになるという問題点がありました。こちらに関しての対応策としては、ディスクの性能自体を向上させるというのももちろんあるのですが、今回我々の取ったもう1つの対応策としては、ストレージプールの分割を対応策として実施しています。1Kubernetesクラスタに1ストレージプールの構成をとって負荷を軽減するという対応を取りました。

続いてデータをロストしないための設計という点について紹介させてください。ローリングアップデートが行われるため、Node・Podが消えることを考慮した設計・実装が必要になります。ストレージを使ってはいますが、例えば下のここの図にあります通り、更新Aというのがあったときにきちんとそれを同期せずにやると、同一ドキュメントに更新A'という更新がきたときに更新Aが上書きされるといった問題が起きました。

今回の我々の対応策としては、preStop Hookを使って更新データの同期処理をしっかり行うことで問題を解決しています。こちらはアプリケーションに応じて異なる点もあると思いますので、利用するアプリケーションに応じてグレースフルに終了するということが、ステートフルではより大事になるかなと思います。

最後にデバッグが困難という課題がありました。こちらに関してはローリングアップデートでNodeが再作成されるため、Nodeが保持する情報が消失するという問題です。そのため後々調査しやすいようにNodeの情報もログ管理プラットフォームに連携するという対応策を取っています。それ以外にもいろいろなメトリクスを監視できるようにしておくと、調査しやすいのでいいという話です。

まとめ

以上で発表は終わりとなります。ディスプレイ広告「YDN」の検索エンジンをCaaS移行したシステムの概要を紹介しました。ステートフルアプリケーションのCaaS移行は苦労する点は多いですが、乗り越えれば明るい未来が待っているというところで、がんばっていければと思っています。

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

質疑応答

司会者:発表ありがとうございました。では質問タイムに入っていきたいと思います。「自動アップデートのときにリグレッションテストはどのようにされていますか?」という質問が来ています。

坂下幸徳氏(以下、坂下):ではこれは坂下から回答します。ゼットラボではアドオンマネージャーで入れているコンポーネントをアップデートする際、我々はCI/CDでE2Eのテストを動かすようにしています。そのE2Eのテスト、例えばストレージ回りですとストレージのコンフォーマンステストを利用しています。

ストレージのコンフォーマンステストはKubernetesのCSIのドライバーの人たちがテストできるようにと、ボリュームの割り当てから実際のデータの書き込み、あとはスナップショットテストまで行うような、Kubernetesのコミュニティが用意しているものがありますので、これを我々はE2Eで流し、動作確認を行っています。

司会者:はい。Twitterでけっこうみんな気になっていましたが、「Kubernetes as a Serviceは、なぜ"K"ではなくて"C"なんですか?」。

坂下:これは社内でもいろいろ、"C"で書いたり"K"で書いたり登壇で分かれているのがあります。あまり気にしないでください。

司会者:「Container as a Service」の略で"C"?

坂下:Container as a Serviceと言うかKubernetes as a Serviceと言うかで、そもそも表記が変わることがあります。

司会者:質問が来ました。「CI/CDにはどのようなツールを使用しているのでしょうか?」。

坂下:CI/CDは、我々はかなり頻繁に変わっています。現時点で利用しているのはGitHub ActionsとArgoCDの2つで、我々はCI/CDを組んでいます。

飯田:アプリケーション側としては社内でGitHubを使っているのと、あとはScrewdriverというCI/CDツールを使っています。

司会者:ありがとうございます。ではそろそろいい時間なので、これで終了したいと思います。発表ありがとうございました。

坂下:ありがとうございました。

飯田:ありがとうございました。

続きを読むには会員登録
(無料)が必要です。

会員登録していただくと、すべての記事が制限なく閲覧でき、
著者フォローや記事の保存機能など、便利な機能がご利用いただけます。

無料会員登録

会員の方はこちら

関連タグ:

この記事のスピーカー

同じログの記事

コミュニティ情報

Brand Topics

Brand Topics

  • 今までとこれからで、エンジニアに求められる「スキル」の違い AI時代のエンジニアの未来と生存戦略のカギとは

人気の記事

新着イベント

ログミーBusinessに
記事掲載しませんか?

イベント・インタビュー・対談 etc.

“編集しない編集”で、
スピーカーの「意図をそのまま」お届け!