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.