在 Azure Kubernetes 服务 (AKS) 中创建 WebAssembly 系统接口 (WASI) 节点池以运行 WebAssembly (WASM) 工作负荷(预览)

WebAssembly (WASM) 是一种二进制格式,针对 WASM 运行时中的快速下载和最大执行速度进行了优化。 WASM 运行时设计为在目标体系结构上运行,在沙盒中执行 WebAssembly,与主计算机隔离,具有接近本机的性能。 默认情况下,WebAssemblies 无法访问沙盒外部主机上的资源,除非明确允许,并且无法通过套接字进行通信来访问环境变量或 HTTP 流量。 WebAssembly 系统接口 (WASI) 标准为 WASM 运行时定义了一个 API,使用功能模型向 WebAssembly 提供对环境和主机外部资源的访问。

重要

WASI 节点池现在使用 containerd shim 来运行 WASM 工作负载。 以前,AKS 使用 Krustlet 来允许 WASM 模块在 Kubernetes 上运行。 如果你仍在使用基于 Krustlet 的 WASI 节点池,可以通过创建一个新的 WASI 节点池并将工作负载迁移到新节点池,来迁移到 containerd shim。

在您开始之前

必须安装最新版本的 Azure CLI。

安装 aks-preview Azure CLI 扩展

重要

AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

若要安装 aks-preview 扩展,请运行以下命令:

az extension add --name aks-preview

运行以下命令以更新到已发布的最新扩展版本:

az extension update --name aks-preview

注册“WasmNodePoolPreview”功能标志

使用 WasmNodePoolPreview 命令注册 功能标志,如以下示例所示:

az feature register --namespace "Microsoft.ContainerService" --name "WasmNodePoolPreview"

几分钟后,状态将显示为“已注册”。 使用 az feature show 命令验证注册状态:

az feature show --namespace "Microsoft.ContainerService" --name "WasmNodePoolPreview"

当状态反映为“已注册”时,使用 az provider register 命令刷新 Microsoft.ContainerService 资源提供程序的注册:

az provider register --namespace Microsoft.ContainerService

局限性

  • 目前,只有适用于 spinslight 应用程序的 containerd shim,这些应用程序使用 wasmtime 运行时。 除了 wasmtime 运行时应用程序之外,还可以在 WASM/WASI 节点池上运行容器。
  • 可以在同一节点上运行容器和 wasm 模块,但无法在同一 pod 上运行容器和 wasm 模块。
  • WASM/WASI 节点池不能用于系统节点池。
  • WASM/WASI 节点池的 os-type 必须是 Linux。
  • 无法使用 Azure 门户创建 WASM/WASI 节点池。

将 WASM/WASI 节点池添加到现有 AKS 群集

要添加 WASM/WASI 节点池,请使用 az aks nodepool add 命令。 以下示例创建一个具有一个节点且名为 mywasipool 的 WASI 节点池。

az aks nodepool add \
    --resource-group myResourceGroup \
    --cluster-name myAKSCluster \
    --name mywasipool \
    --node-count 1 \
    --workload-runtime WasmWasi 

注释

workload-runtime 参数的默认值为 ocicontainer。 若要创建可运行容器工作负荷的节点池,请省略 workload-runtime 参数或将值设置为 ocicontainer。

使用 验证 workloadRuntime 值。 例如:

az aks nodepool show -g myResourceGroup --cluster-name myAKSCluster -n mywasipool --query workloadRuntime

以下示例输出展示了 mywasipool 具有 workloadRuntime 类型的 WasmWasi。

az aks nodepool show -g myResourceGroup --cluster-name myAKSCluster -n mywasipool --query workloadRuntime
"WasmWasi"

使用 kubectl 命令将 配置为连接到你的 Kubernetes 群集。 以下命令:

az aks get-credentials -n myakscluster -g myresourcegroup

使用 kubectl get nodes 显示群集中的节点。

kubectl get nodes -o wide
NAME                                 STATUS   ROLES   AGE    VERSION    INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
aks-mywasipool-12456878-vmss000000   Ready    agent   123m   v1.23.12   <WASINODE_IP> <none>        Ubuntu 22.04.1 LTS   5.15.0-1020-azure   containerd://1.5.11+azure-2
aks-nodepool1-12456878-vmss000000    Ready    agent   133m   v1.23.12   <NODE_IP>     <none>        Ubuntu 22.04.1 LTS   5.15.0-1020-azure   containerd://1.5.11+azure-2

使用 kubectl describe node 显示 WASI 节点池中节点上的标签。 下面的示例展示了 aks-mywasipool-12456878-vmss000000 的详细信息。

kubectl describe node aks-mywasipool-12456878-vmss000000
Name:               aks-mywasipool-12456878-vmss000000
Roles:              agent
Labels:             agentpool=mywasipool
...
                    kubernetes.azure.com/wasmtime-slight-v1=true
                    kubernetes.azure.com/wasmtime-spin-v1=true
...

添加一个 RuntimeClass 用于运行 旋转轻微 应用程序。 创建包含以下内容的名为 wasm-runtimeclass.yaml 的文件:

apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: "wasmtime-slight-v1"
handler: "slight"
scheduling:
  nodeSelector:
    "kubernetes.azure.com/wasmtime-slight-v1": "true"
---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: "wasmtime-spin-v1"
handler: "spin"
scheduling:
  nodeSelector:
    "kubernetes.azure.com/wasmtime-spin-v1": "true"

使用 kubectl 来创建 RuntimeClass 对象。

kubectl apply -f wasm-runtimeclass.yaml

运行 WASM/WASI 工作负荷

创建包含以下内容的名为 slight.yaml 的文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wasm-slight
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wasm-slight
  template:
    metadata:
      labels:
        app: wasm-slight
    spec:
      runtimeClassName: wasmtime-slight-v1
      containers:
        - name: hello-slight
          image: ghcr.io/deislabs/containerd-wasm-shims/examples/slight-rust-hello:v0.3.3
          command: ["/"]
          resources:
            requests:
              cpu: 10m
              memory: 10Mi
            limits:
              cpu: 500m
              memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
  name: wasm-slight
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: wasm-slight

注释

开发应用程序时,应针对 wasm32-wasi 目标生成模块。 有关更多详细信息,请参阅 spinslight 文档。

使用 kubectl 运行示例部署:

kubectl apply -f slight.yaml

使用 kubectl get svc 获取服务的外部 IP 地址。

kubectl get svc
NAME          TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
kubernetes    ClusterIP      10.0.0.1       <none>         443/TCP        10m
wasm-slight   LoadBalancer   10.0.133.247   <EXTERNAL-IP>  80:30725/TCP   2m47s

http://EXTERNAL-IP/hello 上访问示例应用程序。 以下示例使用 curl

curl http://EXTERNAL-IP/hello
hello

注释

如果请求超时,请使用 kubectl get podskubectl describe pod <POD_NAME> 检查 pod 的状态。 如果 pod 未运行,请使用 kubectl get rskubectl describe rs <REPLICA_SET_NAME> 查看副本集是否在创建新 pod 时出现问题。

清除

若要删除示例部署,请使用 kubectl delete

kubectl delete -f slight.yaml

若要删除 WASM/WASI 节点池,请使用 az aks nodepool delete

az aks nodepool delete --name mywasipool -g myresourcegroup --cluster-name myakscluster