Skip to main content
SeaweedFS is a simple, highly scalable distributed file system with an S3-compatible object store and a POSIX filer. Its CSI driver provisions persistent volumes for Kubernetes, including ReadWriteMany (RWX) volumes shared across pods. On Talos it is a lightweight alternative to a full Ceph/Rook cluster when you want cheap, reliable PVC storage without the operational overhead. This guide covers provisioning a dedicated disk for SeaweedFS, deploying the master, filer, and volume servers, installing the CSI driver, and verifying that volumes provision.

Prerequisites

Before you begin, ensure that you have the following:
  • talosctl configured and authenticated against your cluster
  • kubectl configured to access the same cluster
  • Helm 3 installed
  • At least one dedicated disk per storage node, separate from the system disk where Talos is installed

Step 1: Provision a dedicated disk with UserVolumeConfig

Talos Linux v1.10 introduced UserVolumeConfig, which replaces the deprecated machine.disks API. This resource automatically mounts selected disks under /var/mnt/<name>. In this guide, the volume is named seaweedfs which mounts at /var/mnt/seaweedfs. How you apply the UserVolumeConfig depends on how your cluster is managed. Choose the tab that matches your setup.

1.1: Inspect available disks

Inspect the disks available on each storage node so you know which disk to select and what its transport is.
Note the transport (for example nvme, sata, or virtio) and the identifier of the disk you want to dedicate to SeaweedFS. You will use these to write the selector in the next step.Confirm which disk is the system disk, so you select a different one:
The disk it reports (for example nvme0n1) is excluded by the !system_disk selector. Make sure the disk you intend to use for SeaweedFS is a different disk with READ ONLY set to false.

1.2: Create the UserVolumeConfig

Create a UserVolumeConfig document that tells Talos which disk to provision. Talos mounts the volume at /var/mnt/seaweedfs.Two things to get right:
  • A size constraint is required. Set minSize (and optionally maxSize), or Talos rejects the config with min size or max size is required. The example below claims at least 10GiB and grows to fill the disk.
  • Match a disk that actually exists on your node. The diskSelector.match field is a Common Expression Language (CEL) expression. The example matches any non-system disk; narrow it using the transport and fields you saw in Step 1.1.
To target a specific disk, narrow the selector using the fields from talosctl get disks — for example disk.transport == 'nvme' && !system_disk, disk.size > 50u * GiB, or the most stable option, matching a stable device path such as '/dev/disk/by-id/...' in disk.symlinks. Do not assume a transport such as nvme; use whatever Step 1.1 reported for your hardware. For more information, refer to the Disk Management documentation.

1.3: Apply the UserVolumeConfig to storage nodes

Define the IP addresses of the worker nodes that will provide storage to SeaweedFS, one entry per node:
Then apply the patch to each node:

1.4: Reboot the nodes

Reboot each worker node to apply the configuration changes:
After the nodes come back up, confirm the volume reached the ready phase. Talos prefixes user-volume IDs with u-, so the volume is u-seaweedfs:
The volume should report PHASE ready, mounted at /var/mnt/seaweedfs.

Step 2: Enable privileged pod security

The SeaweedFS containers use hostPath volumes and do not run as non-root, which the default Talos Pod Security Admission Policies block. Create the seaweedfs namespace and label it to allow privileged workloads:

Step 3: Install SeaweedFS with Helm

Add the SeaweedFS Helm repository:
SeaweedFS deploys three components — a master, a filer, and a volume server — and each one writes to its own hostPath. By default the chart points these at /ssd and /storage, which are not writable on Talos: the Talos root filesystem is read-only, and only paths under /var can be written. Installing the chart unmodified fails with mkdir /ssd: read-only file system. Create a values file that redirects every hostPath — for the master, filer, and volume server, including their log volumes — to the /var/mnt/seaweedfs mount provisioned in Step 1:
Install SeaweedFS with the values file:
This configures all three SeaweedFS components to store their data and logs under /var/mnt/seaweedfs, which matches the disk path created in Step 1. Wait for the core components to become ready, then confirm the pods are Running:

Step 4: Install the SeaweedFS CSI driver

The CSI driver provisions PersistentVolumes backed by the SeaweedFS filer. It ships from its own Helm repository, separate from the main SeaweedFS chart, so add that repository first:
Install the driver, pointing it at the filer service created in Step 3:
The seaweedfsFiler value is the address of the filer’s HTTP service, in the form <service>.<namespace>:8888 (port 8888 is the filer’s HTTP port). Adjust the service name and namespace if you changed the release name or namespace in Step 3.
Wait for the driver’s node daemonset to roll out, then confirm all pods in the namespace are Running:
Alongside the master, filer, and volume pods, you should see seaweedfs-csi-driver-node-* and seaweedfs-csi-driver-controller-*. Confirm the StorageClass was created:
You should see seaweedfs-storage, provisioned by seaweedfs-csi-driver.
The SeaweedFS CSI driver supports both ReadWriteOnce (RWO) and ReadWriteMany (RWX) access modes, which makes it a good fit for workloads that need shared volumes across pods.

Step 5: Create a test persistent volume

Create a test PersistentVolumeClaim. Set storageClassName to the SeaweedFS StorageClass name reported in Step 4.
Check its status:
The PVC should reach the Bound state within a few seconds, confirming that SeaweedFS can provision volumes. Once you have confirmed it works, remove the test claim: