Skip to content

Commit 7fd2a4e

Browse files
authored
Merge pull request #215068 from zr-msft/zr-aks-udpate-wasm
[AKS]: updates wasiwasm nodeools doc
2 parents d2b74f7 + 0993cc6 commit 7fd2a4e

File tree

1 file changed

+90
-148
lines changed

1 file changed

+90
-148
lines changed

articles/aks/use-wasi-node-pools.md

Lines changed: 90 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,23 @@ title: Create WebAssembly System Interface(WASI) node pools in Azure Kubernetes
33
description: Learn how to create a WebAssembly System Interface(WASI) node pool in Azure Kubernetes Service (AKS) to run your WebAssembly(WASM) workload on Kubernetes.
44
services: container-service
55
ms.topic: article
6-
ms.date: 10/12/2021
6+
ms.date: 10/19/2022
77
---
88

99
# Create WebAssembly System Interface (WASI) node pools in Azure Kubernetes Service (AKS) to run your WebAssembly (WASM) workload (preview)
1010

11-
[WebAssembly (WASM)][wasm] is a binary format that is optimized for fast download and maximum execution speed in a WASM runtime. A WASM runtime is designed to run on a target architecture and execute WebAssemblies in a sandbox, isolated from the host computer, at near-native performance. By default, WebAssemblies can't access resources on the host outside of the sandbox unless it is explicitly allowed, and they can't communicate over sockets to access things environment variables or HTTP traffic. The [WebAssembly System Interface (WASI)][wasi] standard defines an API for WASM runtimes to provide access to WebAssemblies to the environment and resources outside the host using a capabilities model. [Krustlet][krustlet] is an open-source project that allows WASM modules to be run on Kubernetes. Krustlet creates a kubelet that runs on nodes with a WASM/WASI runtime. AKS allows you to create node pools that run WASM assemblies using nodes with WASM/WASI runtimes and Krustlets.
11+
[WebAssembly (WASM)][wasm] is a binary format that is optimized for fast download and maximum execution speed in a WASM runtime. A WASM runtime is designed to run on a target architecture and execute WebAssemblies in a sandbox, isolated from the host computer, at near-native performance. By default, WebAssemblies can't access resources on the host outside of the sandbox unless it is explicitly allowed, and they can't communicate over sockets to access things environment variables or HTTP traffic. The [WebAssembly System Interface (WASI)][wasi] standard defines an API for WASM runtimes to provide access to WebAssemblies to the environment and resources outside the host using a capabilities model.
12+
13+
> [!IMPORTANT]
14+
> WASI nodepools now use [containerd shims][wasm-containerd-shims] to run WASM workloads. Previously, AKS used [Krustlet][krustlet] to allow WASM modules to be run on Kubernetes. If you are still using Krustlet-based WASI nodepools, you can migrate to containerd shims by creating a new WASI nodepool and migrating your workloads to the new nodepool.
1215
1316
## Before you begin
1417

1518
WASM/WASI node pools are currently in preview.
1619

1720
[!INCLUDE [preview features callout](./includes/preview/preview-callout.md)]
1821

19-
This article uses [Helm 3][helm] to install the *nginx* chart on a supported version of Kubernetes. Make sure that you are using the latest release of Helm and have access to the *bitnami* Helm repository. The steps outlined in this article may not be compatible with previous versions of the Helm chart or Kubernetes.
20-
21-
You must also have the following resource installed:
22-
23-
* The latest version of the Azure CLI.
24-
* The `aks-preview` extension version 0.5.34 or later
22+
You must also have the latest version of the Azure CLI and `aks-preview` extension installed.
2523

2624
### Register the `WasmNodePoolPreview` preview feature
2725

@@ -59,12 +57,11 @@ az extension update --name aks-preview
5957

6058
### Limitations
6159

62-
* You can't run WebAssemblies and containers in the same node pool.
63-
* Only the WebAssembly(WASI) runtime is available, using the Wasmtime provider.
60+
* Currently, there are only containerd shims available for [spin][spin] and [slight][slight] applications, which use the [wasmtime][wasmtime] runtime. In addition to wasmtime runtime applications, you can also run containers on WASI/WASM node pools.
61+
* You can run containers and wasm modules on the same node, but you can't run containers and wasm modules on the same pod.
6462
* The WASM/WASI node pools can't be used for system node pool.
6563
* The *os-type* for WASM/WASI node pools must be Linux.
66-
* Krustlet doesn't work with Azure CNI at this time. For more information, see the [CNI Support for Kruslet GitHub issue][krustlet-cni-support].
67-
* Krustlet doesn't provide networking configuration for WebAssemblies. The WebAssembly manifest must provide the networking configuration, such as IP address.
64+
* You can't use the Azure portal to create WASM/WASI node pools.
6865

