月間800億PVを支えるIaaS基盤の舞台裏

奥村司氏(以下、奥村):それでは「月間800億PVを支えるIaaS基盤の舞台裏」と題しまして、ヤフー株式会社の奥村と奥野が発表いたします。よろしくお願いいたします。

それではまずスピーカー紹介です。私が奥村と申します。2016年にSIerからヤフー株式会社に入社いたしまして、現在はクラウドプラットフォーム本部でプライベートクラウドチームのリーダーをしています。

本日のアジェンダです。まずはYahoo! JAPANとそのIaaS環境について概要をお話しいたします。そのあと本セッションの主題にもなっているIaaS基盤の舞台裏について、構築編と運用編、その2つに分けてお話ししたいと思います。今日は技術的に踏み込んだ内容ではなくて、どちらかといえば、大規模IaaS環境の運用者の考え方であったり、ポリシーといった部分の共有がメインになると思います。

Yahoo! JAPANのIaaS環境とそれをよく利用するサービス

それではまずYahoo! JAPANについて簡単に紹介させてください。こちらがヤフーが提供しているポータルのトップページです。現在はデバイスも多様化していますので、多くのサービスと同様、スマホからのアクセスが大半を占める状況になっています。ヤフー株式会社はメディア、金融、コマースなど幅広いサービスを展開している国内有数のコンテンツサービスプロバイダとなっています。

それではこれらのサービスが利用しているヤフーのIaaS環境について簡単に紹介いたします。ヤフーでは現在9万台の物理サーバーを保有しており、そのうちの約2万台がIaaSのハイパーバイザーとして使用されています。

その2万台のハイパーバイザー上では、およそ17万台のVMが起動していて、これらの環境はすべてオンプレで運用されており、先ほど例に挙げたようなサービスもみんなこのIaaSを通してサービスされています。

IaaSの詳細についてもう少し説明します。IaaSの基盤にはOpenStackを利用していて、2013年から現在のIaaS環境が使われています。ハイパーバイザーには基本的にKVMを使っていますが、ごく一部の環境ではVMwareを併用しています。OpenStackクラスタの数は200以上存在していて、クラスタ数がとても多いのがヤフーのIaaSの大きな特徴です。

先ほどもお話ししましたとおり、ハイパーバイザーの数が2万台以上存在しますので、そのラックの数は1,000以上に及びます。

OpenStackのバージョンはGrizzlyからRockyまでの12世代のバージョンの中の7世代を実際に利用しています。このグラフはOpenStackのバージョンごとのクラスタ数を示したもので、右に行くほど新しいとなっているんですが、最近のバージョンほどクラスタ数が多いのが読み取れると思います。これは運用開始から時が経つにつれて構築クラスタ数が増加していったことを示しています。

では実際にどのようなサービスがIaaS環境を多く利用しているかを利用リソース量基準で並べてみました。この中にはみなさんがよくご存知のサービスも多く含まれていると思います。この中で社内のプラットフォームとして利用されているサービスを赤くしてみました。

プロダクションのサービスと社内のプラットフォームの利用量を比較すると、実は社内のプラットフォームで利用されている量のほうが多いことがわかります。コンシューマ向けサービスそのものよりも、そのバックエンドのほうに大量のリソースが使われているという事実が、こういうことからも見えてきます。

クラスタ数が多い理由

ここでもう一度IaaS環境の規模を振り返ってみたいと思います。どういった理由で200以上のクラスタが構築されたのかという部分についてもう少しお話をしていきます。ヤフーのクラスタ数が多い理由は、全社向けに公開されている通常のIaaS環境以外にも、特定の環境ですとか特定のユーザー向けのIaaSクラスタが数多く存在するためです。

プロダクション用の環境と開発用の環境ではクラスタを分けていたりですとか、広告やメールとかそういった大規模なユーザーには専用のクラスタを作って提供していたり、あとはCaaSやPaaS、DBaaSといったプラットフォームのIaaS環境としても専用のクラスタを作っています。こういった理由が積み重なった結果、200以上のクラスタが作られました。

