Skip to main content
Version: 1.x

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:

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:

  1. Declarative wasmCloud management via Custom Resource Definitions (CRDs), with wasmCloud hosts managed by the WasmCloudHostConfig CRD, encoding best practices for deploying wasmCloud hosts
  2. 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
  3. 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.

Running Kubernetes locally

Some good options for local Kubernetes include minikube, kind, k3s, or k0s.

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.

shell
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:

shell
kubectl rollout status deploy,sts -l app.kubernetes.io/name=nats
shell
kubectl wait --for=condition=available --timeout=600s deploy -l app.kubernetes.io/name=wadm
shell
kubectl wait --for=condition=available --timeout=600s deploy -l app.kubernetes.io/name=wasmcloud-operator

Next create a wasmCloud host:

shell
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:

shell
 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:

shell
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:

yaml
...
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:

shell
kubectl apply -f https://raw.githubusercontent.com/wasmCloud/wasmcloud-operator/main/examples/quickstart/hello-world-application.yaml

Check the deployment status:

shell
kubectl get application
shell
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:

shell
kubectl get services
text
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:

shell
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:

shell
kubectl port-forward pods/$WASMCLOUD_HOST_POD 8080

curl the application:

shell
curl http://localhost:8080

You should get the response:

plaintext
Hello from Rust!

Debugging

You can use kubectl to get logs from the wasmCloud host running on your kind cluster:

shell
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 the hello-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.

shell
kubectl port-forward service/nats 4222:4222 4223:4223

Now you can use your local wash toolchain with your wasmCloud deployment:

shell
wash get inventory

The output should look like this:

plaintext
  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.

yaml
---
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:

shell
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:

shell
kubectl rollout status deploy,sts -l app.kubernetes.io/name=nats
shell
kubectl wait --for=condition=available --timeout=600s deploy -l app.kubernetes.io/name=wadm

Next install the wasmcloud-host subchart:

shell
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:

shell
 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:

shell
wash get inventory

This command should return the Kubernetes node and pod name for the wasmCloud host (your node and pod name will differ):

text
  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.)

shell
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.

text
  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.