Wasm vs. Docker:高性能で安全、かつ汎用性の高いコンテナ

Docker と WebAssembly (Wasm) は、ソフトウェア開発環境を再構築した 2 つの重要なテクノロジーです。 ここ数年で Wasm の人気が高まるにつれ、Wasm について耳にすることが多くなり、アプリケーション スタックで使用する利点についても耳にしたことがあるかもしれません。 これは、特にテクノロジーが非常に緊密に連携しているため、Wasm と Docker の違いについて考えるきっかけになったかもしれません。

この記事では、これら 2 つのテクノロジを連携させて、アプリケーションをデプロイするための一貫性のある効率的で安全な環境を提供する方法について説明します。 これら2つのツールを組み合わせることで、開発者はコンテナ化されたソフトウェア開発でWebAssemblyのパフォーマンス上の利点を簡単に享受できます。

White text on blue background saying Wasm vs. Docker

WASMとは?

Wasm は、World Wide Web Consortium (W3C) によって管理されているコンパクトなバイナリ命令形式です。 これは、C/C++、C#、JavaScript、Go、Rust など、 40 を超えるプログラミング言語用の移植可能なコンパイル ターゲットです。 言い換えれば、Wasm は、スタックベースの仮想マシンで実行するためにエンコードされたバイトコード形式です。

JavaをJavaバイトコードにコンパイルしてJava仮想マシン(JVM)上で実行し、Java仮想マシン(JVM)でコンパイルしてさまざまなアーキテクチャで実行できるのと同様に、プログラムをWasmバイトコードにコンパイルしてから、Armやx86などの異なるアーキテクチャで実行するようにパッケージ化できるWasmランタイムによって実行できます。

a program can be compiled to Wasm bytecode and then executed by a Wasm runtime, which can be packaged to run on different architectures, such as Arm and x86

Wasm ランタイムとは?

Wasm ランタイムは、移植可能なバイトコードと基盤となるハードウェアアーキテクチャの間のギャップを埋めます。 また、ホスト環境と通信するための API も提供し、JavaScript などの他の言語間の相互運用性を提供します。

大まかに言うと、Wasm ランタイムは 3 つのセマンティックフェーズでバイトコードを実行します。

  1. デコード:モジュールを処理して内部表現に変換する
  2. 検証:デコードされたモジュールが有効かどうかの確認
  3. 実行: 有効なモジュールのインストールと呼び出し

Wasm ランタイムの例としては、 SpinWasmtimeWasmEdgeWasmer などがあります。 FirefoxやChromeなどの主要なブラウザも使用しています スパイダーモンキーV8、それぞれ。

なぜWasmを使うのか?

アプリケーションスタックでWebAssemblyを使用する理由を理解するために、その主な利点、特にパフォーマンスと汎用性を犠牲にすることなくセキュリティを調べてみましょう。

パフォーマンスを犠牲にしないセキュリティ

Wasmは、安全なサンドボックス環境内でネイティブに近い速度でコードを実行し、悪意のあるソフトウェアからシステムを保護します。 このパフォーマンスは、WebAssembly バイトコードをマシンコードに直接ジャストインタイム (JIT) コンパイルすることで実現され、中間形式へのトランスパイルの必要性を回避します。 

また、Wasm は共有リニアメモリ (モジュール間または WebAssembly と JavaScript 間のデータ交換を簡素化する連続したメモリブロック) も使用します。 この設計により、効率的な通信が可能になり、開発者は JavaScript の柔軟性と WebAssembly の堅牢なパフォーマンスを 1 つのアプリケーションで融合させることができます。

このシステムのセキュリティは、サンドボックスとして機能するホストランタイム環境の設計によってさらに強化されます。 これにより、Wasm モジュールが指定されたメモリ空間の外部にアクセスすることや、ファイルシステムアクセス、ネットワークリクエスト、システムコールなどの潜在的に危険な操作を実行することを制限します。 WebAssembly では、ホスト機能にアクセスするために明示的なインポートとエクスポートを行う必要があるため、制御のレイヤーが追加され、安全な実行環境が確保されます。

ユースケースの多様性

最後に、WebAssemblyは(その名前に反して)従来のWebプラットフォーム以上のものに関連しています。 また、サーバーサイドアプリケーション、エッジコンピューティング、ゲーム開発、クラウド/サーバーレスコンピューティングにも優れたツールです。 パフォーマンス、セキュリティ、またはターゲット・デバイス・リソースが懸念される場合は、このコンパクト・バイナリー・フォーマットの使用を検討してください。

ここ数年、WebAssembly System Interface( またはWASI)のおかげで、WebAssemblyはサーバー側でより普及しています。 WASIは、ファイル、ファイルシステム、クロックなどのオペレーティングシステム機能へのアクセスを提供する Wasm用のモジュラーAPI です。 

DockerとWasm:どのように関連していますか?

WebAssembly コードについて読んだ後、Docker がどのように関連しているか疑問に思うかもしれません。 WebAssembly はサンドボックス化と移植性を処理しませんか? Dockerは全体像の中でどのように位置付けられますか? さらに話し合いましょう。

Dockerは、開発者がWasmを使用するアプリケーションを含め、アプリケーションを構築、実行、共有するのに役立ちます。 これは、Wasm が Linux コンテナーを補完するテクノロジであるため、特に当てはまります。 ただし、開発者の確かな経験がない状態でこれらのコンテナを処理すると、すぐにアプリケーション開発の障害になる可能性があります。

そこで、Dockerは、WasmやLinuxコンテナでビルドするためのスムーズな開発者エクスペリエンスを提供します。