このパイチャートは実際に全社に公開しているIaaSクラスタと、それ以外の特殊な環境などの限定されたユーザー向けにのみ提供しているクラスタとの比率を表しています。この外周に赤色が付いた左上の部分だけが全社に公開しているクラスタで、実は全体の4分の1しかありません。それ以外はすべて特定のユーザーや特定のサービスにのみ公開しているクラスタです。

ハイパーバイザーの選び方

それではセッションの主題にもなっています、大規模IaaS基盤の舞台裏についてお話をしていきます。構築編と運用編に分けて、まずは構築編からお話しします。

まずクラスタ構築の流れを簡単にまとめてみました。上から順に下に向かって構築が進められていくような感じですね。設計して見積、そして設置してセットアップ、デプロイ、テストと。「まぁそうだよね」という流れになっているかなと思います。

まずはじめにヤフーのIaaSはどんな観点でハイパーバイザーを選んでいるのかということについて紹介いたします。一般的にIaaSに使うハイパーバイザーを買うときに重視するだろうなという性能を並べてみました。これらの性能は我々のIaaS環境でも当然重要視されます。特に1ラック当たりの電力量がシビアな環境が多いため、電力あたりの性能は非常に重視される部分です。

そして一度の発注で最大で数千台のサーバーを買うこともありますので、目標とする納期に納入可能かどうかに影響する調達性という部分も非常に重要になってきます。これら今挙げたような性能も当然重要なのですが、実は長い目で見ると別の視点も表れてきます。それがなるべくハイパーバイザーの種類を増やさないということですね。発注ごとにスペックを変えてしまうとパーツの種類が増えてしまって、現地のNOCの運用負荷が増大してしまいます。

例えば筐体交換1つを取ってもそれだけパーツの数や種類が多いと、在庫管理の工数が膨れ上がってしまいます。2万台のハイパーバイザーがあったとしても10種類しかなければ運用は可能ですが、2万台のハイパーバイザーでなおかつ100種類もあると運用がとても難しくなるのはなんとなく想像できるかなと思います。

ハイパーバイザーの種類が増えてしまうと、IaaSのリソース管理も複雑化します。ハイパーバイザーごとにスペックがバラバラですと、例えばこのクラスタはメモリ250GB、こちらのクラスタはメモリ500GBと、そういうふうにばらけてしまうと、クラスタのトータルでのリソース管理が複雑化してしまいます。

それからユーザーも起動するVMがどんなスペックのハイパーバイザーで起動するのかもわからなくなってしまうので、性能のいいハイパーバイザーを厳選してしまうといういわゆるインスタンスガチャの引き金になってしまいます。ですのでなるべくハイパーバイザーの種類を減らすために、ハイパーバイザーのスペックはCPU世代ごとで固定しています。

ここに例で挙げていますが、例えばCascadeLake世代であれば、買うハイパーバイザーのスペックは基本的に1種類のみというかたちになっています。ヤフーではCPUアーキテクチャの見直しを年1回行っていますので、ハイパーバイザーのスペック変更も結果的に年1回行うというかたちになっています。

ハイパーバイザーのリソース割り当てポリシー

それでは続いて、ハイパーバイザーのリソースをどのようなポリシーでVMに割り当てるかという部分についてお話をしていきます。

これは具体的には仮想化にあたってCPUをVMに占有させるのか、共有させるのかといった部分ですとか、VMのディスクは共有のストレージに置くのか、それともローカルのディスクに置くのかといった設計を指しています。VMの性能とクラスタ全体のキャパシティ、コスト効率に直結する非常に重要な設計部分になってきます。

CPUリソース

では実際にヤフーのIaaSではこの部分をどういった設計にしているのかという話をしていきます。まずはCPUリソースです。CPUに関しては結論から言いますと、実CPUスレッド数の3倍まで、VMのCPUに割り当てています。仮にハイパーバイザーに搭載されたCPUスレッド数が100ならば、そのハイパーバイザーの上で動作するVMのCPU数の合計は300まで許可するという設定になります。

