発表内容と自己紹介

相良幸範氏(以下、相良):では「KubeVirtを使ったIaaS基盤構築」という題で、ヤフーの相良が発表します。まず、本日の発表についてです。KubeVirtという技術でヤフーのIaaS基盤を実現するとどうなるかを評価する機会があり、そこで技術調査と設計を行いました。まだ基盤自体は構築の途中で運用はできていないのと、検討期間が6ヶ月とIaaS基盤を検討するにはそもそも短すぎて、詰められていない箇所もあります。

そういった事情はありつつ、検討の中でいくつか知見を得られたので、本日はKubeVirtの紹介とシステム設計のポイントなどをお話ししたいと思います。

内容に入る前に自己紹介です。私は相良といいます。ヤフーに入社したのは1年半ほど前で、最近はKubernetes基盤の設計や、OSの性能解析の仕事を実施しています。前職はSIの会社で、主に研究開発やシステム設計を実施していました。最初の時期からOpenStackを触っていて、通信キャリア向けの大規模なOpenStack基盤を設計したりしていました。

本日、このようなアジェンダでお話ししたいと思います。KubeVirtの内容に入っていく前に、まずIaaS基盤が必要な背景やKubeVirtプロジェクトのお話をします。そのあとKubernetesがどうやってVMを起動する仕組みになっているのかお話しして、最後にシステム設計をやってみて感じたポイントなどをお話ししようと思います。

IaaSが必要な背景

最初にIaaSが必要な背景や、KubeVirtプロジェクトの紹介をします。IaaSが必要な背景について、コンテナに移行できるなら移行するのがベストですが、それができないシステムも残り続けます。技術的な話では、そもそもシステムで利用するミドルがコンテナネイティブでないとか、大規模なシステムなどでは、特殊な要件をクリアするためにカーネルパラメーターの設定が必要などの話もあると思います。

また、そもそもビジネス上の理由で、移行のリソースの捻出が難しい話もあったりすると思います。ほかにはCaasやPaaSなどの下の層で、ベアメタル、物理を直接使わないケースでIaaSが必要になったりします。

ということで、数は減っていきますが、IaaSが必要な場面も残り続けます。そこで、発展著しいKubernetesでVMを管理できたらというのが、今回のモチベーションです。

OpenStackエンジニアから見たKubernetesの利点

IaaSの領域ですが、OpenStackが代表的なソフトだと思っています。自己紹介でも話しましたが、私はOpenStackを長い間利用してシステムを設計したり、OpenStack自体の開発も一部携わっています。OpenStackエンジニアから見たKubernetesの利点について、まずお話ししてみようと思います。

最初のポイントは、Kubernetesの特徴でよく話に上がるReconciliation Loopの仕組みです。etcdに格納された状態に収束していくのは、とてもシンプルな仕組みのように思います。

OpenStackでは管理DBとメッセージキューを使ってコンポーネント間の連携を行っています。新しいバージョンほど発生しづらくはなっていると思いますが、管理DBの値と実際の環境のリソースの利用状況がズレているなどの経験をしたことがあります。おそらく高負荷な状況でVM起動などが失敗してしまい、ロールバックの処理を実施しようとしたものの、それ自体も失敗したケースなのかと思っています。

それに比べると、etcdが常に真だというアーキテクチャはシンプルで、仕組みとしてトラブルが起こりづらい優れた設計だと思います。

2点目に拡張性を書いています。1点目の特徴と重なる点もあると思いますが、CRDとカスタムコントローラで本体のコア機能と同様の仕組みで自由に拡張できる点は、シンプルで強力だと思います。

また、APIの入り口のAdmissionコントローラの箇所で、リクエストの細かい制御ができる点も優れていると思います。複雑な環境向けにシステムを設計すると、ユーザーからのAPIリクエストで、必ず値が含まれていることを保証したいようなケースも出てきます。この場合にwebhookを使い、Kubernetes本体のコードに手を入れることなくAPIリクエストをもれなく制御できる点は、よくできた仕組みだなと思います。

3点目に、Kubernetesコミュニティのエコシステムの恩恵を受けられる話を書いています。OpenStackは2010年に開発がスタートして、10年、11年ほど経過した今では機能は成熟したものの、開発者がだいぶ減ってしまった状況です。最新の「Wallaby」のリリースの統計をスライドのリンクで見れますが、機能のレビューは5割弱がRed Hatとなっていて、コミュニティ色がだいぶ薄まってしまった感じです。ディストリビュータの製品開発や、サポートに依存する傾向が強くなってきていると感じています。

また、年2回程度ある大型の世界的なコミュニティのイベントも、ピーク時は7,000~8,000人が参加していましたが、今では1,500~2,000人ぐらいになってきています。一方で、KubeConは1万2,000人ほどの規模があると聞いています。こういった状況で、OpenStackのコミュニティは昔ほどの勢いはなくなってしまい、インフラ領域の新しい機能開発はKubernetes向けに行われることが多くなってきているのかなと思います。

KubernetesとOpenStackの得意領域の違い

先のページでKubernetesの利点をお話ししました。ちょっと別の観点からも見ようと思っていて、それぞれのソフトの得意領域の違いも話したいと思います。

Kubernetesはアプリケーションサービスを効率的に提供するための機能が手厚い印象があります。例えば、ServiceやDeploymentなどは独自の切り口だと思います。アプリに近いという意味で、トップダウンな仕組みになっている感じがします。

