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 users wishing to deploy wasmCloud with Kubernetes, including details on prerequisites such as NATS, different strategies for deploying the platform, and how to deploy the wasmCloud operator.
The wasmCloud platform on Kubernetes
As deployed on Kubernetes, the wasmCloud platform consists of three core parts:
- wasmCloud host(s) - Runtime environment for WebAssembly components
- NATS with Jetstream - Connective technology underlying the wasmCloud lattice
- wasmCloud Application Deployment Manager (
wadm
) - Scheduler for application lifecycle management
Deployment with Helm
Helm is commonly understood as a package manager for Kubernetes, enabling platform teams to install and manage software on Kubernetes clusters. Deployments are defined in declarative charts that describe the relationship between various Kubernetes resources.
The wasmCloud project has chosen to embrace Helm as the tool for managing wasmCloud on Kubernetes. We also provide an optional wasmCloud Operator to facilitate smoother automation of the platform. Kubernetes Operators automate the management of complex, stateful applications, continuously monitoring the state of custom resources and making real-time adjustments to align the actual state with the desired state specified by the user.
When deploying wasmCloud to Kubernetes with Helm, NATS and wadm
are provisioned by the wasmcloud-platform
chart. The final part of the deployment—a wasmCloud host—is added through one of two mutually exclusive sub-charts:
By default, the wasmcloud-platform
chart deploys hosts using the operator, but it may be easily configured to use the more "manual" wasmcloud-host
subchart instead. This choice distinguishes the two primary patterns for deploying and operating the wasmCloud platform on Kubernetes:
- Platform and operator
- Platform-only
We generally recommend that teams use the platform and operator pattern, but both of these patterns have their own use-cases and strengths that teams should consider when planning a deployment.
Platform and operator
The platform and operator pattern is the preferred strategy for deploying wasmCloud on Kubernetes, since it automates much of the platform's management and functionality. Kubernetes operators use Custom Resource Definitions (CRDs) to extend the Kubernetes API and manage applications in a Kubernetes-native way.
The wasmCloud operator can be found on GitHub at https://github.com/wasmCloud/wasmcloud-operator and enables the following:
- Declarative wasmCloud management via Custom Resource Definitions (CRDs), with wasmCloud hosts managed by the
WasmCloudHostConfig
CRD, encoding best practices for deploying wasmCloud hosts - Interoperability with the wasmCloud Application Deployment Manager (wadm) for deploying wasmcloud applications defined in the OAM spec format, so that a wasmCloud application can be deployed with a single
kubectl apply
- Kubernetes services integration, automatically creating services for wasmCloud applications deployed with a HTTP Server capability (in the future this will become configurable).
Deploying the platform and operator
In order to follow the instructions on this page, you will need a Kubernetes (>=1.24.0) cluster and appropriate access credentials as well as a Helm (>=3.8.0) installation. It will also be useful to have wasmCloud Shell (wash
) installed locally.
In order to deploy wasmCloud in the platform and operator pattern, first install the wasmcloud-platform
Helm chart. By default, the chart installs NATS, wadm
, and the wasmCloud operator subchart.
helm upgrade --install \
wasmcloud-platform \
--values https://raw.githubusercontent.com/wasmCloud/wasmcloud/main/charts/wasmcloud-platform/values.yaml \
oci://ghcr.io/wasmcloud/charts/wasmcloud-platform \
--dependency-update
Wait for all components to install and wadm-nats
communications to establish:
kubectl rollout status deploy,sts -l app.kubernetes.io/name=nats
kubectl wait --for=condition=available --timeout=600s deploy -l app.kubernetes.io/name=wadm
kubectl wait --for=condition=available --timeout=600s deploy -l app.kubernetes.io/name=wasmcloud-operator
Next create a wasmCloud host:
helm upgrade --install \
wasmcloud-platform \
--values https://raw.githubusercontent.com/wasmCloud/wasmcloud/main/charts/wasmcloud-platform/values.yaml \
oci://ghcr.io/wasmcloud/charts/wasmcloud-platform \
--dependency-update \
--set "hostConfig.enabled=true"
If the deployment is successful, you should receive the note:
✨ Congratulations! Your wasmCloud platform has been deployed successfully.
- 🛀 To use the wash cli with your new wasmCloud platform, run:
kubectl port-forward service/nats 4222:4222 4223:4223
- 🗺️ To launch the wasmCloud dashboard on http://localhost:3030, in a different terminal window, run:
wash ui
If you'd like, you can check wasmCloud host status:
kubectl describe wasmcloudhostconfig wasmcloud-host
Run a WebAssembly component on Kubernetes
When you kubectl apply
a wasmCloud application manifest, the cluster automatically provisions the component workload with wasmCloud.
This example uses the hello-world-application.yaml
manifest included in the operator's quickstart. (The source code for the application is available in the wasmCloud repository.)
Below is an excerpt of the manifest:
...
spec:
components:
- name: http-component
type: component
properties:
image: ghcr.io/wasmcloud/components/http-hello-world-rust:0.1.0
...
The component is packaged as an OCI artifact and specified in the image
field. This isn't a container, but a component conforming to OCI standards, meaning that it can be used with existing registries for container images.
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.105.170.131 <none> 8080/TCP 2m53s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m39s
nats ClusterIP 10.102.201.180 <none> 4222/TCP,7422/TCP,4223/TCP 7m54s
nats-headless ClusterIP None <none> 4222/TCP,7422/TCP,4223/TCP,6222/TCP,8222/TCP 7m54s
wasmcloud-host ClusterIP 10.102.144.92 <none> 4222/TCP 6m32s
wasmcloud-operator ClusterIP 10.96.73.87 <none> 8443/TCP 7m54s
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
You should get the response:
Hello from Rust!
Debugging
You can use kubectl
to get logs from the wasmCloud host running on your kind cluster:
kubectl logs -l app.kubernetes.io/instance=wasmcloud-host -c wasmcloud-host
Common mistakes
- If you're having trouble deploying an application, make sure your wadm application manifest references an OCI image and not a local file.
- If a service is not automatically generated for an application using the httpserver provider, check to ensure that the provider uses
daemonscaler
in the application manifest. (You can see an example of this in thehello-world-application
manifest.)
Manage applications with wash
Connect your local wash
with the wasmCloud deployment. 4222
is the port for the NATS service and 4223
is the port for NATS websockets.
kubectl port-forward service/nats 4222:4222 4223:4223
Now you can use your local wash
toolchain with your wasmCloud deployment:
wash get inventory
The output should look like this:
Host labels
hostcore.arch aarch64
hostcore.os linux
hostcore.osfamily unix
kubernetes true
Component ID Name Max count
hello_world-http_component http-hello-world 1
Provider ID Name
hello_world-httpserver http-server-provider
You can watch a video of operator deployment on YouTube:
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
Platform-only
The platform-only pattern is intended for organizational environments in which the use of Kubernetes operators is restricted.
In order to deploy wasmCloud in the platform-only pattern, first install the wasmcloud-platform
Helm chart with the operator.enabled
value set to false
:
helm upgrade --install \
wasmcloud-platform \
--values https://raw.githubusercontent.com/wasmCloud/wasmcloud/main/charts/wasmcloud-platform/values.yaml \
oci://ghcr.io/wasmcloud/charts/wasmcloud-platform \
--set "operator.enabled=false" \
--dependency-update
Wait for all components to install and wadm-nats
communications to establish:
kubectl rollout status deploy,sts -l app.kubernetes.io/name=nats
kubectl wait --for=condition=available --timeout=600s deploy -l app.kubernetes.io/name=wadm
Next install the wasmcloud-host
subchart:
helm upgrade --install \
wasmcloud-platform \
--values https://raw.githubusercontent.com/wasmCloud/wasmcloud/main/charts/wasmcloud-platform/values.yaml \
oci://ghcr.io/wasmcloud/charts/wasmcloud-platform \
--set "host.enabled=true" \
--dependency-update
If the deployment is successful, you should receive the note:
✨ Congratulations! Your wasmCloud platform has been deployed successfully.
- 🛀 To use the wash cli with your new wasmCloud platform, run:
kubectl port-forward service/nats 4222:4222 4223:4223
- 🗺️ To launch the wasmCloud dashboard on http://localhost:3030, in a different terminal window, run:
wash ui
If you follow the instructions to run the kubectl port-forward
, you can test the local wash
connection:
wash get inventory
This command should return the Kubernetes node and pod name for the wasmCloud host (your node and pod name will differ):
hostcore.os linux
hostcore.osfamily unix
kubernetes true
kubernetes_node_name minikube
kubernetes_pod_name wasmcloud-7cb4d4c7cb-jr
gd8
No components found
No providers found
From this point, you can deploy a wasmCloud application using the wash
toolchain. (Note that you cannot use kubectl to deploy a wasmCloud application manifest as you can when using the wasmCloud operator.)
wash app deploy https://raw.githubusercontent.com/wasmCloud/wasmcloud-operator/main/examples/quickstart/hello-world-application.yaml
If you run wash get inventory
again, you will see that the wasmCloud application is running on Kubernetes.
hostcore.arch aarch64
hostcore.os linux
hostcore.osfamily unix
kubernetes true
kubernetes_node_name minikube
kubernetes_pod_name wasmcloud-7cb4d4c7cb-jrgd8
Component ID Name Max count
hello_world-http_component http-hello-world 1
Provider ID Name
hello_world-httpserver http-server-provider
In order to uninstall the sample application, run wash app undeploy hello-world
.
You can find a complete list of configurable chart values in the wasmcloud-platform
chart documentation.