これはおそらくプライベートクラウドを運用されている方から見ますとけっこう攻めた値に見えるかもしれませんが、この数字で問題になるということは、実際はほとんどありません。問題になる場合の対処については後述いたします。

ではこのハイパーバイザーの実CPUスレッド数の3倍までVMに割り当てているのはどういう状態なのかを簡単にご説明いたします。このように各VMからは自分には十分なCPUが割り当てられているように見えますが、実際に存在する実CPUスレッド数はVMに割り当てたCPUに対して3分の1しか存在しないということになります。

ですので仮にすべてのVMが自身に割り当てられたCPUをすべて同時に使用してしまうと、VM間でCPUスレッドの取り合いが発生してしまって本来のCPU数に期待する性能を発揮できないという状況が発生してしまいます。こういった状況は非常に困るというユースケースも当然出てきますので、そういったユーザーにはサービス専用のハイパーバイザーを用意しています。

AWSで言うところのDedicated Hostsをイメージしていただけるとわかりやすいと思います。特に定常的にCPU使用率が高く、ノイジーネイバーの原因となるようなユーザーやVMには優先的に専用のVM、ハイパーバイザーを割り当てるなどしています。

サービス専用ハイパーバイザーの中には静的にVMとハイパーバイザーのCPUをpinningした環境を用意していて、主に広告配信システムなど非常にシビアなレイテンシーを求められるようなサービスにこういった設定を使用しています。

静的pinningは、文字どおりハイパーバイザー側の実CPUスレッドに対してVMのvCPUを静的に1対1で割り当てています。こうすることで集約率は当然大きく劣るんですけれども、CPUレスポンスは大きく向上させることができまして、通常のVM環境ではとても食えないようなワークロードも収容できるようになります。

ディスクリソース

CPUのお話はここまでで、次はディスクリソースのお話です。ヤフーのIaaSは、VMのデータは基本的にローカルディスク保存となっています。データを格納しているローカルディスクはRAID構成を組んでおらず、ディスクが1個データロストすれば当然VMのデータもロストするという環境になっています。

このVMのデータをローカルディスクに保存しているのはどういう状態かをまず図で表してみました。まずハイパーバイザーの大きな一番外の枠があって、その中にディスクが2本搭載されています。SATAのSSDとNVMeのSSDです。SATAが低速でそれと比較してNVMeは遥かに高速であるとご認識ください。

ハイパーバイザーのOSですね。これについては低速なSATAのSSD側に格納しています。VMのデータは高速なNVMeのほうに格納しています。VMから見たルートディスクは、この図のvdaというところですが、これは実際にはqcow2のイメージファイルとしてハイパーバイザーのNVMe SSDに格納されています。

先ほども申し上げましたが、このVMのデータを格納するディスクはRAID構成になっておらず、原則NVMe SSDの1本構成になっています。ですのでVMのデータロストはそれなりの頻度で発生はしてしまうんですけれども、高いコストを払って冗長化するよりも利用者がVMのデータロストが発生しても問題ないアーキテクチャを採用するほうが建設的であるという考えに基づいてこういった構成になっています。

ですのでヤフーのIaaS利用ユーザーは、VMのデータロストを前提とした分散アーキテクチャの採用が不可欠となっています。

ローカルディスクを使う理由

ではこういったデータロストのリスクを抱えてまで、なぜローカルディスクを使うのかについてお話をしていきたいと思います。ローカルディスクは共有ストレージと比較して大きく3つのメリットがございます。それが速い、安い、うまいというものです。

まず1点目の速いという部分ですけれど、これは単純にNVMe SSDが速いということです。ここに書いてある性能は、PCI gen3のエンタープライズ向けSSDのだいたいの性能を記載していますが、秒間5から6ギガバイトのシーケンシャルリード、同じくシーケンシャルリードで10万IOPSという性能を達成できています。

