Skip to main content
Version: v2

Filesystems and Volumes for Wasm Workloads

Overview​

For workloads that utilize external filesystem resources via wasi:filesystem preopens, you can mount data from a Kubernetes Volume.

  • Preopens provide secure access to filesystem resources by mounting them within a component before instantiation.
  • Kubernetes Volumes enable containers to access filesystem data.

In a wasmCloud deployment, filesystem data is made available to the containerized wasmCloud host, which may in turn pass data to a component.

In this section of the Operator Manual, you'll learn how to:

  • Deploy volumes that provide filesystem resources to the wasmCloud host
  • Create a WorkloadDeployment manifest for a component that preopens filesystem resources

The host must allow the path first​

Since 2.11.0 a hostPath volume is permitted only when its canonical path lies within a directory the host allows, listed in runtime.hostGroups[].hostPaths.allowed (host flag --allowed-host-path, WASH_ALLOWED_HOST_PATHS):

yaml
runtime:
  hostGroups:
    - name: default
      hostPaths:
        allowed:
          - /var/data

With no directories listed, no hostPath volume is permitted, so this grant is fail-closed like the egress allowlists. A workload whose volume falls outside every allowed directory is refused rather than silently given nothing. Canonical paths are what get judged, so .. segments and symlinks cannot reach outside an allowed directory.

Some paths stay refused even inside an allowed directory: the host reserves the credential and CA files its own flags name, its OCI cache, its config files, its configs:/secrets: catalog sources, and component-plugin Wasm files, and it refuses kernel filesystems (/proc, /sys, /dev) and the scratch root. --reserved-host-path adds more.

Ephemeral volumes (ephemeral: {}) need no grant. They live under the scratch root, runtime.hostGroups[].scratchRoot (--scratch-root, WASH_SCRATCH_ROOT), which defaults to wasmcloud-scratch in the system temp directory. A workload's scratch is removed when it stops, and a starting host clears what dead hosts left behind.

wash dev configures both for you

A dev session derives its allowed paths from the volumes the project declares and moves its scratch root under the wash cache directory, so the dev loop does not need either setting and a session mounting /tmp is not refused. The grant is a Kubernetes concern.

This is a host-wide guardrail, not a tenancy boundary: every workload on the host may mount any directory the host allows. See Workload Security for that distinction.

Deploying volumes with wasmCloud hosts​

When deploying components that require filesystem resources, you first need to create the volume and make the volume available to the wasmCloud host.

The sample host configuration excerpt below makes a volume called wasmcloud-data available to a host with the default label. (We use this hostgroup for simple local testing in our default operator deployment, but you could use any hostgroup.)

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    wasmcloud.com/hostgroup: default
    wasmcloud.com/name: hostgroup
  name: hostgroup-default
  namespace: default
spec:
  selector:
    matchLabels:
      wasmcloud.com/hostgroup: default
      wasmcloud.com/name: hostgroup
  template:
    metadata:
      labels:
        wasmcloud.com/hostgroup: default
        wasmcloud.com/name: hostgroup
    spec:
      volumes:
        - name: wasmcloud-data
          hostPath:
            path: "/var/data"
  • The name field assigns a unique name to the volume.
  • The hostPath.path field specifies the target path for the file or directory on the host machine.

Declarative alternative: runtime.hostGroups[].volumes​

Starting in 2.4.0, the runtime-operator Helm chart accepts pod-level volumes and host-container volumeMounts directly on each host group entry, so the volume survives a helm upgrade instead of being re-applied as a manual patch on the rendered Deployment:

yaml
runtime:
  hostGroups:
    - name: default
      replicas: 3
      volumes:
        - name: wasmcloud-data
          hostPath:
            path: /var/data
      volumeMounts:
        - name: wasmcloud-data
          mountPath: /var/data

The WorkloadDeployment half of the wiring is unchanged — components still reference the volume by name via spec.volumes + localResources.volumeMounts, as shown in the next section. See runtime.hostGroups[].volumes, volumeMounts, and ports for the full schema.

Deploying components with filesystem access​

To access filesystem resources via the preopens and the wasmCloud host, a component should import wasi:filesystem. You can use the Wasm Shell (wash) CLI to check your component's imports:

shell
wash inspect ./component.wasm 

Output should include:

wit
import wasi:filesystem/types@0.2.x;
import wasi:filesystem/preopens@0.2.x;

The sample WorkloadDeployment manifest below makes the wasmcloud-data volume available to the http-fs-hello component at the /assets path within the component.

yaml
apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: WorkloadDeployment
metadata:
  name: http-fs-hello
spec:
  replicas: 1
  template:
    spec:
      hostSelector:
        hostgroup: default
      volumes:
        - name: wasmcloud-data
          hostPath:
            path: /var/data # should match path in host deployment
      components:
        - name: http-fs-hello
          image: ghcr.io/<namespace>/http-fs-hello:0.1.2
          localResources:
            volumeMounts:
              - name: wasmcloud-data
                mountPath: /assets # where data is mounted inside component
      hostInterfaces:
        - namespace: wasi
          package: http
          interfaces:
            - incoming-handler
          config:
            host: localhost
  • The workload must be assigned to a host with the named volume, and (since 2.11.0) the host must allow the hostPath directory as described above.
  • Resources defined under the localResources field are made available to the component.
  • The volumeMounts.name field specifies the volume to use.
  • The volumeMounts.mountPath field specifies the path where the data from the volume should be made available within the component.
  • It is not necessary to define wasi:filesystem under hostInterfaces.