WebAssembly 入门教程 / 13 - Docker 与容器
13 - Docker 与容器
Docker + Wasm = 比传统容器更轻量、更安全、启动更快的容器化方案。
13.1 Docker 对 Wasm 的支持
背景
2022 年 10 月,Docker 宣布与 Wasm 集成。这意味着可以直接在 Docker Desktop 中运行 Wasm 容器。
传统容器 vs Wasm 容器
传统 Linux 容器:
┌─────────────────────┐
│ 应用进程 │
│ ├── bin/ │
│ ├── lib/ │
│ ├── lib64/ │ 完整的 Linux 用户空间
│ ├── usr/ │ 通常 100MB+
│ ├── etc/ │
│ └── ... │
├─────────────────────┤
│ 容器运行时 (runc) │
├─────────────────────┤
│ Linux 内核 (namespaces│
│ + cgroups) │
└─────────────────────┘
Wasm 容器:
┌─────────────────────┐
│ Wasm 模块 │
│ (单个 .wasm 文件) │ 通常 1-10MB
├─────────────────────┤
│ Wasm 运行时 │
│ (containerd-shim- │ 无完整 Linux 用户空间
│ wasmedge/wasmtime) │
├─────────────────────┤
│ Linux 内核 │
└─────────────────────┘
对比
| 特性 | 传统容器 | Wasm 容器 |
|---|---|---|
| 镜像大小 | 50MB - 1GB+ | 1MB - 20MB |
| 冷启动时间 | 100ms - 数秒 | < 1ms |
| 内存占用 | 数十 MB | 数 MB |
| 安全模型 | Namespace + Cgroup | Wasm 沙箱 |
| 跨平台 | 依赖 CPU 架构 | 天然跨平台 |
| 系统调用 | 直接访问内核 | 通过 WASI |
13.2 使用 Docker Desktop 运行 Wasm
前置条件
# 1. 安装 Docker Desktop 4.15+
# 2. 启用 Wasm 运行时
# Docker Desktop → Settings → Features in development → ✅ Enable Wasm
# 或使用命令行
docker run --runtime=io.containerd.wasmedge.v1 \
--platform wasi/wasm32 \
hello-wasm
创建 Wasm 容器镜像
# Dockerfile.wasm
FROM scratch
COPY app.wasm /app.wasm
ENTRYPOINT ["/app.wasm"]
# 构建镜像
docker build --platform wasi/wasm32 -t my-wasm-app -f Dockerfile.wasm .
# 运行
docker run --runtime=io.containerd.wasmedge.v1 \
--platform wasi/wasm32 \
my-wasm-app
使用 Rust 构建 Wasm 应用
// src/main.rs
fn main() {
println!("Hello from Wasm container!");
// 读取环境变量
if let Ok(msg) = std::env::var("MESSAGE") {
println!("Message: {}", msg);
}
// 读取文件
if let Ok(content) = std::fs::read_to_string("/data/input.txt") {
println!("File content: {}", content);
}
}
# 多阶段构建
FROM rust:1.77 AS builder
WORKDIR /app
COPY . .
RUN rustup target add wasm32-wasi && \
cargo build --target wasm32-wasi --release
FROM scratch
COPY --from=builder /app/target/wasm32-wasi/release/app.wasm /app.wasm
ENTRYPOINT ["/app.wasm"]
13.3 containerd shim 运行时
可用的 Wasm shim
| shim | 运行时 | 说明 |
|---|---|---|
containerd-shim-wasmedge-v1 | WasmEdge | 高性能,AI 推理 |
containerd-shim-wasmtime-v1 | Wasmtime | 参考实现,完整 WASI |
containerd-shim-wasmer-v1 | Wasmer | 多后端 |
spin | Spin | Fermyon 微服务框架 |
slight | SpiderLightning | Deis Labs |
安装 containerd shim
# 安装 WasmEdge shim
curl -sSf https://raw.githubusercontent.com/nicedoc/nicedoc.io/master/install.sh | bash
# 配置 containerd
cat >> /etc/containerd/config.toml << EOF
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.wasm]
runtime_type = "io.containerd.wasmedge.v1"
EOF
# 重启 containerd
sudo systemctl restart containerd
13.4 Kubernetes 中的 Wasm
使用 runwasi 在 K8s 中运行 Wasm
# RuntimeClass 定义
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: wasmedge
handler: wasmedge
---
# Pod 使用 Wasm RuntimeClass
apiVersion: v1
kind: Pod
metadata:
name: wasm-app
spec:
runtimeClassName: wasmedge
containers:
- name: app
image: my-registry/my-wasm-app:latest
env:
- name: MESSAGE
value: "Hello from K8s"
resources:
limits:
memory: "64Mi"
cpu: "100m"
Kwok + Wasm 测试集群
# 使用 kind 创建支持 Wasm 的集群
kind create cluster --config=- <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraMounts:
- hostPath: /usr/local/bin/containerd-shim-wasmedge-v1
containerPath: /usr/local/bin/containerd-shim-wasmedge-v1
EOF
13.5 WasmCloud
WasmCloud 是一个专为 Wasm 设计的分布式应用平台,基于 Actor 模型。
核心概念
WasmCloud 架构:
┌────────────────────────────────────────┐
│ Lattice (网格) │
│ ┌──────────┐ ┌──────────┐ │
│ │ Actor │ │ Actor │ │
│ │ (业务逻辑) │ │ (业务逻辑) │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ┌────▼──────────────▼─────┐ │
│ │ Capability │ │
│ │ (HTTP, DB, MQ, etc.) │ │
│ └──────────────────────────┘ │
└────────────────────────────────────────┘
Actor(业务逻辑)
use wasmcloud_actor_httpserver::*;
use wasmcloud_actor_messaging::*;
#[derive(Debug, Default, Actor, HealthResponder)]
#[contracts(HttpServer, Messaging)]
pub struct MyActor {}
#[async_trait]
impl HttpServer for MyActor {
async fn handle_request(&self, ctx: &Context, req: &HttpRequest) -> RpcResult<HttpResponse> {
let response = match req.path.as_str() {
"/hello" => HttpResponse::ok("Hello from WasmCloud!"),
"/health" => HttpResponse::ok(r#"{"status":"healthy"}"#),
_ => HttpResponse::not_found(),
};
Ok(response)
}
}
Capability Provider
# wasmcloud.toml
name = "my-actor"
language = "rust"
type = "actor"
version = "0.1.0"
[actor]
claims = ["wasmcloud:httpserver", "wasmcloud:messaging"]
# 构建
wash build
# 本地开发
wash dev
# 部署到 lattice
wash app deploy wadm.yaml
13.6 Docker Compose 示例
# docker-compose.yaml
version: "3.9"
services:
api-gateway:
image: my-registry/api-gateway:latest
platform: wasi/wasm32
runtime: io.containerd.wasmedge.v1
ports:
- "8080:8080"
environment:
- LOG_LEVEL=info
auth-service:
image: my-registry/auth:latest
platform: wasi/wasm32
runtime: io.containerd.wasmedge.v1
environment:
- JWT_SECRET=secret123
cache:
image: redis:7-alpine
ports:
- "6379:6379"
13.7 轻量容器场景
Serverless / FaaS
# Knative Service 使用 Wasm 容器
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: wasm-function
spec:
template:
spec:
runtimeClassName: wasmedge
containers:
- image: my-registry/function:latest
resources:
limits:
memory: "32Mi"
cpu: "50m"
IoT 网关
IoT 设备 (ARM64):
┌─────────────────────────┐
│ containerd + Wasm shim │
│ ┌─────────────────────┐ │
│ │ Wasm 容器: │ │
│ │ • 传感器数据采集 │ │ 同一 .wasm 文件
│ │ • 边缘预处理 │ │ 无需交叉编译
│ │ • 异常检测 │ │
│ └─────────────────────┘ │
└─────────────────────────┘
13.8 镜像优化
最小镜像大小
# 最小 Wasm 容器镜像
FROM scratch
COPY --chmod=755 app.wasm /app.wasm
ENTRYPOINT ["/app.wasm"]
# 对比镜像大小
docker images
# REPOSITORY TAG SIZE
# node-app latest 180MB ← Node.js 容器
# python-app latest 120MB ← Python 容器
# go-app latest 12MB ← Go 容器
# wasm-app latest 2.5MB ← Wasm 容器 ✓
压缩 Wasm 二进制
# wasm-opt 优化
wasm-opt -Oz app.wasm -o app_opt.wasm
# Brotli 压缩(Docker 会自动解压)
brotli app.wasm -o app.wasm.br
# 对比
ls -lh app.wasm app_opt.wasm
# 1.2M app.wasm
# 800K app_opt.wasm
13.9 安全优势
沙箱对比
传统容器攻击面:
┌──────────────────┐
│ 应用进程 │
│ ↓ 系统调用 │
│ Linux 内核 │ ← 内核漏洞可导致逃逸
│ ↓ 硬件 │
│ 宿主机 │
└──────────────────┘
Wasm 容器攻击面:
┌──────────────────┐
│ Wasm 模块 │
│ ↓ WASI 调用 │ ← 只有有限的系统调用
│ Wasm 运行时 │ ← 能力受限的沙箱
│ ↓ 系统调用 │
│ Linux 内核 │ ← 双重隔离
│ ↓ 硬件 │
│ 宿主机 │
└──────────────────┘
13.10 注意事项
⚠️ 生态成熟度:Docker + Wasm 仍在快速演进中,生产使用需要充分测试。
⚠️ 运行时选择:不同 shim 运行时的行为可能有差异,选择时需要考虑完整性和性能。
⚠️ 网络限制:WASI Preview 1 的网络支持有限,需要 Preview 2 或特定扩展。
⚠️ 调试工具:Wasm 容器的调试工具链不如传统容器成熟,需要提前评估。
13.11 扩展阅读
下一章:14 - 性能与优化 — 深入理解 Wasm 性能特征并掌握优化技巧。