sigs.k8s.io/cluster-api-provider-azure@v1.14.3/docs/book/src/topics/wasi.md (about) 1 # WebAssembly / WASI Workloads 2 3 ## Overview 4 5 CAPZ enables you to create WebAssembly (Wasm) / WASI pod workloads targeting the [Deislabs Slight](https://github.com/deislabs/spiderlightning), [Fermyon Spin](https://github.com/fermyon/spin), [Lunatic](https://github.com/lunatic-solutions/lunatic), or [VMware Wasm Workers Server](https://workers.wasmlabs.dev) frameworks for building and running fast, secure microservices on Kubernetes. 6 > **NOTE**: Images built with [image-builder](https://github.com/kubernetes-sigs/image-builder) version v0.1.22 or later support all four Wasm runtimes. 7 8 All of the runtimes (lunatic, slight, spin, and wws) for running Wasm workloads are embedded in *containerd shims* by the [deislabs/containerd-wasm-shims](https://github.com/deislabs/containerd-wasm-shims) project which is built upon [containerd/runwasi](https://github.com/containerd/runwasi). These containerd shims enable Kubernetes to run Wasm workloads without needing to embed the Wasm runtime in each OCI image. 9 10 ## Deislabs Slight (SpiderLightning) 11 Slight (or SpiderLightning) is an open source wasmtime-based runtime that provides cloud capabilities to Wasm microservices. These capabilities include key/value, pub/sub, and much more. 12 13 ## Fermyon Spin 14 Spin is an open source framework for building and running fast, secure, and composable cloud microservices with WebAssembly. It aims to be the easiest way to get started with WebAssembly microservices, and takes advantage of the latest developments in the WebAssembly component model and Wasmtime runtime. 15 16 ## Lunatic 17 Lunatic is a universal open source runtime for fast, robust and scalable server-side applications. It's inspired by Erlang and can be used from any language that compiles to WebAssembly. 18 19 ## VMware Wasm Workers Server 20 Wasm Workers Server is an open source framework that allows you to develop and run serverless applications using a lightweight construct called "workers". The server itself is implemented as a self-contained binary that routes HTTP requests to a WebAssembly runtime that hosts the workers. 21 22 ### Applying the Wasm Runtime Classes 23 By default, CAPZ virtual machine images include containerd shims to run `lunatic`, `slight`, `spin`, and `wws` workloads. To inform Kubernetes about the ability to run Wasm workloads on CAPZ nodes, you must apply a *runtime class* for one or more runtimes to your workload cluster. 24 25 Create a `wasm-runtimes.yaml` file with the following contents to enable all four runtimes: 26 27 ```yaml 28 --- 29 apiVersion: node.k8s.io/v1 30 kind: RuntimeClass 31 metadata: 32 name: "wasmtime-lunatic-v1" 33 handler: "lunatic" 34 --- 35 apiVersion: node.k8s.io/v1 36 kind: RuntimeClass 37 metadata: 38 name: "wasmtime-slight-v1" 39 handler: "slight" 40 --- 41 apiVersion: node.k8s.io/v1 42 kind: RuntimeClass 43 metadata: 44 name: "wasmtime-spin-v2" 45 handler: "spin" 46 --- 47 apiVersion: node.k8s.io/v1 48 kind: RuntimeClass 49 metadata: 50 name: "wasmtime-wws-v1" 51 handler: "wws" 52 ``` 53 54 Deploy these resources to your workload cluster: 55 ```bash 56 kubectl --kubeconfig=<workload-kubeconfig> apply -f wasm-runtimes.yaml 57 ``` 58 59 The preceding YAML document will register runtime classes for `lunatic`, `slight`, `spin`, and `wws`, which will direct containerd to use the appropriate shim when a pod workload is scheduled onto a cluster node. 60 61 ### Running an Example Spin Workload 62 With the runtime classes registered, we can now schedule Wasm workloads on our nodes by creating a Kubernetes Deployment and Service. Create a `spin.yaml` file with the following contents: 63 64 ```yaml 65 --- 66 apiVersion: apps/v1 67 kind: Deployment 68 metadata: 69 name: wasm-spin 70 spec: 71 replicas: 3 72 selector: 73 matchLabels: 74 app: wasm-spin 75 template: 76 metadata: 77 labels: 78 app: wasm-spin 79 spec: 80 runtimeClassName: wasmtime-spin-v2 81 containers: 82 - name: spin-hello 83 image: ghcr.io/deislabs/containerd-wasm-shims/examples/spin-rust-hello:latest 84 command: ["/"] 85 resources: 86 requests: 87 cpu: 10m 88 memory: 10Mi 89 limits: 90 cpu: 500m 91 memory: 128Mi 92 --- 93 apiVersion: v1 94 kind: Service 95 metadata: 96 name: wasm-spin 97 spec: 98 type: LoadBalancer 99 ports: 100 - protocol: TCP 101 port: 80 102 targetPort: 80 103 selector: 104 app: wasm-spin 105 ``` 106 107 Deploy these resources to your workload cluster: 108 ```bash 109 kubectl --kubeconfig=<workload-kubeconfig> apply -f spin.yaml 110 ``` 111 112 The preceding deployment and service will create a load-balanced "hello world" service with 3 Spin microservices. Note the `runtimeClassName` applied to the Deployment, `wasmtime-spin-v2`, which informs containerd on the cluster node to run the workload with the Spin v2 shim. 113 114 ### A Running Spin Microservice 115 With the service and the deployment applied, you should now have a Spin microservice running in your workload cluster. If you run the following command against the workload cluster, you can find the IP for the `wasm-spin` service. 116 117 ```shell 118 kubectl --kubeconfig=<workload-kubeconfig> get services -w 119 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE 120 kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 14m 121 wasm-spin LoadBalancer 10.105.51.137 20.121.244.48 80:30197/TCP 3m8s 122 ``` 123 124 In the preceding output, we can see the `wasm-spin` service with an external IP of `20.121.244.48`. Your external IP will be different, but that is expected. 125 126 Next, let's connect to the service and get a response from our Wasm microservice. You will need to replace the placeholder IP address below with the your external IP address from the preceding output. 127 128 ```shell 129 curl http://20.121.244.48/hello 130 Hello world from Spin! 131 ``` 132 133 In the preceding output, we see the HTTP response from our Spin microservice, "Hello world from Spin!". 134 135 ### Building a Lunatic, Spin, Slight, or WWS Application 136 At this point, you might be asking "How do I build my own Wasm microservice?" Here are some pointers to help you get started. 137 138 #### Example `lunatic` Application 139 To learn more about building `lunatic` applications, see the [Lunatic README](https://github.com/lunatic-solutions/lunatic#readme). 140 141 #### Example `slight` Application 142 The [`slight` example in deislabs/containerd-wasm-shims repo](https://github.com/deislabs/containerd-wasm-shims/tree/ad323c4e773633630706cf1d354293dec90e61e6/images/slight) demonstrates a project layout for creating a container image consisting of a `slight` `app.wasm` and a `slightfile.toml`, both of which are needed to run the microservice. 143 144 To learn more about building `slight` applications, see [Deislabs Slight](https://github.com/deislabs/spiderlightning). 145 146 #### Example `spin` Application 147 The [`spin` example in deislabs/containerd-wasm-shims repo](https://github.com/deislabs/containerd-wasm-shims/tree/ad323c4e773633630706cf1d354293dec90e61e6/images/spin) demonstrates a project layout for creating a container image consisting of two `spin` apps, `spin_rust_hello.wasm` and `spin_go_hello.wasm`, and a `spin.toml` file. 148 149 To learn more about building `spin` applications, see [Fermyon Spin](https://github.com/fermyon/spin). 150 151 #### Example `wws` Application 152 The [`wws` examples in vmware-labs/wasm-workers-server repo](https://github.com/vmware-labs/wasm-workers-server/tree/main/examples) demonstrate project layouts for `wws` workers in multiple languages. 153 154 To learn more about building `wws` applications, see [VMware Wasm Workers Server](https://workers.wasmlabs.dev/docs/get-started/introduction). 155 156 ### Constraining Scheduling of Wasm Workloads 157 You may have a cluster where not all nodes are able to run Wasm workloads. In this case, you would want to constrain the nodes that are able to have Wasm workloads scheduled. 158 159 If you would like to constrain the nodes that will run the Wasm workloads, you can apply a node label selector to the runtime classes, then apply node labels to the cluster nodes you'd like to run the workloads. 160 161 Create a `wasm-runtimes-constrained.yaml` file with the following contents: 162 163 ```yaml 164 --- 165 apiVersion: node.k8s.io/v1 166 kind: RuntimeClass 167 metadata: 168 name: "wasmtime-lunatic-v1" 169 handler: "lunatic" 170 scheduling: 171 nodeSelector: 172 "cluster.x-k8s.io/wasmtime-lunatic-v1": "true" 173 --- 174 apiVersion: node.k8s.io/v1 175 kind: RuntimeClass 176 metadata: 177 name: "wasmtime-slight-v1" 178 handler: "slight" 179 scheduling: 180 nodeSelector: 181 "cluster.x-k8s.io/wasmtime-slight-v1": "true" 182 --- 183 apiVersion: node.k8s.io/v1 184 kind: RuntimeClass 185 metadata: 186 name: "wasmtime-spin-v2" 187 handler: "spin" 188 scheduling: 189 nodeSelector: 190 "cluster.x-k8s.io/wasmtime-spin-v2": "true" 191 --- 192 apiVersion: node.k8s.io/v1 193 kind: RuntimeClass 194 metadata: 195 name: "wasmtime-wws-v1" 196 handler: "wws" 197 scheduling: 198 nodeSelector: 199 "cluster.x-k8s.io/wasmtime-wws-v1": "true" 200 ``` 201 202 Deploy these resources to your workload cluster: 203 ```bash 204 kubectl --kubeconfig=<workload-kubeconfig> apply -f wasm-runtimes-constrained.yaml 205 ``` 206 207 In the preceding YAML, note the nodeSelector and the label. The Kubernetes scheduler will select nodes with the `cluster.x-k8s.io/wasmtime-lunatic-v1: "true"`, `cluster.x-k8s.io/wasmtime-slight-v1: "true"`, `cluster.x-k8s.io/wasmtime-spin-v2: "true"`, or `cluster.x-k8s.io/wasmtime-wws-v1: "true"` label to determine where to schedule Wasm workloads. 208 209 You will also need to pair the above runtime classes with labels applied to your cluster nodes. To label your nodes, use a command like the following: 210 211 ```bash 212 kubectl --kubeconfig=<workload-kubeconfig> label nodes <your-node-name> <label> 213 ``` 214 215 Once you have applied node labels, you can safely schedule Wasm workloads to a constrained set of nodes in your cluster.