Deploying wasmCloud on Kubernetes
wasmCloud is compatible with, but not dependent on, Kubernetes. We think the future of WebAssembly is bright, and we also know there are plenty of systems already running in Kubernetes. For this reason, we provide the wasmCloud operator to help users run wasmCloud hosts on a Kubernetes cluster—and thereby run WebAssembly components on Kubernetes.
For high-level discussion of our approach to Kubernetes and compatibility with common cloud native tooling, see wasmCloud on Kubernetes.
On this page, you can find documentation for operators wishing to deploy wasmCloud with Kubernetes, including details on prerequisites such as NATS and how to deploy the operator.
When running wasmCloud on Kubernetes, you can use kubectl
to deploy wasmCloud manifests, check wasmCloud logs, and more. The example below demonstrates standard usage of kubectl
with wasmCloud.
Getting started with the wasmCloud operator
The wasmCloud operator can be found on GitHub at https://github.com/wasmCloud/wasmcloud-operator and enables...
- Deployment of wasmCloud Hosts onto a Kubernetes cluster via Custom Resource Definition (
WasmCloudHostConfig
) - Interoperability with the wasmCloud Application Deployment Manager (wadm) for deploying wasmcloud applications defined in the OAM spec format.
- Automated creation of Kubernetes Services pointing to wasmCloud applications deployed with a HTTP Server capability (in the future this will become configurable—today it's automatic).
In order to follow the instructions on this page, you will need a Kubernetes cluster and appropriate access credentials as well as a Helm installation. It will also be useful to have wasmCloud Shell (wash
) installed locally.
You can watch a video of the setup on YouTube:
Deploying the operator
A wasmCloud cluster requires a few things to run:
- A NATS cluster (with Jetstream enabled)
- wasmCloud Application Deployment Manager (wadm) connected to the NATS cluster in order to support deploying wasmCloud applications
If you are running Kubernetes locally, the following steps will help you start a NATS cluster and wadm in your Kubernetes cluster, then deploy the operator.
Deploy NATS
Add the NATS Helm repo:
helm repo add nats https://nats-io.github.io/k8s/helm/charts/
Install the upstream NATS Helm chart to start a cluster with the values.yaml
file from the quickstart:
helm upgrade --install -f https://raw.githubusercontent.com/wasmCloud/wasmcloud-operator/main/examples/quickstart/nats-values.yaml nats nats/nats
Validate the installation with:
kubectl rollout status deploy,sts -l app.kubernetes.io/instance=nats
Deploy wadm
You can deploy wadm to your Kubernetes cluster with a Helm chart hosted by wasmCloud.
helm install wadm -f https://raw.githubusercontent.com/wasmCloud/wasmcloud-operator/main/examples/quickstart/wadm-values.yaml oci://ghcr.io/wasmcloud/charts/wadm
Validate the installation with:
kubectl rollout status deploy -l app.kubernetes.io/instance=wadm
Deploy the operator
To deploy the operator:
kubectl apply -k https://github.com/wasmCloud/wasmcloud-operator/deploy/base
Validate the installation with:
# make sure pods are ready
kubectl rollout status deploy -l app=wasmcloud-operator -n wasmcloud-operator
# apiservice should be available
kubectl get apiservices.apiregistration.k8s.io v1beta1.core.oam.dev
Create wasmCloud hosts
Apply the wasmcloud-host
manifest:
kubectl apply -f https://raw.githubusercontent.com/wasmCloud/wasmcloud-operator/main/examples/quickstart/wasmcloud-host.yaml
Check wasmCloud host status:
kubectl describe wasmcloudhostconfig wasmcloud-host
You can also check logs for a given host with:
kubectl logs -f -l app.kubernetes.io/instance=my-wasmcloud-cluster -c wasmcloud-host
Deploying a workload
When you kubectl apply
a wasmCloud application manifest, the cluster will automatically provision the component workload with wasmCloud. Below is the hello-world-application.yaml
manifest included in the quickstart:
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: hello-world
annotations:
version: v0.0.1
description: 'HTTP hello world demo in Rust, using the WebAssembly Component Model and WebAssembly Interfaces Types (WIT)'
wasmcloud.dev/authors: wasmCloud team
wasmcloud.dev/source-url: https://github.com/wasmCloud/wasmCloud/blob/main/examples/rusg/components/http-hello-world/wadm.yaml
wasmcloud.dev/readme-md-url: https://github.com/wasmCloud/wasmCloud/blob/main/examples/rusg/components/http-hello-world/README.md
wasmcloud.dev/homepage: https://github.com/wasmCloud/wasmCloud/tree/main/examples/rusg/components/http-hello-world
wasmcloud.dev/categories: |
http,http-server,rust,hello-world,example
spec:
components:
- name: http-component
type: component
properties:
image: ghcr.io/wasmcloud/components/http-hello-world-rust:0.1.0
traits:
# Govern the spread/scheduling of the component
- type: spreadscaler
properties:
replicas: 1
# Add a capability provider that enables HTTP access
- name: httpserver
type: capability
properties:
image: ghcr.io/wasmcloud/http-server:0.22.0
traits:
# Establish a unidirectional link from this http server provider (the "source")
# to the `http-component` component (the "target") so the component can handle incoming HTTP requests,
#
# The source (this provider) is configured such that the HTTP server listens on 127.0.0.1:8080
- type: link
properties:
target: http-component
namespace: wasi
package: http
interfaces: [incoming-handler]
source_config:
- name: default-http
properties:
address: 0.0.0.0:8080
Run kubectl apply
:
kubectl apply -f https://raw.githubusercontent.com/wasmCloud/wasmcloud-operator/main/examples/quickstart/hello-world-application.yaml
Check the deployment status:
kubectl get application
APPLICATION DEPLOYED VERSION LATEST VERSION STATUS
hello-world v0.0.1 v0.0.1 Deployed
When you run a wasmCloud application that uses the httpserver
provider with a daemonscaler, as this one does, the operator automatically creates a Kubernetes service for the application.
View services:
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world ClusterIP 10.96.199.43 <none> 8080/TCP 11s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6m29s
nats ClusterIP 10.96.104.180 <none> 4222/TCP,7422/TCP,4223/TCP 5m36s
nats-headless ClusterIP None <none> 4222/TCP,7422/TCP,4223/TCP,6222/TCP,8222/TCP 5m36s
wasmcloud-host ClusterIP 10.96.67.225 <none> 4222/TCP 84s
Test the application
On a cluster without ingress (such as this one), you can still test the component from within the wasmCloud host container where the application is running.
Assign the wasmCloud host pod name to an environment variable:
WASMCLOUD_HOST_POD=$(kubectl get pods -o jsonpath="{.items[*].metadata.name}" -l app.kubernetes.io/instance=wasmcloud-host)
Port-forward the wasmCloud host's port 8080:
kubectl port-forward pods/$WASMCLOUD_HOST_POD 8080
curl
the application:
curl http://localhost:8080
Manage applications with wash
Port-forward into the NATS service running in your Kubernetes cluster. 4222
is the port for the NATS service, 4223
is the port for NATS websockets.
kubectl port-forward svc/nats 4222:4222 4223:4223
Now you can connect to wasmCloud on Kubernetes with your local wash toolchain:
wash app list
Optional configuration
Image pull secrets (Optional)
You can also specify an image pull secret to use use with the wasmCloud hosts so that they can pull components from a private registry. This secret needs to be in the same namespace as the WasmCloudHostConfig CRD and must be a
kubernetes.io/dockerconfigjson
type secret. See the Kubernetes documentation for more information on how to provision that secret.
Once it is created, you can reference an image pull secret in the WasmCloudHostConfig
CRD by
setting the registryCredentialsSecret
field to the name of the secret.
Argo CD Health Check (Optional)
Argo CD provides a way to define a custom health check that it then runs against a given resource to determine whether or not the resource is in healthy state.
For this purpose, we specifically expose a status.phase
field, which exposes the underlying status information from wadm.
With the following ConfigMap, a custom health check can be added to an existing Argo CD installation for tracking the health of wadm applications.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
labels:
app.kubernetes.io/name: argocd-cm
app.kubernetes.io/part-of: argocd
data:
resource.customizations: |
core.oam.dev/Application:
health.lua: |
hs = {}
hs.status = "Progressing"
hs.message = "Reconciling application state"
if obj.status ~= nil and obj.status.phase ~= nil then
if obj.status.phase == "Deployed" then
hs.status = "Healthy"
hs.message = "Application is ready"
end
if obj.status.phase == "Reconciling" then
hs.status = "Progressing"
hs.message = "Application has been deployed"
end
if obj.status.phase == "Failed" then
hs.status = "Degraded"
hs.message = "Application failed to deploy"
end
if obj.status.phase == "Undeployed" then
hs.status = "Suspended"
hs.message = "Application is undeployed"
end
end
return hs