From 81a7702792eb4a92bb72a3d74fe16fa627b614f7 Mon Sep 17 00:00:00 2001 From: Chris Werner Rau Date: Fri, 23 Jan 2026 17:46:58 +0100 Subject: [PATCH] feat(cinder-csi-plugin): add splitMode This allows the user to deploy the controller-manager split between the management cluster and the workload cluster. --- charts/cinder-csi-plugin/Chart.yaml | 2 +- .../templates/cinder-csi-driver.yaml | 2 + .../controllerplugin-deployment.yaml | 61 +++++++++++++++++-- .../controllerplugin-podmonitor.yaml | 2 +- .../templates/controllerplugin-rbac.yaml | 29 ++++++++- .../templates/custom_storageclass.yaml | 2 +- .../templates/nodeplugin-daemonset.yaml | 13 +++- .../templates/nodeplugin-rbac.yaml | 2 + .../templates/storageclass.yaml | 2 +- charts/cinder-csi-plugin/values.yaml | 25 +++++++- 10 files changed, 124 insertions(+), 16 deletions(-) diff --git a/charts/cinder-csi-plugin/Chart.yaml b/charts/cinder-csi-plugin/Chart.yaml index 9b68d63cdd..f104c5d029 100644 --- a/charts/cinder-csi-plugin/Chart.yaml +++ b/charts/cinder-csi-plugin/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v1 appVersion: v1.34.1 description: Cinder CSI Chart for OpenStack name: openstack-cinder-csi -version: 2.34.3 +version: 2.35.0 home: https://github.com/kubernetes/cloud-provider-openstack icon: https://github.com/kubernetes/kubernetes/blob/master/logo/logo.png maintainers: diff --git a/charts/cinder-csi-plugin/templates/cinder-csi-driver.yaml b/charts/cinder-csi-plugin/templates/cinder-csi-driver.yaml index 5b681e4c4d..52af1ad5b8 100644 --- a/charts/cinder-csi-plugin/templates/cinder-csi-driver.yaml +++ b/charts/cinder-csi-plugin/templates/cinder-csi-driver.yaml @@ -1,3 +1,4 @@ +{{- if or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "workload") }} apiVersion: storage.k8s.io/v1 kind: CSIDriver metadata: @@ -8,3 +9,4 @@ spec: volumeLifecycleModes: - Persistent - Ephemeral +{{- end }} diff --git a/charts/cinder-csi-plugin/templates/controllerplugin-deployment.yaml b/charts/cinder-csi-plugin/templates/controllerplugin-deployment.yaml index e04cd87432..db4e06a4be 100644 --- a/charts/cinder-csi-plugin/templates/controllerplugin-deployment.yaml +++ b/charts/cinder-csi-plugin/templates/controllerplugin-deployment.yaml @@ -1,3 +1,4 @@ +{{- if or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "management") }} kind: Deployment apiVersion: apps/v1 metadata: @@ -10,7 +11,7 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - replicas: {{ .Values.csi.plugin.controllerPlugin.replicas }} + replicas: {{ and .Values.splitMode.enabled (eq .Values.splitMode.type "management") | ternary .Values.splitMode.replicas .Values.csi.plugin.controllerPlugin.replicas }} strategy: type: {{ .Values.csi.plugin.controllerPlugin.strategy.type }} {{- if eq .Values.csi.plugin.controllerPlugin.strategy.type "RollingUpdate" }} @@ -28,7 +29,11 @@ spec: annotations: {{- include "cinder-csi.controllerplugin.podAnnotations" . | nindent 8 }} spec: - serviceAccount: csi-cinder-controller-sa + {{- if .Values.splitMode.enabled }} + automountServiceAccountToken: false + {{- else }} + serviceAccountName: csi-cinder-controller-sa + {{- end }} securityContext: {{- toYaml .Values.csi.plugin.controllerPlugin.podSecurityContext | nindent 8 }} containers: @@ -43,6 +48,9 @@ spec: - "--timeout={{ .Values.timeout }}" - "--leader-election=true" - "--default-fstype=ext4" + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - "--kubeconfig=/etc/kubernetes/kubeconfig" + {{- end }} {{- if .Values.csi.attacher.extraArgs }} {{- with .Values.csi.attacher.extraArgs }} {{- tpl . $ | trim | nindent 12 }} @@ -57,6 +65,11 @@ spec: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + {{- end }} resources: {{ toYaml .Values.csi.attacher.resources | nindent 12 }} - name: csi-provisioner securityContext: @@ -71,6 +84,9 @@ spec: - "--default-fstype=ext4" - "--feature-gates=Topology={{ .Values.csi.provisioner.topology }}" - "--extra-create-metadata" + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - "--kubeconfig=/etc/kubernetes/kubeconfig" + {{- end }} {{- if .Values.csi.provisioner.extraArgs }} {{- with .Values.csi.provisioner.extraArgs }} {{- tpl . $ | trim | nindent 12 }} @@ -85,6 +101,11 @@ spec: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + {{- end }} resources: {{ toYaml .Values.csi.provisioner.resources | nindent 12 }} - name: csi-snapshotter securityContext: @@ -96,6 +117,9 @@ spec: - "--csi-address=$(ADDRESS)" - "--timeout={{ .Values.timeout }}" - "--leader-election=true" + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - "--kubeconfig=/etc/kubernetes/kubeconfig" + {{- end }} {{- if .Values.csi.snapshotter.extraArgs }} {{- with .Values.csi.snapshotter.extraArgs }} {{- tpl . $ | trim | nindent 12 }} @@ -110,6 +134,11 @@ spec: volumeMounts: - mountPath: /var/lib/csi/sockets/pluginproxy/ name: socket-dir + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + {{- end }} resources: {{ toYaml .Values.csi.snapshotter.resources | nindent 12 }} - name: csi-resizer securityContext: @@ -122,6 +151,9 @@ spec: - "--timeout={{ .Values.timeout }}" - "--handle-volume-inuse-error=false" - "--leader-election=true" + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - "--kubeconfig=/etc/kubernetes/kubeconfig" + {{- end }} {{- if .Values.csi.resizer.extraArgs }} {{- with .Values.csi.resizer.extraArgs }} {{- tpl . $ | trim | nindent 12 }} @@ -136,6 +168,11 @@ spec: volumeMounts: - name: socket-dir mountPath: /var/lib/csi/sockets/pluginproxy/ + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - name: kubeconfig + mountPath: /etc/kubernetes + readOnly: true + {{- end }} resources: {{ toYaml .Values.csi.resizer.resources | nindent 12 }} - name: liveness-probe securityContext: @@ -219,7 +256,12 @@ spec: volumeMounts: - name: socket-dir mountPath: /csi - {{- with .Values.csi.plugin.volumeMounts }} + {{- if .Values.secret.enabled }} + - name: cloud-config + mountPath: {{ .Values.secret.path }} + readOnly: true + {{- end }} + {{- with .Values.splitMode.enabled | ternary .Values.splitMode.volumeMounts .Values.csi.plugin.volumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} resources: {{ toYaml .Values.csi.plugin.resources | nindent 12 }} @@ -235,11 +277,19 @@ spec: hostPath: path: /etc/config {{- end }} - {{- with .Values.csi.plugin.volumes }} + {{- with .Values.splitMode.enabled | ternary .Values.splitMode.volumes .Values.csi.plugin.volumes }} {{- toYaml . | nindent 8 }} {{- end }} + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "management") }} + - name: kubeconfig + secret: + secretName: {{ .Values.splitMode.kubeconfig.secretName }} + items: + - key: {{ .Values.splitMode.kubeconfig.secretKey }} + path: kubeconfig + {{- end }} affinity: {{ toYaml .Values.csi.plugin.controllerPlugin.affinity | nindent 8 }} - nodeSelector: {{ toYaml .Values.csi.plugin.controllerPlugin.nodeSelector | nindent 8 }} + nodeSelector: {{ toYaml (and .Values.splitMode.enabled (eq .Values.splitMode.type "management") | ternary .Values.splitMode.nodeSelector .Values.csi.plugin.controllerPlugin.nodeSelector) | nindent 8 }} tolerations: {{ toYaml .Values.csi.plugin.controllerPlugin.tolerations | nindent 8 }} {{- with .Values.csi.plugin.controllerPlugin.hostAliases }} hostAliases: @@ -252,3 +302,4 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} +{{- end }} diff --git a/charts/cinder-csi-plugin/templates/controllerplugin-podmonitor.yaml b/charts/cinder-csi-plugin/templates/controllerplugin-podmonitor.yaml index 2dd8ee6e4a..7ea8697565 100644 --- a/charts/cinder-csi-plugin/templates/controllerplugin-podmonitor.yaml +++ b/charts/cinder-csi-plugin/templates/controllerplugin-podmonitor.yaml @@ -1,4 +1,4 @@ -{{- if .Values.csi.plugin.podMonitor.enabled }} +{{- if and (or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "management")) .Values.csi.plugin.podMonitor.enabled }} apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: diff --git a/charts/cinder-csi-plugin/templates/controllerplugin-rbac.yaml b/charts/cinder-csi-plugin/templates/controllerplugin-rbac.yaml index 3d3c242249..8175839e9e 100644 --- a/charts/cinder-csi-plugin/templates/controllerplugin-rbac.yaml +++ b/charts/cinder-csi-plugin/templates/controllerplugin-rbac.yaml @@ -1,12 +1,15 @@ +{{- if or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "workload") }} # This YAML file contains RBAC API objects, # which are necessary to run csi controller plugin +{{- if not .Values.splitMode.enabled }} apiVersion: v1 kind: ServiceAccount metadata: name: csi-cinder-controller-sa namespace: {{ .Release.Namespace }} --- +{{- end }} kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: @@ -33,9 +36,15 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: csi-attacher-binding subjects: + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "workload") }} + - kind: User + name: {{ .Values.splitMode.subject.name }} + apiGroup: rbac.authorization.k8s.io + {{- else }} - kind: ServiceAccount name: csi-cinder-controller-sa namespace: {{ .Release.Namespace }} + {{- end }} roleRef: kind: ClusterRole name: csi-attacher-role @@ -80,9 +89,15 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: csi-provisioner-binding subjects: + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "workload") }} + - kind: User + name: {{ .Values.splitMode.subject.name }} + apiGroup: rbac.authorization.k8s.io + {{- else }} - kind: ServiceAccount name: csi-cinder-controller-sa namespace: {{ .Release.Namespace }} + {{- end }} roleRef: kind: ClusterRole name: csi-provisioner-role @@ -118,9 +133,15 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: csi-snapshotter-binding subjects: + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "workload") }} + - kind: User + name: {{ .Values.splitMode.subject.name }} + apiGroup: rbac.authorization.k8s.io + {{- else }} - kind: ServiceAccount name: csi-cinder-controller-sa namespace: {{ .Release.Namespace }} + {{- end }} roleRef: kind: ClusterRole name: csi-snapshotter-role @@ -158,11 +179,17 @@ apiVersion: rbac.authorization.k8s.io/v1 metadata: name: csi-resizer-binding subjects: + {{- if and .Values.splitMode.enabled (eq .Values.splitMode.type "workload") }} + - kind: User + name: {{ .Values.splitMode.subject.name }} + apiGroup: rbac.authorization.k8s.io + {{- else }} - kind: ServiceAccount name: csi-cinder-controller-sa namespace: {{ .Release.Namespace }} + {{- end }} roleRef: kind: ClusterRole name: csi-resizer-role apiGroup: rbac.authorization.k8s.io ---- +{{- end }} diff --git a/charts/cinder-csi-plugin/templates/custom_storageclass.yaml b/charts/cinder-csi-plugin/templates/custom_storageclass.yaml index 267c731a27..12484d762c 100644 --- a/charts/cinder-csi-plugin/templates/custom_storageclass.yaml +++ b/charts/cinder-csi-plugin/templates/custom_storageclass.yaml @@ -1,3 +1,3 @@ -{{- if .Values.storageClass.custom -}} +{{- if and .Values.storageClass.custom (or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "workload")) -}} {{ .Values.storageClass.custom }} {{- end }} diff --git a/charts/cinder-csi-plugin/templates/nodeplugin-daemonset.yaml b/charts/cinder-csi-plugin/templates/nodeplugin-daemonset.yaml index a03e0b9979..15eeadb772 100644 --- a/charts/cinder-csi-plugin/templates/nodeplugin-daemonset.yaml +++ b/charts/cinder-csi-plugin/templates/nodeplugin-daemonset.yaml @@ -1,3 +1,4 @@ +{{- if or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "workload") }} kind: DaemonSet apiVersion: apps/v1 metadata: @@ -20,7 +21,7 @@ spec: annotations: {{- include "cinder-csi.nodeplugin.podAnnotations" . | nindent 8 }} spec: - serviceAccount: csi-cinder-node-sa + serviceAccountName: csi-cinder-node-sa hostNetwork: true dnsPolicy: {{ .Values.csi.plugin.nodePlugin.dnsPolicy }} securityContext: @@ -133,7 +134,12 @@ spec: - name: pods-probe-dir mountPath: /dev mountPropagation: "HostToContainer" - {{- with .Values.csi.plugin.volumeMounts }} + {{- if .Values.secret.enabled }} + - name: cloud-config + mountPath: {{ .Values.secret.path }} + readOnly: true + {{- end }} + {{- with .Values.splitMode.enabled | ternary .Values.splitMode.volumeMounts .Values.csi.plugin.volumeMounts }} {{- toYaml . | nindent 12 }} {{- end }} resources: {{ toYaml .Values.csi.plugin.resources | nindent 12 }} @@ -167,7 +173,7 @@ spec: hostPath: path: /etc/config {{- end }} - {{- with .Values.csi.plugin.volumes }} + {{- with .Values.splitMode.enabled | ternary .Values.splitMode.volumes .Values.csi.plugin.volumes }} {{- toYaml . | nindent 8 }} {{- end }} affinity: {{ toYaml .Values.csi.plugin.nodePlugin.affinity | nindent 8 }} @@ -184,3 +190,4 @@ spec: imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} +{{- end }} diff --git a/charts/cinder-csi-plugin/templates/nodeplugin-rbac.yaml b/charts/cinder-csi-plugin/templates/nodeplugin-rbac.yaml index 894a8df219..0028c1c44f 100644 --- a/charts/cinder-csi-plugin/templates/nodeplugin-rbac.yaml +++ b/charts/cinder-csi-plugin/templates/nodeplugin-rbac.yaml @@ -1,3 +1,4 @@ +{{- if or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "workload") }} apiVersion: v1 kind: ServiceAccount metadata: @@ -26,3 +27,4 @@ roleRef: kind: ClusterRole name: csi-nodeplugin-role apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/cinder-csi-plugin/templates/storageclass.yaml b/charts/cinder-csi-plugin/templates/storageclass.yaml index 704c30038b..47e19335ad 100644 --- a/charts/cinder-csi-plugin/templates/storageclass.yaml +++ b/charts/cinder-csi-plugin/templates/storageclass.yaml @@ -1,4 +1,4 @@ -{{- if .Values.storageClass.enabled }} +{{- if and .Values.storageClass.enabled (or (not .Values.splitMode.enabled) (eq .Values.splitMode.type "workload")) }} apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: diff --git a/charts/cinder-csi-plugin/values.yaml b/charts/cinder-csi-plugin/values.yaml index 4f94643e81..c613a3a282 100644 --- a/charts/cinder-csi-plugin/values.yaml +++ b/charts/cinder-csi-plugin/values.yaml @@ -85,9 +85,6 @@ csi: - name: cacert mountPath: /etc/cacert readOnly: true - - name: cloud-config - mountPath: /etc/config - readOnly: true nodePlugin: dnsPolicy: ClusterFirstWithHostNet # Optional additional annotations to add to the nodePlugin Pods. @@ -180,6 +177,7 @@ secret: hostMount: true create: false filename: cloud.conf + path: /etc/config # name: cinder-csi-cloud-config # data: # cloud.conf: |- @@ -233,3 +231,24 @@ imagePullSecrets: [] # add annotations to all pods, deployment, daemonset and podmonitor commonAnnotations: {} + +# External mode for split-cluster deployments (e.g., Cluster API) +# When disabled, deploys both controller and node plugin with standard RBAC +splitMode: + enabled: false + # type: "management" - Deploy controller with external kubeconfig (management cluster) + # type: "workload" - Deploy node plugin with RBAC for external controller (workload cluster) + type: "" + # Management cluster settings (type: management) + kubeconfig: + secretName: "" + secretKey: value + replicas: 1 + nodeSelector: {} + # Workload cluster settings (type: workload) + # The User subject name for controller RBAC (identity of external controller) + subject: + name: cinder-csi-controller + # Volumes and volumeMounts for splitMode (overrides csi.plugin.volumes/volumeMounts) + volumes: [] + volumeMounts: []