Docker+Wasm:把 WebAssembly 模块当容器一样跑
阅读时间: 大约 11 分钟
Docker+Wasm:把 WebAssembly 模块当容器一样跑

2022 年 10 月 24 日,Docker 工程师 Michael Irwin 发表博客,宣布 Docker+Wasm 技术预览(Technical Preview) 开放,并在同期宣布 Docker 作为投票成员加入 Bytecode Alliance。据 Koala 项目库介绍,这是容器巨头 Docker 在浏览器之外给 WebAssembly 找的新位置:让你用熟悉的 docker run 直接跑 Wasm 应用。本文基于这篇官方博客,拆解它到底是怎么跑起来的、和传统 Linux 容器是什么关系,以及官方自己标注的预览期坑。
一、背景:Wasm 从浏览器走向服务器
WebAssembly(Wasm)原本是为浏览器设计的——把 Rust/C/C++/Go 等 40 多种语言编译成可移植的二进制,在浏览器沙箱里高速运行。官方博客举的例子很有说服力:Figma、AutoCAD、Photoshop 跑在 Web 端;fastq.bio 把基于 Web 的 DNA 序列质量分析迁到 Wasm 后获得了 20 倍提速;Disney 甚至把 Disney+ 的应用开发套件建在 Wasm 之上。
真正让 Docker 动心的是 WASI(WebAssembly System Interface):它让 Wasm 脱离浏览器、访问类操作系统接口,从而在服务端和边缘运行。Vercel、Fastly、Shopify、Cloudflare 都在用 Wasm 跑边缘代码,Fermyon 则在做云上的 Wasm 微服务平台。Docker 的判断是:Wasm 不是要取代 Linux 容器,而是与之互补——开发者可以按场景二选一,甚至两者混用。
二、是什么:一条新的 containerd shim
关键要理解:Docker+Wasm 并没有发明一个”Wasm 容器运行时”去替换 runc。它复用了 Docker 迁移到 containerd 镜像管理后获得的能力——同时使用 OCI 制品(artifact)和 containerd shim。
如上图所示,Docker Engine 之下是 containerd,它传统上通过 containerd-shim → runc → 容器进程 启动 Linux 容器。Docker+Wasm 做的事,是新增一条并列链路:
- Docker 与 WasmEdge 合作实现了一个 containerd shim(
containerd-wasm-shim); - 这个 shim 从 OCI 制品里抽出 Wasm 模块,交给 WasmEdge 运行时执行;
- 用户通过声明 Wasm 运行时来启用这条新 shim。
于是对 Docker Engine 来说,跑一个 Wasm 模块和跑一个 Linux 容器,在调度、镜像拉取、网络配置这层几乎是同一种操作。
三、技术机制:一条命令怎么跑起来
官方给的最小示例是这样的:
docker run -dp 8080:8080 --name=wasm-example \
--runtime=io.containerd.wasmedge.v1 \
--platform=wasi/wasm32 \
michaelirwin244/wasm-example两个关键 flag 的官方解释:
--runtime=io.containerd.wasmedge.v1:告诉 Docker 引擎用 Wasm containerd shim,而不是标准的 Linux 容器运行时(runc);--platform=wasi/wasm32:声明镜像架构为 wasi/wasm32。正因为是 Wasm 架构,你不需要为 x86/ARM 分别构建镜像——Wasm 运行时会在最后一步把 Wasm 二进制转换为当前机器的机器指令。这正是”一次构建、处处运行”的落地。
镜像拉下来后,运行时读取镜像的 ENTRYPOINT,定位并抽出 Wasm 模块,加载进 Wasm 运行时启动,再配置网络。示例应用是一个 Rust 写的简易 Web 服务器,返回 "Hello world from Rust running with Wasm!",并在 /echo 回显 POST 数据。关键收益是:这个 Wasm 应用可以和你的 Linux 容器并排运行,甚至能用 Docker Compose 一起编排。

四、关键口径:20 倍与”不是容器”
博客里出现的数字需要分清来源:
- 20 倍提速来自 fastq.bio 把 DNA 分析迁到 Wasm 的浏览器内案例,是第三方业务、浏览器场景,不是 Docker+Wasm 在服务端压测出来的——不能拿来论证”容器里跑 Wasm 快 20 倍”;
- Docker 官方没有给出 Wasm 相比 runc 容器的启动延迟、内存占用对比。它强调的是 Wasm 的”隔离性、轻量化”,以及与平台架构解耦的分发优势,而非一个量化的性能冠军。
五、官方自承的局限(预览期口径)
这篇博客最诚实的部分,是它明确列了一堆”技术预览”坑:
- 强制开启 containerd 镜像存储且无法关闭:如果你之前没用 containerd 镜像存储,已有的镜像和容器将变得不可访问——这是升级前必须知道的破坏性变更;
- Docker Compose 被中断时可能不优雅退出:官方给出的 workaround 是
killall -9 docker-compose; - 推送到 Hub 可能报
insufficient_scope: authorization failed,即便你在 Docker Desktop 里登录过——workaround 是去命令行再docker login; - 官方还自承:多线程、垃圾回收等 Wasm 能力仍在演进,缩短开发反馈环、走向生产的路径尚未打通。
博客结尾也直说”things may change quite rapidly”,这只是技术预览。
六、适用 / 不适用场景
适合:
- 想在统一的 Docker 工具链里试验 Wasm 边缘/微服务的开发者;
- 追求”一次构建、多架构部署”、厌恶为 x86/ARM 分别打镜像的团队;
- 把 Wasm 小服务和现有 Linux 容器混编在一个 Compose 里做原型验证。
不适合:
- 把它当作生产级 Wasm 编排平台——官方明说生产路径还在探索;
- 不能接受 containerd 镜像存储迁移、或本地已有大量旧镜像/容器依赖的环境;
- 需要重度多线程、GC 或成熟运维生态的负载。
七、客观分析:优势与局限
优势:
- 复用 Docker 心智:
docker run、镜像、Compose 全套经验直接迁移,降低 Wasm 上手门槛; - 架构解耦:
wasi/wasm32镜像真正实现一次构建到处跑; - 与容器互补而非替换:同一台机器上 Wasm 模块和 Linux 容器并存;
- 生态站位:Docker 加入 Bytecode Alliance,背书 WASI 标准路线。
局限:
- 本质是 shim,不是重新设计运行时:能力上限受 WasmEdge 与 WASI 成熟度约束;
- 预览期破坏性变更:强制 containerd 镜像存储会让旧镜像不可见;
- 无官方量化性能对比:轻量化/隔离性是定性说法,没有同场压测;
- 生产就绪度未定:官方把多线程、GC、生产路径列为”下一步”。
八、它意味着什么 / 谁该关注
Docker+Wasm 的真正意义,不在于”容器里跑 Wasm”这个噱头,而在于它把 Wasm 从”边缘平台各自为战”拉进了开发者最熟悉的镜像与 docker run 工作流。对正在评估 WASM/WASI 是否适合自家微服务、边缘函数的团队,这是一条低成本试验路径。但请务必记住它的官方定位——2022 年的技术预览、今天虽已脱离 beta,却仍未被 Docker 包装成”生产首选”。把它当作一个值得跟进的方向,而不是明天就要替换 runc 的决定。