とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど

開催予定の勉強会

読者登録と各種SNSのフォローもよろしくお願いいたします。

Docker DesktopでWASMを使ってみる

ここでいうWASMとはWebAssemblyのことを指しています。 WebAssemblyについては説明するのが難しいので、オフィシャルサイトをご覧ください。

かなりざっくり説明すると、特定の環境に依存しないで動くアプリケーションの配布形式の一種です。 初期はJSの高速化、のちにブラウザーでアプリケーションが動くというところから始まりました。 現在は、色々な環境でアプリケーションを動かすための「エンジン」として期待される傾向があります。

Docker DesktopもサポートするプラットフォームとしてWASMランタイムを追加して話題 となっていましたが、この機能は開発リリースでしか利用できませんでした。

Dockerはdockerdとcontainerdが動いていて、役割ごとにdockerdかcontainerdが動作します。 WASMアプリを動かすためのインターフェイスであるcontainerd-wasm-shimが追加されて、 ランタイムを呼び出すと、そのランタイムを使ってWASMアプリをDockerで動かせるという仕組みです。

以下の表ではwasmedgeランタイムが呼び出されていますが、現在はWasm workloads に書かれているランタイムがサポートされています。

最近それが一般リリースでも使える状況になったため、設定変更すればすぐに手元の環境でも試すことができます。 さっそく触ってみましょう!

Docker Desktopの設定変更

「Use containerd for pulling and storing images」と「Enable Wasm」を設定して、Docker Desktopを再起動するだけです。 初めて「Enable Wasm」を設定した場合は、ランタイムのダウンロードが行われます(一回でダウンロードできないときがあります)。

注意!

執筆日時点ではこの機能を使うために設定を変更すると、VSCodeでDocker拡張機能が使えなくなる点に注意してください。 問題が解決されるまでは「どっちが正常に動くことが自分にとって重要なのか」、考える必要があります。

(VSCodeでDocker拡張機能が使えなくなるので、つまりDev Containers拡張も使えません)。困る人はステイです。

また、この設定を変更したときにDocker Desktopのサービスがいつまで経っても起動してくれないことが偶にあります。 その時はリセットして設定してみてください。なんとか頑張ってください。 ちなみに私は20分くらいかかりました。

使ってみよう

まずはWASMバイナリーを作ってみましょうか。 これはRustで書いた単純にhello worldを表示するだけのアプリケーションです。

fn main() {
    println!("Hello, world!");
}

コンパイルします。

$ rustup target add wasm32-wasi
$ rustc hello.rs --target wasm32-wasm
$ ls
hello.rs    hello.wasm*

WASMを実行するランタイムは色々あるのですが、今回はwasmtimeを使います。 インストール方法については公式サイト をどうぞ(上のコードと同じものがそのまま載っています)。

なお、macOSでHomebrewを使っている場合はwasmtimeのFormulae があります。

実行してみるとこのような感じです。

$ wasmtime hello.wasm 
Hello, world!

$ file hello.wasm 
hello.wasm: WebAssembly (wasm) binary module version 0x1 (MVP)

作ったWASMバイナリーをDockerコンテナーで実行してみましょう。公式ドキュメント も参考にします。 このようなDockerfileを作成します。

# syntax=docker/dockerfile:1
FROM scratch
COPY hello.wasm /hello.wasm
ENTRYPOINT [ "/hello.wasm" ]

ベースイメージはこれを使ってみます。何も入っていないイメージです。

hub.docker.com

Dockerfileができたら、イメージをビルドしてみます。

docker buildx build --platform wasi/wasm -t ytooyama/hello-world .

ビルドを実行するとつぎのようなエラーが出るのですが(ここらへんはまだBetaなのでそのうち対応されると思います)、イメージはちゃんと作られています。

 => ERROR exporting to image                                                                        0.0s
 => => exporting layers                                                                             0.0s
 => => exporting manifest sha256:e54aa54d0d593a1b37fb6b8f493884fa2f2ddb0591a1451ad61c28cb311d0b9c   0.0s
 => => exporting config sha256:0ea51b5dd7448007256fc105ca689b49af09d7d161fb0ea0ec2da90cd76a03c6     0.0s
 => => exporting attestation manifest sha256:9f6bc8e96d73ecc176f524aa2f683781329e7ea8b91ee7ec358f4  0.0s
 => => exporting manifest list sha256:0d2e5cf178c5d13aff2c9021a56bfaa4733b772442c8b2bdafbcf4d45768  0.0s
 => => naming to docker.io/ytooyama/hello-world:latest                                              0.0s
 => => unpacking to docker.io/ytooyama/hello-world:latest                                           0.0s
------
 > exporting to image:
------
ERROR: failed to solve: no match for platform in manifest sha256:0d2e5cf178c5d13aff2c9021a56bfaa4733b772442c8b2bdafbcf4d4576876de: not found

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/uig9chzy4n0l2t05x8hf7m8av

コマンドを実行してみましょう。イメージが見つかるはずです。

$ docker image ls
REPOSITORY             TAG       IMAGE ID       CREATED              SIZE
ytooyama/hello-world   latest    0d2e5cf178c5   About a minute ago   516kB

作ったイメージはこちらにPushしておきました。

Docker Desktopが起動していない場合は予め起動しておきます。 端末を起動して、次のように実行してみましょう。

ランタイムはmacOSで実行したときと同じwastimeを使ってみます。

docker container run --rm \
  --runtime=io.containerd.wasmtime.v1 \
  --platform=wasi/wasm \
  ytooyama/hello-world

実行すると、このような出力がされて終了します。

Hello, world!

これでmacOSでビルドして動いたアプリケーションをDockerで動かすことができました。

まとめ

クラウドネイティブなアプリケーションにとって、アプリケーション以外の部分、例えばライブラリーやLinuxを除くOS部分はある意味不要な部分です。アプリケーションさえ動いてくれれば良いわけですから。 WASMを使うとそんな理想に一歩近づきます。

Docker DesktopでWASMが使えるようになったのは第一歩だと思います。 Docker Desktop以外の様々な「プラットフォーム」でもWASMが使えるのが当たり前になれば、色々楽しくなりそうです。

WASMが当たり前に使われるようになれば、従来のコンテナーと異なりオーバーヘッドも少ないので、今よりシンプルで低スペックなコンピューターでアプリケーションを動かしたりとかもできそうですね。 家電でも車でもコンピューターが入っている時代ですので、色々変わってきそうな気がしています。 エッジコンピューティングでもWASMとか使われる様になるのかなあとか、想像すると楽しそうな気がします。