From 9273ba6c78de2a8ac10b3c21ba06c12598a16fbf Mon Sep 17 00:00:00 2001 From: Daniel Cosme Date: Fri, 1 May 2026 15:08:33 -0400 Subject: [PATCH] Add truenas-csi driver --- infrastructure/hydra/truenas-csi-driver.yaml | 463 +++++++++++++++++++ 1 file changed, 463 insertions(+) create mode 100644 infrastructure/hydra/truenas-csi-driver.yaml diff --git a/infrastructure/hydra/truenas-csi-driver.yaml b/infrastructure/hydra/truenas-csi-driver.yaml new file mode 100644 index 0000000..66b5a90 --- /dev/null +++ b/infrastructure/hydra/truenas-csi-driver.yaml @@ -0,0 +1,463 @@ +--- +# ClusterRole for CSI controller +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: truenas-csi-controller-role +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + +--- +# ClusterRoleBinding for CSI controller +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: truenas-csi-controller-binding +subjects: + - kind: ServiceAccount + name: truenas-csi-controller-sa + namespace: truenas-csi +roleRef: + kind: ClusterRole + name: truenas-csi-controller-role + apiGroup: rbac.authorization.k8s.io + +--- +# ClusterRole for CSI node +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: truenas-csi-node-role +rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch"] + +--- +# ClusterRoleBinding for CSI node +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: truenas-csi-node-binding +subjects: + - kind: ServiceAccount + name: truenas-csi-node-sa + namespace: truenas-csi +roleRef: + kind: ClusterRole + name: truenas-csi-node-role + apiGroup: rbac.authorization.k8s.io + +--- +# CSI Driver object +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: csi.truenas.io +spec: + attachRequired: true + podInfoOnMount: true + fsGroupPolicy: File + volumeLifecycleModes: + - Persistent + - Ephemeral +--- +# Controller Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: truenas-csi-controller + namespace: truenas-csi +spec: + replicas: 1 + selector: + matchLabels: + app: truenas-csi-controller + template: + metadata: + labels: + app: truenas-csi-controller + spec: + serviceAccountName: truenas-csi-controller-sa + containers: + # CSI Controller + - name: csi-controller + image: ghcr.io/truenas/truenas-csi:latest + imagePullPolicy: IfNotPresent + args: + - "--endpoint=$(CSI_ENDPOINT)" + - "--node-id=$(NODE_ID)" + - "--mode=controller" + - "--v=4" + env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: TRUENAS_URL + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: truenasURL + # API Key authentication + - name: TRUENAS_API_KEY + valueFrom: + secretKeyRef: + name: truenas-api-credentials + key: api-key + - name: TRUENAS_DEFAULT_POOL + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: defaultPool + - name: TRUENAS_NFS_SERVER + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: nfsServer + - name: TRUENAS_ISCSI_PORTAL + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: iscsiPortal + - name: TRUENAS_ISCSI_IQN_BASE + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: iscsiIQNBase + optional: true + - name: TRUENAS_INSECURE_SKIP_VERIFY + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: truenasInsecure + optional: true + - name: NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: socket-dir + mountPath: /csi + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: /healthz + port: 9808 + initialDelaySeconds: 10 + timeoutSeconds: 3 + periodSeconds: 10 + failureThreshold: 5 + + # CSI Provisioner + - name: csi-provisioner + image: registry.k8s.io/sig-storage/csi-provisioner:v6.1.1 + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--feature-gates=Topology=true" + - "--extra-create-metadata" + - "--leader-election=true" + - "--default-fstype=ext4" + - "--timeout=60s" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + + # CSI Attacher + - name: csi-attacher + image: registry.k8s.io/sig-storage/csi-attacher:v4.11.0 + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election=true" + - "--timeout=60s" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + + # CSI Snapshotter + - name: csi-snapshotter + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.5.0 + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election=true" + - "--timeout=60s" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + + # CSI Resizer + - name: csi-resizer + image: registry.k8s.io/sig-storage/csi-resizer:v2.1.0 + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--leader-election=true" + - "--timeout=60s" + env: + - name: ADDRESS + value: /csi/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /csi + + # Liveness Probe + - name: liveness-probe + image: registry.k8s.io/sig-storage/livenessprobe:v2.18.0 + args: + - "--csi-address=/csi/csi.sock" + - "--health-port=9808" + volumeMounts: + - name: socket-dir + mountPath: /csi + + volumes: + - name: socket-dir + emptyDir: {} + +--- +# Node DaemonSet +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: truenas-csi-node + namespace: truenas-csi +spec: + selector: + matchLabels: + app: truenas-csi-node + template: + metadata: + labels: + app: truenas-csi-node + spec: + serviceAccountName: truenas-csi-node-sa + hostNetwork: true + hostPID: true + hostIPC: true + priorityClassName: system-node-critical + tolerations: + - operator: Exists + containers: + # CSI Node Driver + - name: csi-node + image: ghcr.io/truenas/truenas-csi:latest + imagePullPolicy: IfNotPresent + lifecycle: + postStart: + exec: + command: + [ + "/bin/sh", + "-c", + "mkdir -p /run/lock/iscsi && mv /usr/sbin/iscsiadm /usr/sbin/iscsiadm.orig 2>/dev/null; printf '#!/bin/sh\\nnsenter --mount=/host/proc/1/ns/mnt -- /usr/sbin/iscsiadm \"$@\"\\n' > /usr/sbin/iscsiadm && chmod +x /usr/sbin/iscsiadm", + ] + securityContext: + privileged: true + args: + - "--endpoint=$(CSI_ENDPOINT)" + - "--node-id=$(NODE_ID)" + - "--mode=node" + - "--v=4" + env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: TRUENAS_URL + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: truenasURL + # API Key authentication + - name: TRUENAS_API_KEY + valueFrom: + secretKeyRef: + name: truenas-api-credentials + key: api-key + - name: TRUENAS_DEFAULT_POOL + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: defaultPool + - name: TRUENAS_NFS_SERVER + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: nfsServer + - name: TRUENAS_ISCSI_PORTAL + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: iscsiPortal + - name: TRUENAS_ISCSI_IQN_BASE + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: iscsiIQNBase + optional: true + - name: TRUENAS_INSECURE_SKIP_VERIFY + valueFrom: + configMapKeyRef: + name: truenas-csi-config + key: truenasInsecure + optional: true + - name: NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: kubelet-dir + mountPath: /var/lib/kubelet + mountPropagation: Bidirectional + - name: device-dir + mountPath: /dev + - name: iscsi-dir + mountPath: /etc/iscsi + mountPropagation: Bidirectional + - name: iscsi-lib + mountPath: /var/lib/iscsi + mountPropagation: Bidirectional + - name: host-root + mountPath: /host + mountPropagation: Bidirectional + resources: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "256Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: /healthz + port: 9808 + initialDelaySeconds: 10 + timeoutSeconds: 3 + periodSeconds: 10 + failureThreshold: 5 + + # Node Driver Registrar + - name: csi-node-driver-registrar + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.16.0 + args: + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + - "--v=5" + env: + - name: ADDRESS + value: /csi/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: /var/lib/kubelet/plugins/csi.truenas.io/csi.sock + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + + # Liveness Probe + - name: liveness-probe + image: registry.k8s.io/sig-storage/livenessprobe:v2.18.0 + args: + - "--csi-address=/csi/csi.sock" + - "--health-port=9808" + volumeMounts: + - name: plugin-dir + mountPath: /csi + + volumes: + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins/csi.truenas.io/ + type: DirectoryOrCreate + - name: kubelet-dir + hostPath: + path: /var/lib/kubelet + type: Directory + - name: device-dir + hostPath: + path: /dev + - name: iscsi-dir + hostPath: + path: /etc/iscsi + type: Directory + - name: iscsi-lib + hostPath: + path: /var/lib/iscsi + type: DirectoryOrCreate + - name: host-root + hostPath: + path: / + type: Directory