iSCSI Volume Claims
Persistent Volumes provide a means of connecting a service with storage. iSCSI allows a container to be scheduled anywhere, and to reconnect to storage.
| Local Disk | NFSv3 | iSCSI | |
|---|---|---|---|
| Low latency | yes | no | no |
| Authenticated | n/a | no | yes |
| Schedule on any Node | no | yes | yes |
| Concurrent access | yes | yes | no |
| Any Linux File System | yes | no | yes |
Target
Using ZFS, create a vdev for each target/lun
zfs create -o canmount=off zpool2/iscsi zfs create -V 100G -o volmode=dev zpool2/iscsi/t0-lun0 zfs create -V 100G -o volmode=dev zpool2/iscsi/t0-lun1
Following the FreeBSD Network Services guide
# /etc/ctl.conf auth-group ag0 { chap postgresql ************ } portal-group pg0 { discovery-auth-group no-authentication listen 192.168.0.9 } target iqn.2026-04.lan.fs1:target0 { auth-group ag0 portal-group pg0 lun 0 { path /dev/zvol/zpool2/iscsi/t0-lun0 blocksize 4096 size 100G } lun 1 { path /dev/zvol/zpool2/iscsi/t0-lun1 blocksize 4096 size 100G } }
Initiator
Kubernetes needs the initiator service running on each node:
dnf -qy install iscsi-initiator-utils systemctl enable --now iscsid
After this we can specify a persistant volume using iscsi
--- apiVersion: v1 kind: PersistentVolume metadata: name: iscsi0 spec: capacity: storage: 100Gi accessModes: - ReadWriteOnce iscsi: targetPortal: 192.168.0.9:3260 iqn: iqn.2026-04.lan.fs1:target0 lun: 0 fsType: ext4 readOnly: false chapAuthSession: true secretRef: name: postgresql-data storageClassName: fs-vdev
--- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pg2-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Gi storageClassName: fs-vdev
Authentication is provided using a specialized secret provider
--- apiVersion: v1 kind: Secret metadata: name: postgresql-data type: "kubernetes.io/iscsi-chap" stringData: node.session.auth.username: postgresql node.session.auth.password: ************
Testing
Initial connection test without authentication
t="iqn.2026-04.lan.fs1:target0" p="fs1.lan:3260" iscsiadm -m node --targetname $t --portal $p -o new # add connection iscsiadm -m node -L all # log in iscsiadm -m node # list iscsiadm -m node --targetname $t --portal $p -u # log out iscsiadm -m node --targetname $t --portal $p -o delete # remove connection