6966
## Add a WASM/WASI node pool to an existing AKS Cluster
7067

@@ -76,7 +73,7 @@ az aks nodepool add \
7673
--cluster-name myAKSCluster \
7774
--name mywasipool \
7875
--node-count 1 \
79-
--workload-runtime wasmwasi
76+
--workload-runtime WasmWasi
8077
```
8178

8279
> [!NOTE]
@@ -85,25 +82,16 @@ az aks nodepool add \
8582
Verify the *workloadRuntime* value using `az aks nodepool show`. For example:
8683

8784
```azurecli-interactive
88-
az aks nodepool show -g myResourceGroup --cluster-name myAKSCluster -n mywasipool
85+
az aks nodepool show -g myResourceGroup --cluster-name myAKSCluster -n mywasipool --query workloadRuntime
8986
```
9087

9188
The following example output shows the *mywasipool* has the *workloadRuntime* type of *WasmWasi*.
9289

9390
```output
94-
{
95-
...
96-
"name": "mywasipool",
97-
..
98-
"workloadRuntime": "WasmWasi"
99-
}
91+
$ az aks nodepool show -g myResourceGroup --cluster-name myAKSCluster -n mywasipool --query workloadRuntime
92+
"WasmWasi"
10093
```
10194

102-
For a WASM/WASI node pool, verify the taint is set to `kubernetes.io/arch=wasm32-wagi:NoSchedule` and `kubernetes.io/arch=wasm32-wagi:NoExecute`, which will prevent container pods from being scheduled on this node pool. Also, you should see nodeLabels to be `kubernetes.io/arch: wasm32-wasi`, which prevents WASM pods from being scheduled on regular container(OCI) node pools.
103-
104-
> [!NOTE]
105-
> The taints for a WASI node pool are not visible using `az aks nodepool list`. Use `kubectl` to verify the taints are set on the nodes in the WASI node pool.
106-
10795
Configure `kubectl` to connect to your Kubernetes cluster using the [az aks get-credentials][az-aks-get-credentials] command. The following command:
10896

10997
```azurecli
@@ -114,14 +102,12 @@ Use `kubectl get nodes` to display the nodes in your cluster.
114102

115103
```output
116104
$ kubectl get nodes -o wide
117-
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
118-
aks-mywasipool-12456878-vmss000000 Ready agent 9m 1.0.0-alpha.1 WASINODE_IP <none> <unknown> <unknown> mvp
119-
aks-nodepool1-12456878-vmss000000 Ready agent 13m v1.20.9 NODE1_IP <none> Ubuntu 18.04.6 LTS 5.4.0-1059-azure containerd://1.4.9+azure
105+
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
106+
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
107+
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
120108
```
121109

122-
Save the value of *WASINODE_IP* as it is used in later step.
123-
124-
Use `kubectl describe node` to show the labels and taints on a node in the WASI node pool. The following example shows the details of *aks-mywasipool-12456878-vmss000000*.
110+
Use `kubectl describe node` to show the labels on a node in the WASI node pool. The following example shows the details of *aks-mywasipool-12456878-vmss000000*.
125111

126112
```output
127113
$ kubectl describe node aks-mywasipool-12456878-vmss000000
@@ -130,159 +116,112 @@ Name: aks-mywasipool-12456878-vmss000000
130116
Roles: agent
131117
Labels: agentpool=mywasipool
132118
...
133-
kubernetes.io/arch=wasm32-wagi
119+
kubernetes.azure.com/wasmtime-slight-v1=true
120+
kubernetes.azure.com/wasmtime-spin-v1=true
134121
...
135-
Taints: kubernetes.io/arch=wasm32-wagi:NoExecute
136-
kubernetes.io/arch=wasm32-wagi:NoSchedule
137122
```
138123

139-
140-
## Running WASM/WASI Workload
141-
142-
To run a workload on a WASM/WASI node pool, add a node selector and tolerations to your deployment. For example:
124+
Add a `RuntimeClass` for running [spin][spin] and [slight][slight] applications. Create a file named *wasm-runtimeclass.yaml* with the following content:
143125