Docker と Wasm を併用する利点

Docker と Wasm を一緒に使用すると、次のような開発者エクスペリエンスの大きなメリットも得られます。

  • 一貫性のある開発環境: 開発者は、Docker を使用して Wasm ランタイム環境をコンテナ化できます。 このアプローチにより、ローカル開発から本番環境まで、どのマシンでも同じように機能する一貫した Wasm 開発および実行環境が可能になります。
  • 効率的な導入: Wasm アプリケーションを Docker 内にパッケージ化することで、開発者は効率的なイメージ管理および配布機能を活用できます。 これにより、これらの種類のアプリケーションをさまざまな環境で簡単にデプロイおよびスケーリングできます。
  • セキュリティと分離: Dockerはオペレーティングシステムレベルでアプリケーションを分離しますが、Wasmはサンドボックス化された実行環境を提供します。これらのテクノロジーを併用することで、多くの一般的な脆弱性に対して堅牢な階層型セキュリティモデルが提供されます。
  • 強化されたパフォーマンス: 開発者は、Dockerコンテナを使用して、Wasmアプリケーションをサーバーレスアーキテクチャまたはマイクロサービスとしてデプロイできます。 これにより、スケーラブルで管理しやすい方法で Wasm のパフォーマンス上の利点を活用できます。

Docker Desktop で Wasm を有効にする方法

WebAssembly コンテナの実行に興味があるなら、あなたは幸運です! Wasm ワークロードのサポートは現在ベータ版であり、Docker Desktop で [設定] の [開発中の機能] タブで [Wasm を有効にする] をオンにすることで有効にできます (図 2)。

手記: まず、 containerd イメージ ストアのサポート が有効になっていることを確認してください。

Screenshot of Docker Desktop Settings showing checkmark beside "Enable Wasm" option.
図 2: Docker Desktop で Wasm を有効にします。

Docker Desktop で Wasm を有効にしたら、準備は完了です。 Docker は現在、Spin、WasmEdge、Wasmtime など、多くの Wasm ランタイムをサポートしています。 また、これらのアプリケーションの実行方法を説明する 詳細なドキュメント もあります。

Docker が WebAssembly をサポートする方法

DockerがWebAssemblyをどのようにサポートしているかを説明するには、Dockerエンジンがどのように機能するかを簡単に確認する必要があります。

Docker Engine は、 containerd と呼ばれる高レベルのコンテナー ランタイム上に構築されています。 このランタイムは、コンテナーのライフサイクルを制御するための基本的な機能を提供します。 shimプロセスを使用すると、containerdは内部で runc (低レベルのランタイム)を利用できます。 その後、runc はオペレーティング システムと直接対話して、コンテナーのさまざまな側面を管理できます。

The Docker Engine builds on a higher-level container runtime called containerd. This runtime provides fundamental functionality to control the container lifecycle. Using a shim process, containerd can leverage runc (a low-level runtime) under the hood. Then, runc can interact directly with the operating system to manage various aspects of containers.

この設計の素晴らしいところは、誰でも shim を書いて WebAssembly ランタイムを含む他のランタイムを containerd と統合できることです。 その結果、WasmEdge、Spin、Wasmtime など、Docker のさまざまな Wasm ランタイムと プラグアンドプレイ できます。

WebAssembly と Docker の未来

WebAssembly は絶えず進化しているため、エコシステムの発展に追いつくには、しっかりとした対応が必要です。 最近の進歩の1つは、新しい WebAssembly Componentモデル が様々なコンテナランタイムのシムにどのような影響を与えるかに関連しています。 Docker では、開発者が Wasm コンテナーを簡単に作成できるようにし、開発者エクスペリエンスを向上させることに取り組んでいます。

2019の有名なツイートスレッドで、Docker の創設者である Solomon Hykes 氏は、クラウド コンピューティングの未来について述べています。この未来では、DockerがWindows、Linux、WebAssemblyのコンテナを並行して実行する世界について述べている。 エコシステムの最近のすべての開発を考えると、その未来はまさにここにあります。

最近の進歩には、次のようなものがあります。

  • の打ち上げ WASI プレビュー 2 WASIは、コンポーネント・モデル・タイプのシステムとセマンティクスに基づいて完全にリベースされます。 これにより、WASIはモジュール化され、完全に仮想化可能になり、さまざまなソース言語からアクセス可能になります。
  • Fermyon、Microsoft、SUSE、LiquidReplyなども、 スピンキューブ オープンソースプロジェクト: このプロジェクトは、Wasmベースのサーバーレス機能をKubernetesクラスターにデプロイするための簡単な道筋を提供しました。 開発者は、k3s(Rancher Labの最小限のKubernetesディストリビューションを実行するための軽量ラッパー)を介してSpinKubeをDockerで使用できます。 Docker Desktop には shim も含まれており、ローカル マシンで Kubernetes コンテナーを実行できます。

2024、Wasmとコンテナの組み合わせは、その効率性、拡張性、コストの面で高く評価されることを期待しています。

まとめ

この記事では、DockerとWasmがどのように連携するか、およびWasmワークロードにDockerを使用する方法について説明しました。 今後数年間で Wasm の採用が拡大することを楽しみにしており、開発者の現状と向かう先の両方に対応するためのサポートを引き続き強化していきます。 

Wasm の詳細と Docker での連携については、次の関連資料を参照してください。

さらに詳しく

この記事の執筆に協力してくれた Fermyon の開発者アドボケイト リードである Sohan Maheshwar に感謝します。