これによって多数のVMを収容しても1VMあたりの性能劣化を大きく抑えることができますので、CPUリソースの項目で話したような集約率を高める設定が、よりこのNVMe SSDの性能により活きてくるということになります。

次は安いという部分です。これは単純にNVMe SSDが最近は安価になってきているということです。ストレージ製品と比較してもハイパーバイザー全台にNVMe SSDを搭載するほうが安価で済むのも採用の大きな理由になっています。

最後のうまいの部分ですね。これは優れた運用性を指しています。ディスクIOのトラフィックがネットワークを流れることはないので、ネットワークをサービスのトラフィックに集中できます。あとは共有ストレージという単一障害点となり得るようなコンポーネントが存在しませんので、Failure domainを局所化できるというメリットもあります。

まとめますと、このような表になります。IaaS環境で共有ストレージを使用しますと、ライブマイグレーションという強力な武器を使うことができるようになりますが、ディスクIOの性能とかコスト、収容効率の観点ではローカルディスクに分があります。ディスクリソースの冒頭でも話した通り、ヤフーの利用ユーザーは分散構成が基本になっています。

ですのでデータロストが発生しても問題がなく、ライブマイグレーションなどでVMを過剰に守る必要もありません。ですのでこういった部分もローカルディスクを選択する決め手になっています。

ディスクについて1点補足すると、すべてのデータがロストしてもいいというわけではなく、中にはやはり絶対に消えては困るというデータも存在しています。そういったデータもIaaSで保存可能なようにヤフーではCinderを介してアプライアンスストレージですとかSDSにそういったデータを格納しています。

メモリとNICの割り当て

CPUとディスク以外のリソースについても軽く触れておきます。まずはメモリです。ヤフーのIaaSでは基本的にはVMのOSはLinuxを想定していますので、バッファやキャッシュで100パーセント埋まることを考えると、メモリの割り当て倍率は必然的に1固定になってきます。

NICに関しては当然VMに対してはハイパーバイザー上のNICを共用するかたちになっていますが、ハイパーバイザー本体にはNICは冗長して搭載されています。これは主にNICのつながる先のToR、ラック内の集約スイッチですね。これを冗長化しなければならないためです。

仮にToRを冗長化せずにそれがダウンしてしまった場合、ヤフーの集約率が高いということもあって、最大で900VMが同時にダウンしてしまうということが発生してしまいます。

まとめますと、ヤフーのIaaSは効率化を重視してポリシーが設計されていますが、ワークロードに応じて性能を重視した環境も用意しています。どのようなワークロードであっても問題なく使用できるように多種多様な環境を柔軟に用意しています。

デプロイが速い理由

それでは次です。デプロイのお話をしていきたいと思います。デプロイはどこまで自動化されているか。そして1クラスタの構築にかかる実際の工数についてちょっとお話をしていきます。まず結論から言いますが、OSインストールが完了した状態からであればIaaSクラスタの構築はスムーズに行けば2日もあれば完了することが多いです。ハイパーバイザーを含めずOpenStackのコントローラ構築に限れば数十分で構築は完了します。

なぜこんなに速いのかですが、その理由はヤフーのIaaSのOpenStackコントローラがOpenStack on Kubernetesの構成を取っているためです。OpenStackの各コントローラコンポーネントをコンテナ化して起用してKubernetesにオーケストレーションさせることで大幅な構築負荷の軽減を実現しています。

ヤフーのOpenStackの構成定義の情報は基本的に1クラスタあたり1ファイルのYAMLで管理されています。まずクラスタ構築者はこのYAMLファイルを作成します。デプロイ時にはこの定義に応じた設定でKubernetes上でコンテナが起動されることになります。基本的にヤフーのIaaSクラスタの構成管理はこの1枚のYAMLで完結していて、このファイルが唯一の構成管理のマスタ情報になっています。

構成管理と実際にデプロイされている設定が違うのはけっこうありがちだと思うんですが、実際にデプロイされる設定と構成管理が1つになっていますので、そういったことはヤフーのIaaSでは原理的に発生しないようになっています。

