2021年9月21日火曜日

WebAssemblyとRustが作るサーバーレスの未来

https://thinkit.co.jp/article/17486
シェアしました。

松下 康之 - Yasuyuki Matsushita
注目を集めるWebAssemblyとRustそしてサーバーレスに結びつく未来を、Cloudflareのエンジニアが解説する。

JavaScriptの登場によって、Webブラウザーはスタティック(静的)なWebページを表示するだけの存在から、より動的なアプリケーションを実行するプラットフォームに進化した。そしてそれをさらに進化させるために登場したのがWebAssemblyだ。WebAssemblyは2015年にMozilla Foundationによって発表され、その後2019年12月にW3Cのレコメンデーションとして採択されたブラウザーで実行されるコードのバイナリーフォーマットの標準だ。

HTML、CSS、そしてJavaScriptに続く進化のための要素の一つとして紹介されるWebAssemblyは、動的型付けのインタープリター言語であるJavaScriptと比較してコードのサイズが小さくなり、実行速度も速くなる利点が強調されがちだ。しかし実際には、もっと大きな変化をもたらす可能性を秘めている。

今回の記事では2019年9月に開催されたFull Stack Festというカンファレンスの動画から「Rust, WebAssembly, and Future of Serverless」と題されたセッションを紹介する。WebAssemblyが単なるバイナリーフォーマットというだけではなく、今後のサーバーレスコンピューティングにつながるものである可能性を探ってみたい。

セッションを行ったのはCloudflareのエンジニア、Steve Klabnik氏

セッションを行ったのはCloudflareのエンジニア、Steve Klabnik氏

Docker創業者がWASMに言及

最初にKlabnik氏は、Solomon Hykes氏(Docker社の創業者兼CTO)による以下のツイートを紹介した。「もしもWebAssemblyとWASIが2008年に存在していたら、Dockerを開発する必要はなかった」

この言葉を理解できる人にとっては、インパクトのあるツイートだ。つまりクラウドネイティブの土台と呼ばれるコンテナ化のきっかけを作ったDockerの開発者が、もしもWASM(WebAssembly)とWASI(WebAssembly System Interface)があの当時にあれば、Dockerを作らなくても良かったというほどにインパクトのあるテクノロジーであるということを意味している。ここで重要なのは「WebAssembly on the server is the future of computing.」という一節だろう。

オリジナルのツイートは以下から確認できる。

また続くツイートではWebAssemblyがDockerをリプレースするのか?という疑問に「そうはならないが、Linux ContainerやWindows Containerと並行してwasm containerが実行される未来がくる。その時にwasmは最も人気のあるコンテナとなるだろう」という予測を返している点も興味深い。つまりHykes氏はコンテナのタイプとしてWebAssemblyが使われる、要するにブラウザーだけではなくサーバーサイドでの実行形態となると考えていることがわかる。

Rust

ではこの謎解きを行うべく、Klabnik氏のセッションを追いかけていこう。最初に紹介したのはRustだ。

Rustの紹介

Rustの紹介

RustはMozilla Foundationが開発をリードするオープンソースのプログラミング言語で、CやC++などと同様にLow Level Languageと位置付けされているが、メモリーに関連する安全性を高めるための多くの工夫がなされている。変数のライフタイムやオーナーシップなどの新しいコンセプトを導入して、極力不用意なメモリーアクセスや操作をさせないように作られており、実行時ではなくコンパイル時にそれらの操作を発見できるように作られていることが特徴だ。

「どうしてメモリー関連の操作を制限するのか」という質問に対する回答として紹介されたのは、Microsoftが発表したソフトウェアの脆弱性に関するレポートだ。これによればMicrosoftが開発したソフトウェアに関する脆弱性の約70%は、メモリー関連の操作、処理に関して起こっていると言う。つまりメモリーの不正アクセスやポインターの操作ミスなどによるバグが非常に多いということがわかる。

MicrosoftのCVEの70%はメモリー関連のバグが由来

MicrosoftのCVEの70%はメモリー関連のバグが由来

このような脆弱性を、言語仕様のレベルで発生させないように設計されたのがRustという言語だ。そのプログラミング言語の特徴を表すイラストも紹介し、鎧を纏った人間が「私が今日のドライバーだ。話している時にはモノを食べないように。喉に詰まらせて死んじゃうよ」というセリフに表されているように、速度を上げようとして不用意なポインター操作などを行うことで、プログラムが誤動作することを暗示している。

Rustを表すイラスト

Rustを表すイラスト

その一例は、次のスライドで見ることができる。ここではある変数に1をプラスする関数(add-one)をmainプログラムの中で使おうとした際にmainの中ではyという変数が初期化されていないことでコンパイラーがエラーを出している。このようにRustは、メモリーアクセス関連には非常に強い縛りが存在することがわかる。

Rustのコンパイラーがエラーを出したサンプル