一方で、OpenStackはインフラリソースを抽象化して提供することに、早い段階からフォーカスを当てていました。そのためモノへの対応関係が強く、ボトムアップな印象をもっています。

あと違いとしては、マルチテナントも最初から考慮されていたりします。KubernetesのコントロールプレーンでIaaSを検討していく際に、この違いがつらいポイントになりそうだなと思っています。

KubeVirtのソフトウェアと利用状況

ここまで、IaaSやOpenStack、Kubernetesの一般的なお話をしました。ここからはKubeVirtについてお話ししたいと思います。

まずはKubeVirtのソフトウェアの紹介をしたいと思います。KubeVirtを一言でいうと、Kubernetes上にインストールするクラスタアドオンです。CRDとカスタムコントローラで構成されていて、Podと同じノードでVMを起動する仕組みになっています。あとで詳しく話しますが、OpenStackと同じように、libvirtとKVMでVMを起動する仕組みになっています。

バージョンについては最新が0.42で、まだ1.0に到達していないのが1つポイントかと思います。機能的には最新のlibvirtやQEMUに対応しています。ユーザーマニュアルを見るとわかりますが、VM管理に必要となる、けっこう高度な機能も対応できているかなという感じです。

KubeVirtの利用状況についてもお話ししようと思います。最初の2点ですが、ここ1年で商用サポートを得られる製品の1機能として利用されるようになってきています。また、oVirt、製品版Red Hat Enterprise Virtualization(RHEV)という、KVMとOpenStackの間ぐらいの管理機能を提供する、VMware ESXの位置に相当するようなプロダクトがありますが、そのプロジェクトもKubeVirtに移行パスを用意していく記載があったりします。ここから、VM運用に求められる細かい管理機能も、今後KubeVirtに提供されていくのではないかと期待しています。

あとは、VNF・CNF基盤としての期待という部分で、細かい部分は省略しますが、継続的なリソース投下を期待できる点もあったりします。

一番下の利用事例で、KubeVirtを使っている企業を並べています。この中では、Goldman Sachsが3万7,000ハイパーバイザー上の22万台のVMをKubeVirtに移行していく話があったりします。こういった感じで、大きな事例も出てきてはいるものの、まだ利用事例としては数えるほどの状況です。

IaaS基盤で重要となる設計の観点とKubeVirtでの実現方法

ここまででIaaSのお話とKubeVirtのプロジェクトの紹介をしてきました。ここからは、KubeVirtの仕組みをお話ししようと思います。IaaS基盤で重要となる設計の観点と、それぞれのKubeVirtでの実現方法を表にまとめてみました。

最初に書いていますが、全体的にKubernetesコントロールプレーンの仕組みをうまく活用するような設計になっています。

コンピュート、VMのスケジューリングはPodのものをそのまま活用しています。VM機能の仕組みは次のスライドで紹介します。イメージに関しては、CDIという仕組みがKubeVirtのサブプロジェクトで開発されていて、PVにVMのイメージを流し込むような仕組みになっています。また、ネットワークはCNIとインテグレーションされています。ただ、CNIはホストのネットワークとPodまでしか接続を行わないので、VMにそのネットワークをつなぎこむための独自の仕組みもあります。

ストレージはCSIとインテグレーションされています。PVの中に仮想ディスクのファイルを置くような仕組みとなっていて、ブロックデバイスをそのまま使うようなRawボリュームの対応はこれからのようです。VM初期化に関しては、パブクラと同じcloud-initの仕組みとなっています。cloud-configのデータが書かれたボリュームを接続することで、cloud-initに情報を渡しています。次のスライドでは、水色の「コンピュート」部分のVM起動の仕組みを細かく見ていきます。

VM起動の仕組み

では、VM起動の仕組みを見ていこうと思います。図の左側に書いてあるように、KubeVirtをインストールすると、virt-apiやvirt-controllerというコンポーネントがコントロールプレーンのノードに用意されます。また、Workerノード上にはDaemonSetで動作する、virt-handlerというコンポーネントが用意されます。

ユーザーはVirtualMachineInstanceというリソースを作成することでVMを起動できます。virt-apiやvirt-controllerのコンポーネントがこれらのリクエストを受けつけて、スケジューラーで適切なノードが選択され、ノード上で動作するvirt-handlerがVMに対応するPodを用意します。

Podの中ではvirt-launcherというコンテナが動作して、VMにCNIが用意するネットワークをつなぎ込んだり、libvirtdにVM起動の命令を発行したりと、KubernetesとVMの仲介をやってくれます。あとはlibvirtdが内部でQEMUを呼び出して、QEMUがホストのデバイスにアクセスしてVMを作成する感じになっています。

VirtualMachineInstanceについて

先ほどのスライドで出てきた、VMを作成するためのVirtualMachineInstanceというリソースについても紹介します。さまざま指定できるものはありますが、最初のケースでスライドに書いてあるような内容を書く必要があります。

下から見ていくとわかりやすいと思います。まず、VMで使用するディスクボリュームの定義を書いてあげる必要があります。ここでは起動ディスクのボリュームと、cloud-initの情報を流し込むためのボリュームを用意しています。

次に、真ん中にあるようにボリュームをアタッチする定義を記載します。この例は最初のケースなのでそこまで複雑ではない感じもしますが、記載量がちょっと多いのが特徴です。kubectl runのように、マニフェストを生成してくれる機能もまだない状況です。そのためPodと比べて複雑で、記憶を頼りに書くのもちょっとつらい印象を受けます。

(次回につづく)