144126
```yml
145-
...
146-
spec:
127+
apiVersion: node.k8s.io/v1
128+
kind: RuntimeClass
129+
metadata:
130+
name: "wasmtime-slight-v1"
131+
handler: "slight"
132+
scheduling:
147133
nodeSelector:
148-
kubernetes.io/arch: "wasm32-wagi"
149-
tolerations:
150-
- key: "node.kubernetes.io/network-unavailable"
151-
operator: "Exists"
152-
effect: "NoSchedule"
153-
- key: "kubernetes.io/arch"
154-
operator: "Equal"
155-
value: "wasm32-wagi"
156-
effect: "NoExecute"
157-
- key: "kubernetes.io/arch"
158-
operator: "Equal"
159-
value: "wasm32-wagi"
160-
effect: "NoSchedule"
161-
...
162-
```
163-
164-
To run a sample deployment, create a `wasi-example.yaml` file using the following YAML definition:
165-
166-
```yml
167-
apiVersion: v1
168-
kind: Pod
134+
"kubernetes.azure.com/wasmtime-slight-v1": "true"
135+
---
136+
apiVersion: node.k8s.io/v1
137+
kind: RuntimeClass
169138
metadata:
170-
name: krustlet-wagi-demo
171-
labels:
172-
app: krustlet-wagi-demo
173-
annotations:
174-
alpha.wagi.krustlet.dev/default-host: "0.0.0.0:3001"
175-
alpha.wagi.krustlet.dev/modules: |
176-
{
177-
"krustlet-wagi-demo-http-example": {"route": "/http-example", "allowed_hosts": ["https://api.brigade.sh"]},
178-
"krustlet-wagi-demo-hello": {"route": "/hello/..."},
179-
"krustlet-wagi-demo-error": {"route": "/error"},
180-
"krustlet-wagi-demo-log": {"route": "/log"},
181-
"krustlet-wagi-demo-index": {"route": "/"}
182-
}
183-
spec:
184-
hostNetwork: true
139+
name: "wasmtime-spin-v1"
140+
handler: "spin"
141+
scheduling:
185142
nodeSelector:
186-
kubernetes.io/arch: wasm32-wagi
187-
containers:
188-
- image: webassembly.azurecr.io/krustlet-wagi-demo-http-example:v1.0.0
189-
imagePullPolicy: Always
190-
name: krustlet-wagi-demo-http-example
191-
- image: webassembly.azurecr.io/krustlet-wagi-demo-hello:v1.0.0
192-
imagePullPolicy: Always
193-
name: krustlet-wagi-demo-hello
194-
- image: webassembly.azurecr.io/krustlet-wagi-demo-index:v1.0.0
195-
imagePullPolicy: Always
196-
name: krustlet-wagi-demo-index
197-
- image: webassembly.azurecr.io/krustlet-wagi-demo-error:v1.0.0
198-
imagePullPolicy: Always
199-
name: krustlet-wagi-demo-error
200-
- image: webassembly.azurecr.io/krustlet-wagi-demo-log:v1.0.0
201-
imagePullPolicy: Always
202-
name: krustlet-wagi-demo-log
203-
tolerations:
204-
- key: "node.kubernetes.io/network-unavailable"
205-
operator: "Exists"
206-
effect: "NoSchedule"
207-
- key: "kubernetes.io/arch"
208-
operator: "Equal"
209-
value: "wasm32-wagi"
210-
effect: "NoExecute"
211-
- key: "kubernetes.io/arch"
212-
operator: "Equal"
213-
value: "wasm32-wagi"
214-
effect: "NoSchedule"
143+
"kubernetes.azure.com/wasmtime-spin-v1": "true"
215144
```
216145
217-
Use `kubectl` to run your example deployment:
146+
Use `kubectl` to create the `RuntimeClass` objects.
218147

219148
```azurecli-interactive
220-
kubectl apply -f wasi-example.yaml
149+
kubectl apply -f wasm-runtimeclass.yaml
221150
```
222151

223-
> [!NOTE]
224-
> The pod for the example deployment may stay in the *Registered* status. This behavior is expected, and you and proceed to the next step.
152+
## Running WASM/WASI Workload
225153

226-
Create `values.yaml` using the example yaml below, replacing *WASINODE_IP* with the value from the earlier step.
154+
Create a file named *slight.yaml* with the following content:
227155

