Skip to content

Commit 4afdcc9

Browse files
authored
refactor!: Split into Deployment and DaemonSet (#645)
* refactor: Split into Deployment and DaemonSet The splits the deployment of the secret-operator as a whole into two parts: - The controller is deployed via a Deployment which ensures only a single instance of the secret-operator in controller mode is running in a Kubernetes cluster. This can potentially lead to perfomance issues and as such should be monitored going forward. - The CSI server is deployed via a DaemonSet (unchanged) as this server is needed on every node to provision requested secret volumes. This refactor is introduced in preparation for #634, in which only a single instance of the CRD conversion webhook must exist as otherwise TLS certificate verification will fail with multiple available certificates. * chore: Add changelog entry * chore: Update comment * refactor: Adjust values.yaml file to be closer to listener-operator * chore: Adjust changelog entry
1 parent 68247f4 commit 4afdcc9

File tree

7 files changed

+329
-166
lines changed

7 files changed

+329
-166
lines changed

CHANGELOG.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ All notable changes to this project will be documented in this file.
1515

1616
### Changed
1717

18+
- Split operator deployment into Deployment and DaemonSet ([#645]).
19+
- Introduce two different modes: `csi-server` and `controller`.
20+
- The CSI server is deployed via a DaemonSet to be available on every node.
21+
- The controller is deployed via a Deployment with a single replica.
1822
- Version CRD structs and enums as v1alpha1 ([#636]).
19-
- BREAKING: Rearrange values to be somewhat consistent with the listener-operator value changes ([#641]).
20-
- `image.repository` has been moved to `secretOperator.image.repository`.
21-
- `image.tag` has been moved to `secretOperator.image.tag`.
22-
- `image.pullPolicy` has been moved to `secretOperator.image.pullPolicy`.
23-
- `csiProvisioner` values have been moved to `externalProvisioner`.
24-
- `csiNodeDriverRegistrar` values have been moved to `nodeDriverRegistrar`.
25-
- `node.driver` values have been moved to `secretOperator`.
26-
- `securityContext` values have been moved to `secretOperator.securityContext`.
23+
- BREAKING: Rearrange values to be somewhat consistent with the listener-operator value changes ([#641], [#645]).
24+
- `csiProvisioner` values have been moved to `csiNodeDriver.externalProvisioner`.
25+
- `csiNodeDriverRegistrar` values have been moved to `csiNodeDriver.nodeDriverRegistrar`.
26+
- `node.driver.resources` values have been split into `controllerService.resources` and `csiNodeDriver.nodeService.resources`.
27+
- `securityContext` values have been split into `controllerService.securityContext` and `.csiNodeDriver.nodeService.securityContext`.
28+
- `podAnnotations`, `podSecurityContext`, `nodeSelector`, `tolerations`, and `affinity` have been split into `controllerService` and `csiNodeDriver`.
29+
- `kubeletDir` has been move to `csiNodeDriver.kubeletDir`.
2730
- Bump csi-node-driver-registrar to `v2.15.0` ([#642]).
2831
- Bump csi-provisioner to `v5.3.0` ([#643]).
2932

@@ -33,6 +36,7 @@ All notable changes to this project will be documented in this file.
3336
[#642]: https://github.com/stackabletech/secret-operator/pull/642
3437
[#643]: https://github.com/stackabletech/secret-operator/pull/643
3538
[#644]: https://github.com/stackabletech/secret-operator/pull/644
39+
[#645]: https://github.com/stackabletech/secret-operator/pull/645
3640

3741
## [25.7.0] - 2025-07-23
3842

Tiltfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ if os.path.exists('result'):
2626
# oci.stackable.tech/sandbox/opa-operator:7y19m3d8clwxlv34v5q2x4p7v536s00g instead of
2727
# oci.stackable.tech/sandbox/opa-operator:0.0.0-dev (which does not exist)
2828
k8s_kind('Deployment', image_json_path='{.spec.template.metadata.annotations.internal\\.stackable\\.tech/image}')
29+
k8s_kind('DaemonSet', image_json_path='{.spec.template.metadata.annotations.internal\\.stackable\\.tech/image}')
2930

3031
# Exclude stale CRDs from Helm chart, and apply the rest
3132
helm_crds, helm_non_crds = filter_yaml(
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
apiVersion: apps/v1
3+
kind: Deployment
4+
metadata:
5+
name: {{ include "operator.fullname" . }}
6+
labels:
7+
{{- include "operator.labels" . | nindent 4 }}
8+
spec:
9+
selector:
10+
matchLabels:
11+
{{- include "operator.selectorLabels" . | nindent 6 }}
12+
template:
13+
metadata:
14+
annotations:
15+
internal.stackable.tech/image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
16+
{{- with .Values.controllerService.podAnnotations }}
17+
{{- toYaml . | nindent 8 }}
18+
{{- end }}
19+
labels:
20+
{{- include "operator.selectorLabels" . | nindent 8 }}
21+
spec:
22+
{{- with .Values.image.pullSecrets }}
23+
imagePullSecrets:
24+
{{- toYaml . | nindent 8 }}
25+
{{- end }}
26+
# NOTE (@Techassi): Does it maybe make sense to have two different service accounts?
27+
serviceAccountName: {{ include "operator.fullname" . }}-serviceaccount
28+
securityContext:
29+
{{- toYaml .Values.controllerService.podSecurityContext | nindent 8 }}
30+
containers:
31+
- name: {{ include "operator.appname" . }}
32+
securityContext:
33+
{{- toYaml .Values.controllerService.securityContext | nindent 12 }}
34+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
35+
imagePullPolicy: {{ .Values.image.pullPolicy }}
36+
resources:
37+
{{ .Values.controllerService.resources | toYaml | nindent 12 }}
38+
# The arguments passed to the command being run in the container. The final command will
39+
# look like `secret-operator run controller [OPTIONS]`. The controller needs to only run
40+
# once in a Kubernetes cluster and as such is deployed as a Deployment with a single
41+
# replica.
42+
args:
43+
- run
44+
- controller
45+
env:
46+
# The following env vars are passed as clap (think CLI) arguments to the operator.
47+
# They are picked up by clap using the structs defied in the operator.
48+
# (which is turn pulls in https://github.com/stackabletech/operator-rs/blob/main/crates/stackable-operator/src/cli.rs)
49+
# You can read there about the expected values and purposes.
50+
51+
# Sometimes products need to know the operator image, e.g. the opa-bundle-builder OPA
52+
# sidecar uses the operator image.
53+
- name: OPERATOR_IMAGE
54+
# Tilt can use annotations as image paths, but not env variables
55+
valueFrom:
56+
fieldRef:
57+
fieldPath: metadata.annotations['internal.stackable.tech/image']
58+
59+
# Namespace the operator Pod is running in, e.g. used to construct the conversion
60+
# webhook endpoint.
61+
- name: OPERATOR_NAMESPACE
62+
valueFrom:
63+
fieldRef:
64+
fieldPath: metadata.namespace
65+
66+
# The name of the Kubernetes Service that point to the operator Pod, e.g. used to
67+
# construct the conversion webhook endpoint.
68+
- name: OPERATOR_SERVICE_NAME
69+
value: {{ include "operator.fullname" . }}
70+
71+
# Operators need to know the node name they are running on, to e.g. discover the
72+
# Kubernetes domain name from the kubelet API.
73+
- name: KUBERNETES_NODE_NAME
74+
valueFrom:
75+
fieldRef:
76+
fieldPath: spec.nodeName
77+
78+
{{- if .Values.kubernetesClusterDomain }}
79+
- name: KUBERNETES_CLUSTER_DOMAIN
80+
value: {{ .Values.kubernetesClusterDomain | quote }}
81+
{{- end }}
82+
{{- include "telemetry.envVars" . | nindent 12 }}
83+
{{- with .Values.controllerService.nodeSelector }}
84+
nodeSelector:
85+
{{- toYaml . | nindent 8 }}
86+
{{- end }}
87+
{{- with .Values.controllerService.affinity }}
88+
affinity:
89+
{{- toYaml . | nindent 8 }}
90+
{{- end }}
91+
{{- with .Values.controllerService.tolerations }}
92+
tolerations:
93+
{{- toYaml . | nindent 8 }}
94+
{{- end }}
95+
{{- with .Values.controllerService.priorityClassName }}
96+
priorityClassName: {{ . }}
97+
{{- end }}

deploy/helm/secret-operator/templates/daemonset.yaml renamed to deploy/helm/secret-operator/templates/csi-node-driver-daemonset.yaml

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
apiVersion: apps/v1
33
kind: DaemonSet
44
metadata:
5-
name: {{ include "operator.fullname" . }}-daemonset
5+
name: {{ include "operator.fullname" . }}-csi-node-driver
66
labels:
77
{{- include "operator.labels" . | nindent 4 }}
88
spec:
@@ -11,28 +11,36 @@ spec:
1111
{{- include "operator.selectorLabels" . | nindent 6 }}
1212
template:
1313
metadata:
14-
{{- with .Values.podAnnotations }}
1514
annotations:
16-
{{- toYaml . | nindent 8 }}
17-
{{- end }}
15+
internal.stackable.tech/image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
16+
{{- with .Values.csiNodeDriver.podAnnotations }}
17+
{{- toYaml . | nindent 8 }}
18+
{{- end }}
1819
labels:
1920
{{- include "operator.selectorLabels" . | nindent 8 }}
2021
spec:
2122
{{- with .Values.image.pullSecrets }}
2223
imagePullSecrets:
2324
{{- toYaml . | nindent 8 }}
2425
{{- end }}
26+
# NOTE (@Techassi): Does it maybe make sense to have two different service accounts?
2527
serviceAccountName: {{ include "operator.fullname" . }}-serviceaccount
2628
securityContext:
27-
{{- toYaml .Values.podSecurityContext | nindent 8 }}
29+
{{- toYaml .Values.csiNodeDriver.podSecurityContext | nindent 8 }}
2830
containers:
29-
- name: {{ include "operator.appname" . }}
31+
- name: csi-node-service
3032
securityContext:
31-
{{- toYaml .Values.secretOperator.securityContext | nindent 12 }}
32-
image: "{{ .Values.secretOperator.image.repository }}:{{ .Values.secretOperator.image.tag | default .Chart.AppVersion }}"
33-
imagePullPolicy: {{ .Values.secretOperator.image.pullPolicy }}
33+
{{- toYaml .Values.csiNodeDriver.nodeService.securityContext | nindent 12 }}
34+
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
35+
imagePullPolicy: {{ .Values.image.pullPolicy }}
3436
resources:
35-
{{ .Values.secretOperator.resources | toYaml | nindent 12 }}
37+
{{ .Values.csiNodeDriver.nodeService.resources | toYaml | nindent 12 }}
38+
# The arguments passed to the command being run in the container. The final command will
39+
# look like `secret-operator run csi-server [OPTIONS]`. The CSI server needs to run on
40+
# every Kubernetes cluster node and as such is deployed as a DaemonSet.
41+
args:
42+
- run
43+
- csi-node-service
3644
env:
3745
# The following env vars are passed as clap (think CLI) arguments to the operator.
3846
# They are picked up by clap using the structs defied in the operator.
@@ -42,7 +50,7 @@ spec:
4250
- name: CSI_ENDPOINT
4351
value: /csi/csi.sock
4452
- name: PRIVILEGED
45-
value: {{ .Values.secretOperator.securityContext.privileged | quote }}
53+
value: {{ .Values.csiNodeDriver.nodeService.securityContext.privileged | quote }}
4654

4755
# Sometimes products need to know the operator image, e.g. the opa-bundle-builder OPA
4856
# sidecar uses the operator image.
@@ -80,32 +88,34 @@ spec:
8088
- name: csi
8189
mountPath: /csi
8290
- name: mountpoint
83-
mountPath: {{ .Values.kubeletDir }}/pods
84-
{{- if .Values.secretOperator.securityContext.privileged }}
91+
mountPath: {{ .Values.csiNodeDriver.kubeletDir }}/pods
92+
{{- if .Values.csiNodeDriver.nodeService.securityContext.privileged }}
8593
mountPropagation: Bidirectional
8694
{{- end }}
8795
- name: tmp
8896
mountPath: /tmp
97+
8998
- name: external-provisioner
90-
image: "{{ .Values.externalProvisioner.image.repository }}:{{ .Values.externalProvisioner.image.tag }}"
91-
imagePullPolicy: {{ .Values.externalProvisioner.image.pullPolicy }}
99+
image: "{{ .Values.csiNodeDriver.externalProvisioner.image.repository }}:{{ .Values.csiNodeDriver.externalProvisioner.image.tag }}"
100+
imagePullPolicy: {{ .Values.csiNodeDriver.externalProvisioner.image.pullPolicy }}
92101
resources:
93-
{{ .Values.externalProvisioner.resources | toYaml | nindent 12 }}
102+
{{ .Values.csiNodeDriver.externalProvisioner.resources | toYaml | nindent 12 }}
94103
args:
95104
- --csi-address=/csi/csi.sock
96105
- --feature-gates=Topology=true
97106
- --extra-create-metadata
98107
volumeMounts:
99108
- name: csi
100109
mountPath: /csi
110+
101111
- name: node-driver-registrar
102-
image: "{{ .Values.nodeDriverRegistrar.image.repository }}:{{ .Values.nodeDriverRegistrar.image.tag }}"
103-
imagePullPolicy: {{ .Values.nodeDriverRegistrar.image.pullPolicy }}
112+
image: "{{ .Values.csiNodeDriver.nodeDriverRegistrar.image.repository }}:{{ .Values.csiNodeDriver.nodeDriverRegistrar.image.tag }}"
113+
imagePullPolicy: {{ .Values.csiNodeDriver.nodeDriverRegistrar.image.pullPolicy }}
104114
resources:
105-
{{ .Values.nodeDriverRegistrar.resources | toYaml | nindent 12 }}
115+
{{ .Values.csiNodeDriver.nodeDriverRegistrar.resources | toYaml | nindent 12 }}
106116
args:
107117
- --csi-address=/csi/csi.sock
108-
- --kubelet-registration-path={{ .Values.kubeletDir }}/plugins/secrets.stackable.tech/csi.sock
118+
- --kubelet-registration-path={{ .Values.csiNodeDriver.kubeletDir }}/plugins/secrets.stackable.tech/csi.sock
109119
volumeMounts:
110120
- name: registration-sock
111121
mountPath: /registration
@@ -116,27 +126,27 @@ spec:
116126
hostPath:
117127
# node-driver-registrar appends a driver-unique filename to this path to avoid conflicts
118128
# see https://github.com/stackabletech/secret-operator/issues/229 for why this path should not be too long
119-
path: {{ .Values.kubeletDir }}/plugins_registry
129+
path: {{ .Values.csiNodeDriver.kubeletDir }}/plugins_registry
120130
- name: csi
121131
hostPath:
122-
path: {{ .Values.kubeletDir }}/plugins/secrets.stackable.tech/
132+
path: {{ .Values.csiNodeDriver.kubeletDir }}/plugins/secrets.stackable.tech/
123133
- name: mountpoint
124134
hostPath:
125-
path: {{ .Values.kubeletDir }}/pods/
135+
path: {{ .Values.csiNodeDriver.kubeletDir }}/pods/
126136
- name: tmp
127137
emptyDir: {}
128-
{{- with .Values.nodeSelector }}
138+
{{- with .Values.csiNodeDriver.nodeSelector }}
129139
nodeSelector:
130140
{{- toYaml . | nindent 8 }}
131141
{{- end }}
132-
{{- with .Values.affinity }}
142+
{{- with .Values.csiNodeDriver.affinity }}
133143
affinity:
134144
{{- toYaml . | nindent 8 }}
135145
{{- end }}
136-
{{- with .Values.tolerations }}
146+
{{- with .Values.csiNodeDriver.tolerations }}
137147
tolerations:
138148
{{- toYaml . | nindent 8 }}
139149
{{- end }}
140-
{{- with .Values.priorityClassName }}
150+
{{- with .Values.csiNodeDriver.priorityClassName }}
141151
priorityClassName: {{ . }}
142152
{{- end }}

0 commit comments

Comments
 (0)