WebAssembly on Kubernetes:当 Serverless 不再需要容器

2026 年,云原生基础设施正在经历一场静默的重塑——Kubernetes 正在分裂为「核心」与「Serverless」两条赛道,而 WebAssembly(Wasm)正以毫秒级冷启动、10MB 级镜像体积和字节码级安全沙箱,成为这场变革中最锋利的刀。

一、背景:容器的「隐性税」

我们早已习惯了一种架构惯性:要部署一个简单的 HTTP 处理函数,先写一个 Dockerfile,塞进完整的 Linux 用户空间、C 运行时库、包管理器残留——最终得到一个 300MB 的容器镜像,只为跑一个 15MB 的二进制。

当流量洪峰袭来,K8s 集群需要从 Registry 拉取镜像、解压分层、配置命名空间、初始化容器运行时——整套流程走完,冷启动可能高达 2~3 秒。对于一次只运行 50ms 的 Serverless 函数来说,这是无法接受的尾延迟。

Docker 创始人 Solomon Hykes 早在 2019 年就说:「如果 WASM+WASI 在 2008 年就存在,我们根本不需要发明 Docker。」

如今,2026 年,这句话正在变成现实。

二、Wasm vs 容器:两种隔离哲学

维度 Docker 容器 WebAssembly 模块
冷启动 100ms ~ 3s < 1ms(缓存后)
镜像体积 150MB ~ 1GB 1MB ~ 25MB
内存开销 3050MB 基础 + 每实例 50200MB 520MB + 每实例 110MB
隔离边界 内核级(namespace + cgroup) 指令级(线性内存沙箱)
安全模型 默认开放 300+ 系统调用,按需收敛 从零授权:不显式授予则无法访问
跨平台 Linux 容器 ≠ Windows 容器 一次编译,x86/ARM/RISC-V 全平台运行

关键数据点: 在 1000 并发实例场景下,按 $0.05/GB/小时计算,容器的内存成本约为 $2.50$10.00/小时,而 Wasm 仅为 $0.05$0.50/小时——成本差距高达 10~50 倍

三、Wasm 在 K8s 上的运行原理

很多人误以为引入 Wasm 意味着要推倒现有 K8s 集群重建。事实恰恰相反——Wasm 模块可以和普通容器在同一个 Worker 节点上共存运行。

关键在于 CNCF 孵化的 runwasi 项目——一套专为 containerd 设计的 shim 层:

               ┌──────────────┐
               │  Kubelet     │
               └──────┬───────┘
                      │ CRI
               ┌──────▼───────┐
               │  containerd   │
               └──┬────────┬──┘
          ┌──────┘        └──────┐
   ┌──────▼──────┐      ┌───────▼───────┐
   │    runc     │      │ runwasi shim  │
   │ (容器路径)   │      │  (Wasm 路径)  │
   └──────┬──────┘      └───────┬───────┘
          │                     │
   ┌──────▼──────┐      ┌───────▼───────┐
   │  Linux NS   │      │ Wasmtime /    │
   │  进程隔离    │      │ WasmEdge      │
   └─────────────┘      └───────────────┘

当调度器检测到 runtimeClassName: wasmtime-spin 时,containerd 会完全绕过容器创建流程,直接将 Wasm 字节码交给轻量级运行时执行——无需拉取完整镜像、无需初始化 Linux 命名空间。

四、实战:用 SpinKube 部署 Serverless Wasm 应用

4.1 前置条件

在 K8s 集群上安装 SpinKube(CNCF Sandbox 项目):

# 安装 containerd-shim-spin
kubectl apply -f https://github.com/spinkube/spin-operator/releases/latest/download/spin-operator.shim-install.yaml

# 安装 Spin Operator
kubectl apply -f https://github.com/spinkube/spin-operator/releases/latest/download/spin-operator.crds.yaml
kubectl apply -f https://github.com/spinkube/spin-operator/releases/latest/download/spin-operator.runtime-class.yaml
kubectl apply -f https://github.com/spinkube/spin-operator/releases/latest/download/spin-operator.shim-executor.yaml

4.2 编写并编译一个 Serverless 函数

使用 Rust 编写一个简单的 HTTP 处理函数:

use spin_sdk::http::{IntoResponse, Request, Response};
use spin_sdk::http_component;

