Skip to main content
User Volumes allow to treat available disk space as a pool of allocatable resource, which can be dynamically allocated to different applications. The user volumes are supposed to be used mostly for hostPath mounts in Kubernetes, but they can be used for other purposes as well. When a user volume configuration is applied, Talos Linux will either locate an existing volume or provision a new one. The volume will be created on the disk which satisfies the diskSelector expression and has enough free space to satisfy the minSize requirement. The user volume is identified by a unique name, which is used both as a mount location and as a label for the volume. The volume name must be unique across all user volumes, and it should be between 1 and 34 characters long, and can only contain ASCII letters, digits, and - (dash) characters. The volume label is derived from the volume name as u-<volume-name>, and it is used to identify the volume on the disk after initial provisioning. The volume mount location is /var/mnt/<volume-name>, and it gets automatically propagated into the kubelet container to provide additional features like subPath mounts. Disk encryption can be optionally enabled for user volumes.

Create user volumes

To create a user volume, append the following document to the machine configuration:
# user-volume.patch.yaml
apiVersion: v1alpha1
kind: UserVolumeConfig
name: local-volume
provisioning:
  diskSelector:
    match: disk.transport == 'nvme'
  minSize: 100GB
  maxSize: 200GB
For example, this machine configuration patch can be applied using the following command:
talosctl --nodes <NODE> patch mc --patch @user-volume.patch.yaml
In this example, a user volume named local-volume is created on the first NVMe disk which has 100GB of disk space available, and it will be created as maximum of 200GB if that space is available. The status of the volume can be checked using the following command:
$ talosctl get volumestatus u-local-volume # note u- prefix
NAMESPACE   TYPE           ID            VERSION   TYPE        PHASE   LOCATION         SIZE
runtime     VolumeStatus   u-local-volume   2         partition   ready   /dev/nvme0n1p2   200 GB
If the volume fails to be provisioned, use the -o yaml flag to get additional details. The volume is immediately mounted to /var/mnt/local-volume:
$ talosctl get mountstatus
NAMESPACE   TYPE          ID           VERSION   SOURCE           TARGET               FILESYSTEM   VOLUME
runtime     MountStatus   u-local-volume  2         /dev/nvme0n1p2   /var/mnt/local-volume   xfs          u-local-volume
It can be used in a Kubernetes pod as a hostPath mount:
kind: Pod
spec:
  containers:
    - name: ceph
      volumeMounts:
        - mountPath: /var/lib/ceph
          name: local-volume
  volumes:
    - name: local-volume
      hostPath:
        path: /var/mnt/local-volume
Please note, the path inside the container can be different from the path on the host.

Remove user volumes

Before removing a user volume, ensure that it is not mounted in any Kubernetes pod. In order to remove a user volume, first remove the configuration document from the machine configuration. The VolumeStatus and MountStatus resources will be removed automatically by Talos Linux.
Note: The actual disk data hasn’t been removed yet, so you can re-apply the user volume configuration back and it will be re-provisioned on the same disk.
To wipe the disk data, and make it allocatable again, use the following command:
talosctl wipe disk nvme0n1p2 --drop-partition
The nvme0n1p2 is the partition name, and it can be obtained from the VolumeStatus resource before the user volume is removed, or from the DiscoveredVolume resource any time later.
Note: If the wipe disk command fails with blockdevice is in use by volume, it means the user volume has not been removed from the machine configuration.

Types of user volumes

UserVolumeConfig includes an optional volumeType field that controls how a user volume is created and managed. If omitted, the system defaults to partition. Types disk and directory are advanced options with specific use cases. If unsure, use the default partition type.

volumeType: partition (default)

A standard volume backed by a dedicated partition on the underlying storage device. If you are unsure which type to choose, this is the recommended option.

volumeType: disk

It is primarily intended for scenarios where you want to dedicate a whole disk to a single workload without partitioning - for example, when provisioning on top of LVM logical volumes or other block devices that do not support partitioning. When set to disk, the volume is provisioned from an entire block device rather than a partition. If you want to consume the entire disk with partitioning support, use a partition user volume instead and set grow: true without specifying maxSize. When using volumeType: disk, the disk itself is not labeled or partitioned. The disk selector must uniquely and stably identify the device (for example via WWN, serial, or persistent path). If the selector is ambiguous, a different device may be selected after a reboot. Restrictions for disk volumes:
  • The provisioning block must not define size-related settings (minSize, maxSize, or grow). A full device implies a fixed size.

volumeType: directory

This type is useful for lightweight storage needs where full partitioning is unnecessary or impractical, and all that is required is a simple directory on the EPHEMERAL volume. When set to directory, the system bypasses provisioning and filesystem creation. Instead, it creates a host directory at:
/var/mnt/<metadata.name>
Characteristics and limitations of directory volumes:
  • No provisioning, filesystem operations, or encryption are performed.
  • The volume is simply a directory on the EPHEMERAL volume.
  • This type provides minimal overhead but does not deliver filesystem-level isolation.
  • Storage capacity is limited by the host’s EPHEMERAL partition.
  • Not suitable for workloads that require predictable or enforceable storage quotas.