ハイパーバイザーでのトラブル

OpenStackコントローラの構築は速く終わりますが、このデプロイ以外で実際に実は時間がかかる部分がありまして、それがハイパーバイザーでトラブルがあった場合です。そのときは構築が長期化することもあります。では実際にハイパーバイザーでどんなトラブルがあったかについて簡単に紹介いたします。

上から行きます。最初にあったのが、納品された500台のサーバーがあって、実はその全台BIOS設定を誤っていましたと。けっこうターボブーストの設定とかが漏れていることが多くて、もちろん発注時に「こういうBIOS設定で納入してください」とお願いしているんですけれども、どうしても違った設定で入ってくるサーバーもあります。

このときは500台すべてがBIOS設定が誤った状態で入ってきて、作業者がもうIPMIで全台接続してBIOS設定をやり直したということがありました。

それから納品されたハイパーバイザーにディスクが搭載されていないということも多々ありました。特にNVMeのSSDとかは世界的に供給が足りていなかったときもあって、「NVMeのSSDだけ納品が遅れます」と。でもそもそもNVMe SSDがないとこちらは構築ができないので、その分だけ構築がストップしてしまったということがありました。

その他で納品時の構成間違い系は多々発生しています。OSインストールしたカーネル版数でNICのドライバが動かないですね。ファームウェアですとか制御チップの問題で、リブート後にサーバーが一切うんともすんとも言わなくなることも起きたこともありました。

テストの自動化

最後です。テストについてお話しします。ヤフーのIaaSのテストはどのように行われるかについてです。構築も自動化していますが、もちろんテストも自動化されています。ヤフーのIaaSではテストの自動化にはfabricを使用しています。

どうやってfabricを使ってテストをしているかというと、fabricの実行サーバーからテストコードをクラスタ内のハイパーバイザー全台に撒いて、ハイパーバイザー全台でテストコードを実行して、その出力結果をバリデートしているというかたちです。

ハイパーバイザー以外にもOpenStack本体へもテストを行っています。OpenStackの機能テストもこのfabricで一緒にやってしまっていて、テストコードでOpenStackのAPIを叩いてその結果をバリデートしているという流れになります。

実際にどのようなテストを行っていますかと、厳密なテスト項目は、ここにずらっと書いていますが、ヤフーのIaaSでは、こういった項目を合計100項目以上、行っています。なぜそんなにたくさんの項目のテストをしているのかというと、テスト項目は、実際は構築の失敗の歴史とイコールになっていまして、これまでの構築で失敗したことは必ずテスト項目として反映しています。

こういった失敗は基本的に財産として捉えていますので、これを正しく活かすということをやっています。「目視でチェックする」とか「ダブルチェックする」というのはけっこう失敗したあとの対処として言われることもありますが、そういった無意味なことはなるべくヤフーのIaaSでは避けようということでがんばっています。

手動でのテスト

ですが実際には理想と現実が存在していて、すべてが自動化できているわけではないということです。これはIaaSチームのドキュメントで、ちょっと見せられない部分はモザイクかけていますが、貼り付けています。

「クラスタリリース前チェック項目」というドキュメントがありまして、PDF化すると10ページにも及ぶ、先ほど並べたような何を確認しているかをリスト化したものですが、「手法」というカラムがあって、そこにはどうやってテストするかという方法が記載されていますが、テスト項目によっては「手動」という文字が実はちらちら見えています。

これはどういうことかと言うと、100項目以上を自動化していても手動での確認となってしまう項目はどうしても存在しているということです。連携するシステムや確認観点が非常に多いIaaSでは自動化が難しいというテストもどうしても出てきます。自動化させるべきテストと人が確認すべきテストの住み分けの判断が非常に重要になってくるかなと思います。

構築編はここまでになります。次からは運用編として奥野からしゃべっていただきます。では奥野さんお願いします。

(後半へつづく)