CloudNative Days Tokyo 2022 登壇レポート -Vol.01

登壇:GMOペパボ「Dynamic VM Scheduling in OpenStack」

2022年11月21日(月)~22日(火)に「CloudNative Days Tokyo 2022」がハイブリッド開催されました。
GMOインターネットグループはダイヤモンドスポンサーとして協賛・登壇しました!

今回は、スポンサーセッション「Dynamic VM Scheduling in OpenStack」の書き起こし記事となります。
ぜひご覧ください。

イベント告知:https://developers.gmo.jp/25932/

登壇者(敬称略)

  • GMOペパボ株式会社 技術基盤チーム シニア・プリンシパル
    山下 和彦(@pyama86

「Dynamic VM Scheduling in OpenStack」

はじめに

GMOインターネットグループのスポンサーセッションで、GMOペパボの山下から、「Dynamic VM Scheduling in OpenStack」というテーマでお話しさせていただきます。

最初に軽く自己紹介をいたしますと、私はGMOペパボの技術基盤チームというところで、シニア・プリンシパルとして活動している山下と申します。TwitterやGitHubは「@pyama86」というアカウントでやっております。
個人でずっと面倒を見ているプロダクトがありまして、STNSというものをやっていて、これは何かというと、旧来LDAPとかMySQL、もしくは/etc/passwdなどで管理されていたLinuxのユーザーやグループを、HTTPベースのJSON APIで名前解決できるというプロダクトです。

続いて、我々GMOペパボの紹介を簡単にさせていただきます。
GMOペパボは、ホスティングやハンドメイド、あとはECとか、いろいろな事業領域にわたってサービスを提供している会社です。
もともと画面左上にあります「LOLIPOP!」というレンタルサーバーサービスから始まった会社で、そこから派生してECやハンドメイド、最近だとCMをご覧になった方もいらっしゃるかもしれませんが、「SUZURI」という好きなアイテムを自分の画像で作れるサービスもやっております。

CNDTは私も何度か参加したことがありますが、久しぶりにオフライン開催で最高だなと思っている次第です。
ただ、これは録画で、今日は10月19日水曜日の14:15で、GMOインターネットグループのパートナーの皆さんと一緒に楽しくお喋りしたり、掛け合いしたりしているのは私だけで、なんか恥ずかしい感じで録画をしています。

今日話すことは、最初に我々のインフラ構成をご説明して、そのあとに発生した問題に触れて、それを解決した話と、あと最後にまとめていくのと時間が余れば結婚における大事なこと42選についてもお話ししていこうと思っています。

ペパボのインフラ構成

ペパボのインフラ構成をざっくり紹介します。
我々は大きく4つのインフラがありまして、1つはOpenStack、これはオンプレミスのデータセンターで、物理サーバー80台、その上でVMが1,000台ほど動いています。ここは先ほどご紹介した会社のあらゆるサービスが共用して使っている環境になります。
続いてBaremetalサーバー、これはホスティング系のサービスを中心に、物理サーバーの上へそのままOSをインストールして使っています。
AWSはOpenStackの待機系としてEKSを使っているほか、データストアのRDSとかElasticxxx系とかのサービスを中心に利用しています。
GCPは、一番はBigQuaryでデータ解析に使っていますが、あとは一部の事業においてはOpenStackの待機系としてGKEを使っていたりします。
OpenStackの上でKubarnetesを最近動かしているのが主にあって、OpenStackについては右の図で説明すると、Baremetalサーバーが並んでいて、その上にOpenStackを構築してあげて、そのOpenStackで作成したVMの上にKubarnetesを構築してその上にContainerを置く、という感じです。
Kubarnetesについても自社でエンジンを開発していて、そのエンジンを用いてKubarnetesを構築したりとか、保守運用をしたりとか、そんな感じで運用しています。

CPU Stealに起因した隣人問題

今回の主題となるノイジーネイバー問題についてご紹介していこうと思います。
今回発生したノイジーネイバー問題は、CPU Stealに起因したものでした。これがなぜ起きるかというと、最初に紹介した我々のいくつかのサービス、基本的には国内で事業を展開しておりまして、国内で事業を展開しているとだいたいインターネットサービスはピークタイムが似通ってきます。お昼休みの時間とか帰宅したあとの夕食の時間帯といった感じで、ECサービスやハンドメイドサービスのピークタイムがめちゃめちゃかぶってしまう。我々のサービスはOpenStackの上でインフラを共有しているので、ピークタイムが重なるとどうしてもリソースの奪い合いになってしまう状態があります。

今回、テーマにしているCPU Stealについても、グラフを持ってきています。
グラフを見ると、12時過ぎから1つ目のピークがあって、15時頃、22時頃にもピークがあります。
先ほどから言っているCPU Stealとはなんぞやというと、今回の例でいうと、あるHypervisorの上でVMが2台(VM1、VM2)動いている時に、それぞれのVMが10秒ずつCPUを使いたいとHypervisorに要求を出すとします。この場合、Hypervisorとしては各VMに10秒あげるというスケジューリングをしますが、リソースの状況などで必ずしもVMが10秒使えないというケースが起こります。この場合、VM1が実際には8秒しか使えなかったとすると、差分の2秒がCPU Stealとなります。

CPU Stealが起きると何が発生するかというと、ひとつはサーバー処理能力が低下します。HTTPサーバーであればレイテンシが落ちたり、データベースであってもクエリのレイテンシが落ちるとか、レイテンシが落ちていくとどんどん接続がスタックしていくので、接続数が増加して、場合によってはMax Connectionsに到達してサービスが提供できなくなるということが起こります。
あとは、ロードアベレージをはじめとする各種サーバメトリクスが悪化していきます。

このような、リソースの奪い合いによって発生するCPU Stealに関する問題を解決するための手段が、我々が作った「スーパー☆ライブマイグレーション」です。

スーパー☆ライブマイグレーション

最初に、「スーパー☆ライブマイグレーション」の前提となる、ライブマイグレーションについて簡単に説明します。
ライブマイグレーションとは、簡単にいうとVMを停止することなくHypervisor間を移動させるという技術です。
ここでは、VM1を左から右のHypervisorへ持っていく例を紹介します。

まずライブマイグレーションを実行しようと思うと、共有ディスクがない場合ですが、まず左のHypervisorから右のHypervisorに対してVMのDiskをコピーしてあげます。続いて、Diskのコピーが終わったら、Memoryを転送します。ここでMemoryとDiskの静止点を待ってHypervisorを切り替えていくのですが、静止点を待つのにKVMとかOpenStackとかではパラメーターがあって、どのくらいダウンタイムを許容するかのパラメーターを持っています。こういったパラメーターをチューニングして、許容できるダウンタイムの中で静止点を取って、静止点が取れたら左側のHypervisorから右側のHypervisorにVMが動いて、ネットワークが切り替わって、右のHypervisorでVM1が動き始める、というのがライブマイグレーションです。

では「スーパー☆ライブマイグレーション」は何をするのかというと、ライブマイグレーションをするだけでなく、ある種スケジューリングまでをやってくれるマイグレーションを呼んでいます。

まず、VMのStealの発生を検知したい。Stealが発生してパフォーマンスが低下しているのを検知したらスケジューリングしたいという感じです。
スケジューリングについては、Stealの発生していない、より空きがあるHypervisorにスケジューリングしたい。
そして、ダウンタイムを発生させたくない。先ほどパラメーターをご紹介しましたが、ライブマイグレーションで静止点を取るにあたり、どのくらいダウンタイムを許容するかというパラメーターを先ほどご紹介しました。ということは、ライブマイグレーションは”ライブ”とはいいつつある程度はダウンタイムを許容するような仕組みです。それをなるべく発生させないようにしたい、あとはこれらが自動ですべていい感じに動いて欲しい。

今回我々はRubyで実装しました。
VMのSteal発生検知については、Stealが発生している、かつ、Loadアベレージがしきい値以上という条件で検知するようにしています。これはなぜかというと、Stealが発生していたとしても、処理が詰まっていなければ別に問題ないので、処理が詰まっているかつStealが発生している場合にライブマイグレーションをするようにしています。

続いて、Hypervisorのスケジューリングです。これは、メトリクスのStealがしきい値以下、かつStealがなるべく少ないものを優先して選んで、かつ、同じロールのVMが移転先のHypervisorになるべくいないというのを条件にしています。なぜかというと、同じHypervisorに同じロールのVMがいっぱい乗っていて、Hypervisorが物理障害などで落ちてしまった場合、その上に乗っているVMが全部ダウンすることになるので、なるべく同じロールのVMが、いろんなHypervisorに分散されるようにスケジューリングしています。
最後に同じAZのサーバーであるということも条件にしています。
AZというのはAvailability Zoneの略で、Hypervisorの群のような感じで、例えば5台のHypervisorを「AZ-1」、別の5台のHypervisorを「AZ-2」といった感じで、そのサーバーグループのような感じでAvailability Zoneを組んでいくことができます。これはが例えば別のデータセンターにAZを置いたりするのが主だった使い方になります。

必ず同じAZにスケジューリングするようにしていますが、なぜかというと、図でVM1をどこかにライブマイグレーションしたいという時に、AZ-2にライブマイグレーションしてしまうと、AZ-2が障害になった時にAZ-2がまるっと落ちてしまうので、両系が落ちてしまうことで冗長がとれないことを防ぐ、なるべく同じAZの中でサーバーを動かすということをやっています。

ダウンタイムを発生させないということについては、オーケストレーターで対応しています。我々はオーケストレーターを大きく2つ使っていて、1つはKubernetes、1つはConsulです。Kubernetesについては、いわゆるkubectl drainでpodを追い出してあげて、スケジュールしないようにする。ConsulはKubernetesを使っていないVMのところでサービスディスカバリに使っていまして、Consulについても似たような機能で、consul maint -enableとか、consul maint -disableでクラスタから切り離すことで対応しています。

Kubernetesになじみのない方にご説明しますが、kubectl drainというのは何をするコマンドかというと、node-1に対してkubectl drainと打つと、node-1で動いているpod、containerを別のnode-2に動かすことができます。かつ、以降はコンテンをスケジュールをしない、podをそれ以上置かないということができます。こうすることで、node-1からpodもしくはcontainerを追い出すことができるので、この状態でライブマイグレーションをすることで、基本的にはサービスのダウンを避けることができます。

続いてconsulについては、いわゆるヘルスチェックなどを利用して、サービスをディスカバリしてグルーピングできる機能があります。この例でいくと、node-1からnode-3まであって、かつそれぞれnginx、Webサーバーを置いている状態です。この状態でnginxm
あるいはHTTPのポートがリッスンできるというヘルスチェックを書いてあげると、dig web.service.consul aでAレコードを引くと、3つのAレコードが返ってきます。
こういった形で、名前解決やConsul Templateなどを利用して、構成ファイルを替えたいとかという用途でconsulを使うことが多いです。

この時に、node-3に対してconsul maint -enableを打つと、node-3がメンテナンス状態になるので、この状態でDNSの問い合わせを投げると10.0.0.1と10.0.0.2だけが返ってきて、node-3である10.0.0.3は返ってこないという状態になります。こうなると、クラスタからnode-3が切り離されているので、この状態でnode-3を安全に無停止でマイグレーションできるようになります。

処理系まとめ

ここまでお話しした内容を簡単にまとめると、まずStealの発生かつロードアベレージの上昇で、ライブマイグレーション開始の判定をします。その上で最適な母艦(Hypervisor)を決定して、その状態でVMをクラスタから切り離し、ライブマイグレーションをかけて、再びクラスタへ組み込む。これを一連の流れとしています。

我々が作ったプログラムはOpenStackの上で動くKubernetesで1つのpodとして動いていて、状態を観測して、期待とずれている場合に、VMを動かして、なるべく元に戻してあげるということをやっています。

本当にあった怖い話

こんな形で実装していますが、簡単に行かなかった話もあります。一例を持ってきました。

サービスの方で運用しているSREのメンバーから「『スーパー☆ライブマイグレーション』が動いているけど、レイテンシが改善しない」という話が私のところに飛び込んできました。実際に調査してみると、ネットワークトラフィックのメトリクスで、13時ぐらいから16時前ぐらいまで、明らかにネットワークトラフィックが高くなっている。何をやっているかというと、先ほどライブマイグレーションの動きを紹介した時にDiskを最初にコピーするというお話をしましたが、VMのDiskの中にはサイズが大きいものもあって、500GBとか1TBとかを普通にライブマイグレーションして転送するとトラフィックが輻輳して破滅してしまう。対策しないとフルに帯域を使ってしまうということで、同僚が対策してくれたのは、ライブマイグレーションに使うVLANを分けておいて、そのVLANに対してrate limitを入れることでトラフィックを使い過ぎないようにするという対応をしました。
同僚に感謝です。

まとめ

今日お話ししたことのまとめです。

我々がやったのは、ノイジーネイバー問題を、スケジューラーを書くことで解決しました。

最初はOSSにしようかとも思いましたが、Kubernetes のdescheduleのような感じで抽象度の高い定義はできますが、オーケストレーターの切り離しのところなどが使いやすくない感じになるので、今回はオープンソースにしない形で実装しました。

我々もやってみて分かりましたが、ライブマイグレーションはピークタイムに動くようなこともあるので、いろいろなところで同時多発的に動くとネットワーク帯域を結構食ってしまうことが分かりました。ライブマイグレーションもある程度の頻度で打つ時はrate limitを検討した方がよいと思います。

当日、私は会場にいると思うので、ぜひ食事したり飲みにいったりできるかなと思っています。

お知らせ

最後にお知らせです。

我々GMOインターネットグループのテックイベントを計画しております。
GMO Developers Dayということで12/6、12/7に開催します。会場は渋谷フクラスの16階と、あとはオンラインのイベントとなります。

GMOインターネットグループは、我々の会社だけでもいろいろな領域においてサービスを提供していますが、グループだと金融や仮想通貨、あとはペイメントなど非常に広い事業領域をやっています。それぞれの事業領域のスペシャリストを集めてトークイベントをしたいと思っていますので、ぜひご都合の付く方はご参加いただければと思います。

以上で私のセッションは終わりですが、我々はいま非常に採用に力を入れております。鹿児島、東京、福岡でいろいろ採用しております。せひGMOペパボで働いてみたいという方がいらっしゃいましたら、ご応募いただければ幸いです。

採用ページ:https://recruit.pepabo.com/

本日はご清聴いただきありがとうございました。

アーカイブ映像

映像はアーカイブ公開しておりますので、
まだ見ていない方、もう一度見たい方は 是非この機会にご視聴ください!

ブログの著者欄

デベロッパーリレーションズチーム

GMOインターネットグループ株式会社

イベント活動やSNSを通じ、開発者向けにGMOインターネットグループの製品・サービス情報を発信中

採用情報

関連記事

KEYWORD

採用情報

SNS FOLLOW

GMOインターネットグループのSNSをフォローして最新情報をチェック