diff --git a/cluster/synology-storageclass.yaml b/cluster/synology-storageclass.yaml new file mode 100644 index 0000000..b565740 --- /dev/null +++ b/cluster/synology-storageclass.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: synology-storageclass + finalizers: + - resources-finalizer.argocd.argoproj.io + annotations: + argocd.argoproj.io/sync-wave: "4" +spec: + destination: + name: in-cluster + namespace: synology-csi + project: default + source: + path: cluster/synology-storageclass + repoURL: https://github.com/rblundon/homelab.git + targetRevision: HEAD + syncPolicy: + automated: + prune: false + selfHeal: true + syncOptions: + - RespectIgnoreDifferences=true + - CreateNamespace=true + managedNamespaceMetadata: + labels: + argocd.argoproj.io/managed-by: openshift-gitops + ignoreDifferences: + - group: apps + kind: Deployment + jsonPointers: + - /spec/replicas \ No newline at end of file diff --git a/cluster/synology-storageclass/controller.yaml b/cluster/synology-storageclass/controller.yaml new file mode 100644 index 0000000..efc56be --- /dev/null +++ b/cluster/synology-storageclass/controller.yaml @@ -0,0 +1,170 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-controller-sa + namespace: synology-csi + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: synology-csi-controller-role +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["csi.storage.k8s.io"] + resources: ["csinodeinfos"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments", "volumeattachments/status"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: synology-csi-controller-role + namespace: synology-csi +subjects: + - kind: ServiceAccount + name: csi-controller-sa + namespace: synology-csi +roleRef: + kind: ClusterRole + name: synology-csi-controller-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: synology-csi-controller + namespace: synology-csi +spec: + serviceName: "synology-csi-controller" + replicas: 1 + selector: + matchLabels: + app: synology-csi-controller + template: + metadata: + labels: + app: synology-csi-controller + spec: + serviceAccountName: csi-controller-sa + hostNetwork: true + containers: + - name: csi-provisioner + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: registry.k8s.io/sig-storage/csi-provisioner:v3.0.0 + args: + - --timeout=60s + - --csi-address=$(ADDRESS) + - --v=5 + - --extra-create-metadata + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: Always + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-attacher + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: registry.k8s.io/sig-storage/csi-attacher:v3.3.0 + args: + - --v=5 + - --csi-address=$(ADDRESS) + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: Always + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-resizer + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: registry.k8s.io/sig-storage/csi-resizer:v1.3.0 + args: + - --v=5 + - --csi-address=$(ADDRESS) + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: Always + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-plugin + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: synology/synology-csi:v1.2.0 #v1.1.3 + args: + - --nodeid=NotUsed + - --endpoint=$(CSI_ENDPOINT) + - --client-info + - /etc/synology/client-info.yml + - --log-level=info + env: + - name: CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: IfNotPresent + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: client-info + mountPath: /etc/synology + readOnly: true + volumes: + - name: socket-dir + emptyDir: {} + - name: client-info + secret: + secretName: client-info-secret diff --git a/cluster/synology-storageclass/csi-driver.yaml b/cluster/synology-storageclass/csi-driver.yaml new file mode 100644 index 0000000..ac8f464 --- /dev/null +++ b/cluster/synology-storageclass/csi-driver.yaml @@ -0,0 +1,9 @@ +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: csi.san.synology.com +spec: + attachRequired: true # Indicates the driver requires an attach operation (TODO: ControllerPublishVolume should be implemented) + podInfoOnMount: true + volumeLifecycleModes: + - Persistent diff --git a/hub-cluster-bootstrap/enable-iscsi.yaml b/cluster/synology-storageclass/enable-iscsi.yaml similarity index 100% rename from hub-cluster-bootstrap/enable-iscsi.yaml rename to cluster/synology-storageclass/enable-iscsi.yaml diff --git a/cluster/synology-storageclass/kustomization.yaml b/cluster/synology-storageclass/kustomization.yaml new file mode 100644 index 0000000..381760e --- /dev/null +++ b/cluster/synology-storageclass/kustomization.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- namespace.yaml +- synology-secret-eso.yaml +- synology-csi-scc.yaml +- controller.yaml +- csi-driver.yaml +- node.yaml +- storage-class.yaml +- snapshotter.yaml +- volume-snapshot-class.yaml +- enable-iscsi.yaml \ No newline at end of file diff --git a/cluster/synology-storageclass/namespace.yaml b/cluster/synology-storageclass/namespace.yaml new file mode 100644 index 0000000..bcf8c6a --- /dev/null +++ b/cluster/synology-storageclass/namespace.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + labels: + kubernetes.io/metadata.name: synology-csi + name: synology-csi + argocd.argoproj.io/managed-by: openshift-gitops-operator + name: synology-csi +spec: + finalizers: + - kubernetes diff --git a/cluster/synology-storageclass/node.yaml b/cluster/synology-storageclass/node.yaml new file mode 100644 index 0000000..a35f729 --- /dev/null +++ b/cluster/synology-storageclass/node.yaml @@ -0,0 +1,140 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-node-sa + namespace: synology-csi + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: synology-csi-node-role +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "update"] + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: synology-csi-node-role + namespace: synology-csi +subjects: + - kind: ServiceAccount + name: csi-node-sa + namespace: synology-csi +roleRef: + kind: ClusterRole + name: synology-csi-node-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: synology-csi-node + namespace: synology-csi +spec: + selector: + matchLabels: + app: synology-csi-node + template: + metadata: + labels: + app: synology-csi-node + spec: + serviceAccount: csi-node-sa + hostNetwork: true + containers: + - name: csi-driver-registrar + securityContext: + privileged: true + imagePullPolicy: Always + image: registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.3.0 + args: + - --v=5 + - --csi-address=$(ADDRESS) # the csi socket path inside the pod + - --kubelet-registration-path=$(REGISTRATION_PATH) # the csi socket path on the host node + env: + - name: ADDRESS + value: /csi/csi.sock + - name: REGISTRATION_PATH + value: /var/lib/kubelet/plugins/csi.san.synology.com/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + - name: csi-plugin + securityContext: + privileged: true + imagePullPolicy: Always #IfNotPresent + image: synology/synology-csi:v1.2.0 #v1.1.3 + args: + - --nodeid=$(KUBE_NODE_NAME) + - --endpoint=$(CSI_ENDPOINT) + - --client-info + - /etc/synology/client-info.yml + - --log-level=info + env: + - name: CSI_ENDPOINT + value: unix://csi/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: kubelet-dir + mountPath: /var/lib/kubelet + mountPropagation: "Bidirectional" + - name: plugin-dir + mountPath: /csi + - name: client-info + mountPath: /etc/synology + readOnly: true + - name: host-root + mountPath: /host + - name: device-dir + mountPath: /dev + volumes: + - name: kubelet-dir + hostPath: + path: /var/lib/kubelet + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins/csi.san.synology.com/ + type: DirectoryOrCreate + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry + type: Directory + - name: client-info + secret: + secretName: client-info-secret + - name: host-root + hostPath: + path: / + type: Directory + - name: device-dir + hostPath: + path: /dev + type: Directory \ No newline at end of file diff --git a/cluster/synology-storageclass/snapshotter.yaml b/cluster/synology-storageclass/snapshotter.yaml new file mode 100644 index 0000000..25b62ad --- /dev/null +++ b/cluster/synology-storageclass/snapshotter.yaml @@ -0,0 +1,107 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: csi-snapshotter-sa + namespace: synology-csi + +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: synology-csi-snapshotter-role +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: synology-csi-snapshotter-role + namespace: synology-csi +subjects: + - kind: ServiceAccount + name: csi-snapshotter-sa + namespace: synology-csi +roleRef: + kind: ClusterRole + name: synology-csi-snapshotter-role + apiGroup: rbac.authorization.k8s.io + +--- +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: synology-csi-snapshotter + namespace: synology-csi +spec: + serviceName: "synology-csi-snapshotter" + replicas: 1 + selector: + matchLabels: + app: synology-csi-snapshotter + template: + metadata: + labels: + app: synology-csi-snapshotter + spec: + serviceAccountName: csi-snapshotter-sa + hostNetwork: true + containers: + - name: csi-snapshotter + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: registry.k8s.io/sig-storage/csi-snapshotter:v4.2.1 + args: + - --v=5 + - --csi-address=$(ADDRESS) + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: Always + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-plugin + securityContext: + privileged: true + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true + image: synology/synology-csi:v1.1.3 + args: + - --nodeid=NotUsed + - --endpoint=$(CSI_ENDPOINT) + - --client-info + - /etc/synology/client-info.yml + - --log-level=info + env: + - name: CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: IfNotPresent + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: client-info + mountPath: /etc/synology + readOnly: true + volumes: + - name: socket-dir + emptyDir: {} + - name: client-info + secret: + secretName: client-info-secret diff --git a/cluster/synology-storageclass/storage-class.yaml b/cluster/synology-storageclass/storage-class.yaml new file mode 100644 index 0000000..ee8612e --- /dev/null +++ b/cluster/synology-storageclass/storage-class.yaml @@ -0,0 +1,15 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: synology-iscsi-storage + annotations: + storageclass.kubernetes.io/is-default-class: "true" +provisioner: csi.san.synology.com +# if all params are empty, synology CSI will choose an available location to create volume +parameters: + dsm: '10.10.121.35' + protocol: 'iscsi' + location: '/volume1' + csi.storage.k8s.io/fstype: 'ext4' +reclaimPolicy: Delete #Retain +allowVolumeExpansion: true diff --git a/cluster/synology-storageclass/synology-csi-scc.yaml b/cluster/synology-storageclass/synology-csi-scc.yaml new file mode 100644 index 0000000..d0ea4aa --- /dev/null +++ b/cluster/synology-storageclass/synology-csi-scc.yaml @@ -0,0 +1,29 @@ +--- +kind: SecurityContextConstraints +apiVersion: security.openshift.io/v1 +metadata: + name: synology-csi-scc +allowHostDirVolumePlugin: true +allowHostNetwork: true +allowPrivilegedContainer: true +allowedCapabilities: +- 'SYS_ADMIN' +defaultAddCapabilities: [] +fsGroup: + type: RunAsAny +groups: [] +priority: +readOnlyRootFilesystem: false +requiredDropCapabilities: [] +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +supplementalGroups: + type: RunAsAny +users: +- system:serviceaccount:synology-csi:csi-controller-sa +- system:serviceaccount:synology-csi:csi-node-sa +- system:serviceaccount:synology-csi:csi-snapshotter-sa +volumes: +- '*' diff --git a/cluster/synology-storageclass/synology-secret-eso.yaml b/cluster/synology-storageclass/synology-secret-eso.yaml new file mode 100644 index 0000000..afabb08 --- /dev/null +++ b/cluster/synology-storageclass/synology-secret-eso.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: client-info-secret + namespace: synology-csi +spec: + secretStoreRef: + kind: ClusterSecretStore + name: doppler-cluster + refreshInterval: "1h" + data: + - secretKey: client-info.yml + remoteRef: + key: SYNOLOGY_CLIENT_INFO diff --git a/cluster/synology-storageclass/volume-snapshot-class.yaml b/cluster/synology-storageclass/volume-snapshot-class.yaml new file mode 100644 index 0000000..af18d68 --- /dev/null +++ b/cluster/synology-storageclass/volume-snapshot-class.yaml @@ -0,0 +1,11 @@ +apiVersion: snapshot.storage.k8s.io/v1 +kind: VolumeSnapshotClass +metadata: + name: synology-snapshotclass + annotations: + storageclass.kubernetes.io/is-default-class: "false" +driver: csi.san.synology.com +deletionPolicy: Delete +# parameters: +# description: 'Kubernetes CSI' # only for iscsi protocol +# is_locked: 'false'