KWasm is a Kubernetes operator that brings WebAssembly (Wasm) runtimes to your cluster nodes. It provisions and manages runtimes like WasmEdge, Wasmtime, and Spin so you can schedule Wasm workloads alongside your regular container pods. When KWasm's operator fails or a node loses its Wasm runtime configuration, your Wasm-based workloads stop scheduling — and Kubernetes has no built-in visibility into whether a RuntimeClass is actually functional on any given node.
In this tutorial you'll set up comprehensive uptime monitoring for your KWasm-enabled Kubernetes cluster using Vigilmon — free tier, no credit card required.
Why KWasm clusters need external monitoring
KWasm extends Kubernetes with a new failure surface that the default control plane doesn't track:
- kwasm-operator pod crashes — no new nodes get Wasm runtimes provisioned; existing Wasm pods keep running but new scheduling requests fail silently
- Node annotation drift — if
kwasm.sh/kwasm-node=trueannotations are removed, the operator stops managing those nodes; Wasm RuntimeClasses on affected nodes become non-functional without any Kubernetes event - DaemonSet installer fails on a node — the
kwasm-node-installerDaemonSet runs on annotated nodes; if it fails, that node cannot schedule Wasm workloads while the node itself showsReady - Wasm runtime binary corruption — the runtime binary (e.g.,
runwasi,spin) on a node may be absent or mismatched; pods using the RuntimeClass get stuck inContainerCreatingindefinitely - RuntimeClass disappears — if the
RuntimeClassobject is accidentally deleted, all pods using it fail to schedule immediately; there is no cluster-level alert for this condition
These failures are particularly subtle because Kubernetes liveness checks confirm container processes are alive, not that the underlying Wasm runtime is functional.
What you'll need
- A Kubernetes cluster with KWasm installed (kwasm-operator running)
- At least one Wasm workload exposed via a Service or Ingress
- A free Vigilmon account (sign up takes 30 seconds)
Step 1: Expose a health endpoint for monitoring
Deploy a Wasm workload with a reachable health route alongside a standard HTTP probe:
# Verify kwasm-operator is running
kubectl get pods -n kwasm -l app.kubernetes.io/name=kwasm-operator
# NAME READY STATUS RESTARTS AGE
# kwasm-operator-7d8f9b4c6-xk2nm 1/1 Running 0 3d
# Check which nodes are Wasm-enabled
kubectl get nodes -l kwasm.sh/kwasm-node=true
# Verify RuntimeClasses exist
kubectl get runtimeclass
# NAME HANDLER AGE
# spin spin 2d
# wasmtime wasmtime 2d
Deploy a lightweight Wasm HTTP service using the Spin runtime (or substitute your runtime):
# wasm-health.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wasm-health
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: wasm-health
template:
metadata:
labels:
app: wasm-health
spec:
runtimeClassName: spin
containers:
- name: health
image: ghcr.io/fermyon/spin-http-go-hello-world:latest
ports:
- containerPort: 3000
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
name: wasm-health
namespace: default
spec:
type: LoadBalancer
selector:
app: wasm-health
ports:
- port: 80
targetPort: 3000
protocol: TCP
kubectl apply -f wasm-health.yaml
# Get the LoadBalancer IP
kubectl get svc wasm-health
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# wasm-health LoadBalancer 10.96.45.100 203.0.113.80 80/TCP 1m
# Verify the Wasm pod scheduled successfully
kubectl get pods -l app=wasm-health -o wide
# NAME READY STATUS NODE
# wasm-health-6d9b4f8c5-abcde 1/1 Running kwasm-node-1
# Confirm it responds
curl http://203.0.113.80/health
# {"status":"ok","runtime":"spin"}
Step 2: Set up HTTP monitoring in Vigilmon
With your Wasm health endpoint exposed, add it to Vigilmon:
- Log in to vigilmon.online and go to Monitors → New Monitor
- Choose HTTP / HTTPS as the type
- Set the URL to your service endpoint:
http://203.0.113.80/health - Set the check interval to 1 minute
- Under Expected response, set:
- Status code:
200 - Response body contains:
"status":"ok"
- Status code:
- Save the monitor
This monitor validates the complete KWasm path: the kwasm-operator must be healthy, the RuntimeClass must exist, the node installer must have provisioned the runtime, the pod must have scheduled, and the Wasm binary must be executing — all for a 200 to reach Vigilmon.
Why external monitoring catches what Kubernetes misses
Kubernetes reports pod phase (Running, Pending) but cannot validate that a Wasm module is actually executing correctly. A pod in ContainerCreating limbo due to a missing runtime shows no error in kubectl get pods until you inspect events. Vigilmon's multi-region consensus probes from independent geographic locations and only fires when multiple probes agree — eliminating false positives from transient network conditions while catching real Wasm scheduling failures within minutes.
Step 3: Monitor TCP ports and the kwasm-operator
Add monitors to detect failures at multiple layers:
Service TCP check:
- Go to Monitors → New Monitor
- Choose TCP Port
- Enter: Host
203.0.113.80, Port80 - Save the monitor
kwasm-operator API health:
The kwasm-operator exposes a metrics endpoint you can optionally proxy for monitoring:
# Port-forward to the operator metrics
kubectl port-forward -n kwasm svc/kwasm-operator 8080:8080
# Check operator health
curl http://localhost:8080/healthz
# ok
Expose the operator health endpoint via an Ingress or internal service if you want continuous monitoring, then add it as an HTTP monitor in Vigilmon.
Node-level Wasm validation:
Use a CronJob to validate that RuntimeClasses are functional on each node and push a heartbeat to Vigilmon when successful:
# wasm-validator-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: wasm-runtime-validator
namespace: default
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
runtimeClassName: spin
restartPolicy: Never
containers:
- name: validator
image: curlimages/curl:latest
command:
- sh
- -c
- |
curl -fsS https://uptime.vigilmon.online/api/v1/heartbeat/YOUR_HEARTBEAT_KEY
kubectl apply -f wasm-validator-cronjob.yaml
Step 4: Configure alert channels
KWasm failures are invisible until users report that Wasm-based services are down. Alert fast.
Email alerts
- In Vigilmon, go to Alert Channels → Add Channel → Email
- Enter your platform team's on-call email
- Assign the channel to all KWasm monitors
Webhook alerts (Slack, PagerDuty, etc.)
- Go to Alert Channels → Add Channel → Webhook
- Enter your webhook URL
- Assign the channel to your monitors
Example payload when the Wasm health endpoint goes down:
{
"monitor_name": "KWasm Wasm Health",
"status": "down",
"url": "http://203.0.113.80/health",
"started_at": "2024-01-15T14:30:00Z",
"duration_seconds": 120
}
Run these diagnostics when an alert fires:
# Check kwasm-operator
kubectl get pods -n kwasm
kubectl logs -n kwasm -l app.kubernetes.io/name=kwasm-operator --tail=100
# Check RuntimeClasses
kubectl get runtimeclass
kubectl describe runtimeclass spin
# Check node installer DaemonSet
kubectl get daemonset -n kwasm
kubectl get pods -n kwasm -l app=kwasm-node-installer -o wide
# Check Wasm pod events
kubectl describe pod -l app=wasm-health | grep -A10 Events
# Check node installer logs on a specific node
kubectl logs -n kwasm -l app=kwasm-node-installer --field-selector spec.nodeName=kwasm-node-1 --tail=50
Step 5: Create a public status page
Wasm-backed services may serve external users. Give them visibility during incidents.
- In Vigilmon, go to Status Pages → New Status Page
- Give it a name: "KWasm Runtime Status"
- Add your monitors: Wasm Health HTTP, Service TCP, Heartbeat
- Group them: Wasm Services, Runtime Infrastructure, Scheduler Health
- Publish the page
Share this URL with your development teams and any external users of Wasm-backed services.
Putting it all together
Here's a summary of the monitors to create for a KWasm cluster:
| Monitor | Type | What it catches |
|---------|------|-----------------|
| http://203.0.113.80/health | HTTP | Full Wasm execution path (operator → RuntimeClass → pod → binary → response) |
| 203.0.113.80:80 | TCP | Service reachability |
| kwasm-operator /healthz | HTTP | Operator health; new node provisioning ability |
| Wasm validator heartbeat | Heartbeat | Wasm scheduling still works on cluster nodes |
And the KWasm diagnostics to run when an alert fires:
# Triage: operator or runtime?
kubectl get pods -n kwasm
kubectl get runtimeclass
# Is the installer healthy on all nodes?
kubectl get pods -n kwasm -l app=kwasm-node-installer -o wide
# Did any Wasm pods get stuck?
kubectl get pods -A -o wide | grep -v Running | grep -v Completed
# Check node-level runtime binaries
kubectl debug node/kwasm-node-1 -it --image=busybox -- \
ls -la /usr/local/bin/containerd-shim-spin-v2
What's next
- SSL certificate monitoring — add SSL monitors for any HTTPS Wasm services
- Heartbeat monitoring — use Vigilmon heartbeats to verify your Wasm validator CronJobs run on schedule
- Multi-runtime coverage — create separate monitors for each RuntimeClass (spin, wasmtime, wasmedge) to isolate which runtime is failing
Get started free at vigilmon.online — no credit card, monitors start running in under a minute.