Rustのコンパイラーがエラーを出したサンプル

WebAssemblyの前身asm.js

次にKlabnik氏はWebAssemblyの前身であるasm.jsを紹介した。asm.jsはC/C++からJavaScriptを生成することで高速なロジックの実行を目指していたものだったが、あくまでもJavaScriptのサブセットでしかなく、目標を達成できなかった。そこで、プラットフォームにネイティブなコードを生成するシステムとして再度、実装を行ったのがWebAssemblyである。

JavaScriptの変数が浮動小数点しかないこと、そこからどうやって整数を取り出すかという仕様に関する説明が続き、Unityを使ってC++で書かれたアプリケーションがJavaScriptに変換されて実行されたデモを例に挙げて、プラグインなどを使わずにasm.jsだけで他の言語のアプリケーションが実行されることを示し、このことのインパクトの大きさを解説した。

Unityで書かれた3Dゲームがブラウザーで実行されるデモ

Unityで書かれた3Dゲームがブラウザーで実行されるデモ

WebAssembly

そしてここからWebAssemblyの解説に移った。

ここからWebAssemblyの説明

ここからWebAssemblyの説明

ここでは実際にRustで書かれたコードを示して、それがどのくらいのサイズに圧縮されるのかを紹介。例として挙げられたのはフィボナッチ数列を求めるコードだが、元のソースコードと比較するとバイナリーフォーマットとなるWebAssemblyの中間コードは、非常にコンパクトにまとめられていることがわかる。

Rustのコードとバイナリーフォーマットの違い

Rustのコードとバイナリーフォーマットの違い

そしてCやC++、RustなどのソースコードからIR(Intermediate Representation、中間コード)を経て、WebAssemblyのバイナリーフォーマットに変換され、その先にあるプラットフォームごとに対応した形で実行されることを紹介した。ここでのポイントはC++やRustで書かれたコードをWebAssemblyというバイナリーに変換するという部分だ。これは、過去に書かれた多くの資産がそのままWebの世界で実行可能になるということだ。

他の言語からWebAssemblyにコンパイルすることで、資産の流用とプラットフォームの違いを吸収

他の言語からWebAssemblyにコンパイルすることで、資産の流用とプラットフォームの違いを吸収

また多くのブラウザーがすでにWebAssemblyに対応していることを紹介。80%を超えるブラウザーでWebAssembly対応が進んでいるという。もちろんスマートフォンやタブレット用のAndroidやiOSにも対応しており、古いIEを除けば対応はほぼ済んでいると思って間違いないだろう。

WebAssemblyのブラウザー対応

WebAssemblyのブラウザー対応

著者
松下 康之 - Yasuyuki Matsushita
フリーランスライター&マーケティングスペシャリスト。DEC、マイクロソフト、アドビ、レノボなどでのマーケティング、ビジネス誌の編集委員などを経てICT関連のトピックを追うライターに。オープンソースとセキュリティが最近の興味の中心。

注目を集めるWebAssemblyとRustそしてサーバーレスに結びつく未来を、Cloudflareのエンジニアが解説する。

RustとWebAssembly

そして次のパートとしてRustとWebAssemblyに関して説明を行い、Mozillaの中ではRustとWebAssemblyのワーキンググループができていることを紹介した。そもそもCやC++といったLow Level Languageにおいて、いかにメモリー関連の安全性を高めるか? というゴールに向かって開発されたRustが、CやC++とともに1st class citizenとして扱われているのは当然のことだ。そして、冒頭で紹介した「WebAssembly on the server is the future of computing」につながる接点が、やっと見えてきたというのが次のトピックだ。

RustとWebAssemblyのコンビネーションでワーキンググループを結成

RustとWebAssemblyのコンビネーションでワーキンググループを結成

ここからサーバーレスにつながる内容に

ここからサーバーレスにつながる内容に

サーバーレス

ここからが、このセッションのタイトルであるサーバーレスにつながる重要なポイントであろう。Webブラウザーの上でさまざまな言語のプログラムが稼働することを目指したWebAssemblyは、必ずしもブラウザーだけで実行されるわけではない。そのためにwasmtimeというランタイムが存在する。これはブラウザーを介さなくてもWebAssemblyのバイナリーが実行されることで、さまざまなプログラミング言語で書かれたプログラムがx86サーバーやARMのプロセッサーが搭載されたIoTデバイスでも実行が可能になるという話につながる。

APIでインフラが抽象化されることによりプラットフォームの進化につながる

APIでインフラが抽象化されることによりプラットフォームの進化につながる

その説明として、クラウドがどのように進化してきたのかをスライドを使って説明した。ここではデータセンターからIaaS、PaaSそしてサーバーレスに進化した際に、APIに注目していることがポイントだ。