228156
```yml
229-
serverBlock: |-
230-
server {
231-
listen 0.0.0.0:8080;
232-
location / {
233-
proxy_pass http://WASINODE_IP:3001;
234-
}
235-
}
157+
apiVersion: apps/v1
158+
kind: Deployment
159+
metadata:
160+
name: wasm-slight
161+
spec:
162+
replicas: 1
163+
selector:
164+
matchLabels:
165+
app: wasm-slight
166+
template:
167+
metadata:
168+
labels:
169+
app: wasm-slight
170+
spec:
171+
runtimeClassName: wasmtime-slight-v1
172+
containers:
173+
- name: testwasm
174+
image: ghcr.io/deislabs/containerd-wasm-shims/examples/slight-rust-hello:latest
175+
command: ["/"]
176+
---
177+
apiVersion: v1
178+
kind: Service
179+
metadata:
180+
name: wasm-slight
181+
spec:
182+
type: LoadBalancer
183+
ports:
184+
- protocol: TCP
185+
port: 80
186+
targetPort: 80
187+
selector:
188+
app: wasm-slight
236189
```
237190

238-
Using [Helm][helm], add the *bitnami* repository and install the *nginx* chart with the `values.yaml` file you created in the previous step. Installing NGINX with the above `values.yaml` creates a reverse proxy to the example deployment, allowing you to access it using an external IP address.
191+
> [!NOTE]
192+
> When developing applications, modules should be build against the `wasm32-wasi` target. For more details, see the [spin][spin] and [slight][slight] documentation.
239193

240-
>[!NOTE]
241-
> The following example pulls a public container image from Docker Hub. We recommend that you set up a pull secret to authenticate using a Docker Hub account instead of making an anonymous pull request. To improve reliability when working with public content, import and manage the image in a private Azure container registry. [Learn more about working with public images.][dockerhub-callout]
194+
Use `kubectl` to run your example deployment:
242195

243-
```console
244-
helm repo add bitnami https://charts.bitnami.com/bitnami
245-
helm repo update
246-
helm install hello-wasi bitnami/nginx -f values.yaml
196+
```azurecli-interactive
197+
kubectl apply -f slight.yaml
247198
```
248199

249-
Use `kubectl get service` to display the external IP address of the *hello-wasi-ngnix* service.
200+
Use `kubectl get svc` to get the external IP address of the service.
250201

251202
```output
252-
$ kubectl get service
253-
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
254-
hello-wasi-nginx LoadBalancer 10.0.58.239 EXTERNAL_IP 80:32379/TCP 112s
255-
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 145m
256-
```
257-
258-
Verify the example deployment is running by the `curl` command against the `/hello` path of *EXTERNAL_IP*.
259-
260-
```azurecli-interactive
261-
curl EXTERNAL_IP/hello
203+
$ kubectl get svc
204+
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
205+
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 10m
206+
wasm-slight LoadBalancer 10.0.133.247 <EXTERNAL-IP> 80:30725/TCP 2m47s
262207
```
263208

264-
The follow example output confirms the example deployment is running.
209+
Access the example application at `http://EXTERNAL-IP/hello`. The following example uses `curl`.
265210

266211
```output
267-
$ curl EXTERNAL_IP/hello
268-
hello world
212+
$ curl http://EXTERNAL-IP/hello
213+
hello
269214
```
270215

271-
> [!NOTE]
272-
> To publish the service on your own domain, see [Azure DNS][azure-dns-zone] and the [external-dns][external-dns] project.
216+
> [!NOTE]
217+
> If your request times out, use `kubectl get pods` and `kubectl describe pod <POD_NAME>` to check the status of the pod. If the pod is not running, use `kubectl get rs` and `kubectl describe rs <REPLICA_SET_NAME>` to see if the replica set is having issues creating a new pod.
273218

274219
## Clean up
275220

276-
To remove NGINX, use `helm delete`.
277-
278-
```console
279-
helm delete hello-wasi
280-
```
281-
282221
To remove the example deployment, use `kubectl delete`.
283222

284223
```azurecli-interactive
285-
kubectl delete -f wasi-example.yaml
224+
kubectl delete -f slight.yaml
286225
```
287226

288227
To remove the WASM/WASI node pool, use `az aks nodepool delete`.
@@ -300,7 +239,10 @@ az aks nodepool delete --name mywasipool -g myresourcegroup --cluster-name myaks
300239
[wasi]: https://wasi.dev/
301240
[azure-dns-zone]: https://azure.microsoft.com/services/dns/
302241
[external-dns]: https://github.com/kubernetes-sigs/external-dns
303-
242+
[wasm-containerd-shims]: https://github.com/deislabs/containerd-wasm-shims
243+
[spin]: https://spin.fermyon.dev/
244+
[slight]: https://github.com/deislabs/spiderlightning#spiderlightning-or-slight
245+
[wasmtime]: https://wasmtime.dev/
304246
<!-- INTERNAL LINKS -->
305247

306248
[az-aks-create]: /cli/azure/aks#az_aks_create

0 commit comments

Comments
 (0)