#[http_component]
fn handle_request(req: Request) -> anyhow::Result<impl IntoResponse> {
    let path = req.uri().path();
    Ok(Response::builder()
        .status(200)
        .header("content-type", "application/json")
        .body(format!(r#"{{"message": "Hello from Wasm!", "path": "{}"}}"#, path))
        .build())
}

编译:

spin build
spin registry push ghcr.io/my-org/wasm-handler:v1.0.0

4.3 部署到 Kubernetes

最关键的一步——通过 runtimeClassName 指定 Wasm 运行时:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wasm-handler
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: wasm-handler
  template:
    metadata:
      labels:
        app: wasm-handler
    spec:
      runtimeClassName: wasmtime-spin   # ← 关键:指定 Wasm 运行时
      containers:
        - name: handler
          image: ghcr.io/my-org/wasm-handler:v1.0.0
          resources:
            limits:
              cpu: "100m"
              memory: "32Mi"            # ← 只需 32MB 内存!
          ports:
            - containerPort: 80

部署:

kubectl apply -f deployment.yaml

# 验证
kubectl get pods -l app=wasm-handler
# NAME                            READY   STATUS    RESTARTS   AGE
# wasm-handler-7d9f8c5b6-x2k9j   1/1     Running   0          2s   ← 秒级就绪!

4.4 配合 HPA 实现毫秒级弹性伸缩

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: wasm-handler-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: wasm-handler
  minReplicas: 2
  maxReplicas: 100
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 0    # ← 无需等待窗口,毫秒级冷启动允许即刻扩容
      policies:
        - type: Percent
          value: 100
          periodSeconds: 5

因为每个 Wasm 实例的冷启动不到 1ms,你可以将 stabilizationWindowSeconds 设为 0,实现真正的即时弹性伸缩——这是传统容器架构想做但做不到的。

五、Docker 原生 Wasm 支持:Edge Runtime

Docker 官方在 2025 年底发布的 Docker Engine 26.0 中,正式内置了 Wasm 运行时(代号「Edge Runtime」),无需额外插件即可直接运行 .wasm 文件:

# 直接运行 Wasm 模块,无需 Dockerfile
docker run --runtime=io.containerd.wasmtime.v1 \
  --platform=wasi/wasm \
  ghcr.io/my-org/wasm-handler:v1.0.0

这意味着 Docker 自己也在拥抱「无容器」的未来。对于开发环境来说,你可以用 docker-compose 同时编排容器化服务(PostgreSQL、Redis)和 Wasm 微服务,在一个配置文件中无缝混合两种运行时。

六、Wasm 不是容器的替代品——而是 Serverless 的正确答案

诚实地讲,Wasm 不是容器的全面替代品:

  • 用容器:PostgreSQL、Redis、Kafka 等有状态复杂应用——它们需要完整的 POSIX 环境、成熟的数据持久化和 GPU 支持
  • 用 Wasm:无状态 HTTP 处理器、事件消费者、第三方插件沙箱、边缘 AI 微推理——冷启动是核心指标、密度是成本关键

混合架构才是正解:同一个 K8s 集群中,容器跑数据库,Wasm 跑业务函数,通过统一的 Service Mesh 管理流量。这就是 2026 年云原生基础设施的真实形态。

七、展望:2026 下半年的关键信号

  1. Wasm 3.0 规范:已加入垃圾回收(GC)、64 位内存寻址(Memory64)、异常处理,使得更多语言(Java、Kotlin、Swift)可以直接编译到 Wasm
  2. WASI 0.3 / Component Model:让不同语言编写的 Wasm 模块可以像微服务一样通过标准化接口互相调用——这本质上是「Wasm 原生的服务网格」
  3. CNCF 生态加速:SpinKube 处于 Sandbox 阶段快速迭代,wasmCloud 进入 Incubation 倒计时
  4. Kubernetes 1.36:Dynamic Resource Allocation(DRA)正式 GA,让 GPU/NPU 等异构硬件可以通过声明式 API 分配给 Wasm 工作负载

Serverless 的未来,未必是更小的容器。它可能根本不需要容器。

—— 2026 年云原生社区共识


本文由「人间凡尔赛」原创发布于 CSDN,转载请注明出处。

参考来源:CNCF Wasm Landscape、SpinKube 官方文档、Docker Wasm Integration Guide、Kubernetes 1.36 Release Notes

更多推荐