つまり自社のデータセンターで稼働する場合は、LinuxなどのOSのAPIを使ってファイルやネットワークなどを使ってアプリケーションが実行される、一方PaaSの場合は、OSではなくそのプラットフォームのAPIとなり、より抽象化が進んだことになる。ここでは、APIが徐々に上のアプリケーションに近いレイヤーに上がってきていることに注意して欲しい。

そしてサーバーレスになった場合には、もはやOSやアプリケーションという外形ではなく、関数や機能という小さなレベルのプロセスがその下のAPIを通じてインフラストラクチャーを利用する形になる。これがAPIに注目した場合のアプリケーションの進化だ。この見方は、少し前であればDockerによるコンテナ化、そして2020年初頭の時点であればKubernetesによる複数のプロセスをAPIから制御する形に相応している。

この図はさまざまな言語の実行形式がDockerで抽象化されていることを示す

この図はさまざまな言語の実行形式がDockerで抽象化されていることを示す

この図をよく見ると、先にKlabnik氏が使ったWebAssemblyの図と相似であることが分かる。

WebAssemblyによるプログラムの実装(再掲)

WebAssemblyによるプログラムの実装(再掲)

つまりDockerがプログラミング言語の違いをコンテナでラップしていることに対し、バイナリーに変換されたRustなどのコードがランタイムを使ってサーバーサイドで実行されることでポータビリティーを獲得することになる。これによって、冒頭で紹介したSolomon Hykes氏の「2008年にWebAssemblyとWASIがあればDockerは必要なかった」という論点が整理されたのではないだろうか。コンテナはLinuxやWindowsなどのOSを区別する必要があるが、WebAssemblyであればその必要はないというわけだ。

WebAssemblyがサーバー側で実行されることでグローバルな展開が可能

WebAssemblyがサーバー側で実行されることでグローバルな展開が可能

WebAssembly System Interface(WASI)

ちなみにWebAssembly System Interface(WASI)とは、ブラウザーレスで実行する際にブラウザーがOSのAPIなどにアクセスしていた部分とのインターフェイスを定義するものだ。WASIはモジュール構造をとっており、WASI-Coreと呼ばれるモジュールがファイルシステムやネットワークなどへのアクセスを受け持ち、その他の追加機能は別モジュールで実装するという形式をとっている。

前のスライドで「グローバルなネットワークを作ることは巨大なサーバーファームを作ることではない」ということを強調したのは、AWSなどの巨大なサーバーファームがなくてもCloudflareの拠点にこのWebAssemblyのサーバー型アプリケーションを実装すれば、グローバルな展開は可能であるということを伝えたかったという意図がある。ちなみにCloudflareのPoP(Point of Presence)は、AWSのリージョン数よりもはるかに多いというのが次のスライドだ。

CloudflareのPoPは世界中に展開されている

CloudflareのPoPは世界中に展開されている

充実するWebAssemblyの周辺環境

そしてブラウザーレスでWebAssemblyのバイナリーを実行するランタイムも、Mozillaが公開しているwasmtimeの他に、Fastlyが開発し、Bytecode Allianceに寄贈されたLucetが存在する。

ちなみにBytecode AllianceはWebAssemblyとWASIをガバナンスするための団体であり、Mozilla、Fastly、Intel、Red Hatなどが参加している。他にもKlabnik氏が所属するCloudflareは、世界中に展開するCloudflareのサーバーにWebAssemblyのアプリケーションを実装するためのツールWorkerや、CLIツールWranglerなどを公開している。

wasmtime以外にもツールは充実し始めている

wasmtime以外にもツールは充実し始めている

最後にまとめとして、RustとWebAssemblyの親和性、WebAssemblyがサーバーレスのプラットフォームになる可能性、さらにARMなどのプロセッサーを使ったエッジでの可能性などを語ってセッションを終えた。

このセッションは、後半のブラウザーを使わずにランタイムを使ってサーバーレスを構築可能であるという部分がかなり駆け足となってしまったのが残念だが、JavaScriptを補完する形でブラウザーでのコンピューティングを拡張したWebAssemblyが、開発環境とCI/CDのためのツールやエンタープライズが求めるセキュリティなどの部分を充実させることで、サーバーレスに向かうというのは可能性としてはありえると思う。

今後は「マイクロサービスなどのユースケースに向けてエコシステムが拡大できるか?」「wasmコンテナの可能性は?」「Rustのランタイムとして市場をリードできるか?」「モニタリングやトレーシングなどのニーズに対応できるか?」という部分に注目が集まるだろう。Rustはデベロッパーからの注目を集めていることもあり、今後の動きに期待したい。

なお、動画は以下から視聴することができる。

動画:Rust, WebAssembly, and the future of Serverless

なおWebAssemblyをブラウザー以外で使うという部分に関しては、以下の動画も参考になる。これは2019年11月にコペンハーゲンで行われたGOTOというカンファンレスで行われたセッションである。セッションを行ったのはMozillaのDan Callahan氏だ。

動画:WebAssembly beyond the Browser

0 コメント:

コメントを投稿