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 operators wishing to deploy wasmCloud with Kubernetes, including details on prerequisites such as NATS and how to deploy the operator.

kubectl support

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

  1. Deployment of wasmCloud Hosts onto a Kubernetes cluster via Custom Resource Definition (WasmCloudHostConfig)
  2. Interoperability with the wasmCloud Application Deployment Manager (wadm) for deploying wasmcloud applications defined in the OAM spec format.
  3. 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:

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.

Testing

Make sure you have a Kubernetes cluster running locally. Some good options include minikube, kind, k3s, or k0s.

Deploy NATS

Add the NATS Helm repo:

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

shell
helm upgrade --install -f https://raw.githubusercontent.com/wasmCloud/wasmcloud-operator/main/examples/quickstart/nats-values.yaml nats nats/nats

Validate the installation with:

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

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

shell
kubectl rollout status deploy -l app.kubernetes.io/instance=wadm

Deploy the operator

To deploy the operator:

shell
kubectl apply -k https://github.com/wasmCloud/wasmcloud-operator/deploy/base

Validate the installation with:

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

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

Check wasmCloud host status:

shell
kubectl describe wasmcloudhostconfig wasmcloud-host

You can also check logs for a given host with:

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

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

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

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

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.

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

Now you can connect to wasmCloud on Kubernetes with your local wash toolchain:

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

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