Browse Source

feat(helm): add readinessProbe support for external-secrets deployment (#5831)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Gergely Bräutigam <skarlso777@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Co-authored-by: Umaid Abbasi <91631027+umizoom@users.noreply.github.com>
Co-authored-by: Joshua N Haupt <joshuanhaupt@outlook.com>
Co-authored-by: n4zukker <n4zukker@users.noreply.github.com>
Co-authored-by: Remy Bertot <stripthis@users.noreply.github.com>
Co-authored-by: Moritz Johner <moolen@users.noreply.github.com>
Co-authored-by: Gustavo Fernandes de Carvalho <17139678+gusfcarvalho@users.noreply.github.com>
Co-authored-by: Jean-Philippe Evrard <jean-philippe.evrard+rochepub@external.roche.com>
Co-authored-by: Jan Lauber <jan.lauber@protonmail.ch>
Co-authored-by: varonix <62331820+varonix0@users.noreply.github.com>
Co-authored-by: lochan_2112 <rn.lochan@gmail.com>
Co-authored-by: Fan Zhang <m42zhang@uwaterloo.ca>
Co-authored-by: Gergely Bräutigam <gergely.brautigam@sap.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Nutmos <nutmos@users.noreply.github.com>
Co-authored-by: Raj Singh <rajsinghcpre@gmail.com>
Co-authored-by: Anders Swanson <91502735+anders-swanson@users.noreply.github.com>
Co-authored-by: Richard Ahlquist <richard.jimmy.johansson@gmail.com>
Co-authored-by: Sakari Tanskanen <sakari.tanskanen@gmail.com>
Co-authored-by: José Maia <josecbmaia@hotmail.com>
Co-authored-by: Anna Kuzmenko <31698540+greenmapc@users.noreply.github.com>
Co-authored-by: Olivier Thomann <Olivier_Thomann@ca.ibm.com>
Co-authored-by: Evyatar Shtern <239746605+evs-secops@users.noreply.github.com>
Co-authored-by: Patrick Martin <patmarti@redhat.com>
Co-authored-by: Jaruwat Panturat <panturah@gmail.com>
Co-authored-by: Chad McElligott <chad.mcelligott@gmail.com>
Co-authored-by: Mateen Anjum <67343899+mateenali66@users.noreply.github.com>
Co-authored-by: cedricherzog-passbolt <cedric.herzog@passbolt.com>
Co-authored-by: Johnvox <jynolen+github@gmail.com>
Co-authored-by: Br1an <932039080@qq.com>
Co-authored-by: mzdeb <maciej@zdeb.pl>
Co-authored-by: Pascal Luckhaus <48798281+lucpas@users.noreply.github.com>
Alexander 3 weeks ago
parent
commit
07191d1853

+ 4 - 0
cmd/controller/root.go

@@ -298,6 +298,10 @@ var rootCmd = &cobra.Command{
 			setupLog.Error(err, "unable to add controller healthz check")
 			os.Exit(1)
 		}
+		if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
+			setupLog.Error(err, "unable to add controller readyz check")
+			os.Exit(1)
+		}
 
 		fs := feature.Features()
 		for _, f := range fs {

+ 12 - 2
deploy/charts/external-secrets/README.md

@@ -145,14 +145,14 @@ The command removes all the Kubernetes components associated with the chart and
 | leaderElect | bool | `false` | If true, external-secrets will perform leader election between instances to ensure no more than one instance of external-secrets operates at a time. |
 | livenessProbe.enabled | bool | `false` | Enabled determines if the liveness probe should be used or not. By default it's disabled. |
 | livenessProbe.spec | object | `{"address":"","failureThreshold":5,"httpGet":{"path":"/healthz","port":"live"},"initialDelaySeconds":10,"periodSeconds":10,"port":8082,"successThreshold":1,"timeoutSeconds":5}` | The body of the liveness probe settings. |
-| livenessProbe.spec.address | string | `""` | Address for liveness probe. |
+| livenessProbe.spec.address | string | `""` | Bind address for the health server used by both liveness and readiness probes (--live-addr flag). |
 | livenessProbe.spec.failureThreshold | int | `5` | Number of consecutive probe failures that should occur before considering the probe as failed. |
 | livenessProbe.spec.httpGet | object | `{"path":"/healthz","port":"live"}` | Handler for liveness probe. |
 | livenessProbe.spec.httpGet.path | string | `"/healthz"` | Path for liveness probe. |
 | livenessProbe.spec.httpGet.port | string | `"live"` | Set this value to 'live' (for named port) or an an integer for liveness probes. @schema type: [string, integer] |
 | livenessProbe.spec.initialDelaySeconds | int | `10` | Delay in seconds for the container to start before performing the initial probe. |
 | livenessProbe.spec.periodSeconds | int | `10` | Period in seconds for K8s to start performing probes. |
-| livenessProbe.spec.port | int | `8082` | Named port for liveness probe. |
+| livenessProbe.spec.port | int | `8082` | Port for the health server used by both liveness and readiness probes (--live-addr flag). |
 | livenessProbe.spec.successThreshold | int | `1` | Number of successful probes to mark probe successful. |
 | livenessProbe.spec.timeoutSeconds | int | `5` | Specify the maximum amount of time to wait for a probe to respond before considering it fails. |
 | log | object | `{"level":"info","timeEncoding":"epoch"}` | Specifies Log Params to the External Secrets Operator |
@@ -184,6 +184,16 @@ The command removes all the Kubernetes components associated with the chart and
 | rbac.aggregateToView | bool | `true` | Specifies whether permissions are aggregated to the view ClusterRole |
 | rbac.create | bool | `true` | Specifies whether role and rolebinding resources should be created. |
 | rbac.servicebindings.create | bool | `true` | Specifies whether a clusterrole to give servicebindings read access should be created. |
+| readinessProbe.enabled | bool | `false` | Determines whether the readiness probe is enabled. Disabled by default. Enabling this will auto-start the health server (--live-addr) even if livenessProbe is disabled. Health server address/port are configured via livenessProbe.spec.address and livenessProbe.spec.port. |
+| readinessProbe.spec | object | `{"failureThreshold":3,"httpGet":{"path":"/readyz","port":"live"},"initialDelaySeconds":10,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5}` | The body of the readiness probe settings (standard Kubernetes probe spec). |
+| readinessProbe.spec.failureThreshold | int | `3` | Number of consecutive probe failures that should occur before considering the probe as failed. |
+| readinessProbe.spec.httpGet | object | `{"path":"/readyz","port":"live"}` | Handler for readiness probe. |
+| readinessProbe.spec.httpGet.path | string | `"/readyz"` | Path for readiness probe. |
+| readinessProbe.spec.httpGet.port | string | `"live"` | Set this value to 'live' (for named port) or an integer for readiness probes. @schema type: [string, integer] |
+| readinessProbe.spec.initialDelaySeconds | int | `10` | Delay in seconds for the container to start before performing the initial probe. |
+| readinessProbe.spec.periodSeconds | int | `10` | Period in seconds for K8s to start performing probes. |
+| readinessProbe.spec.successThreshold | int | `1` | Number of successful probes to mark probe successful. |
+| readinessProbe.spec.timeoutSeconds | int | `5` | Specify the maximum amount of time to wait for a probe to respond before considering it fails. |
 | replicaCount | int | `1` |  |
 | resources | object | `{}` |  |
 | revisionHistoryLimit | int | `10` | Specifies the amount of historic ReplicaSets k8s should keep (see https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) |

+ 6 - 2
deploy/charts/external-secrets/templates/deployment.yaml

@@ -124,7 +124,7 @@ spec:
           - --metrics-addr=:{{ .Values.metrics.listen.port }}
           - --loglevel={{ .Values.log.level }}
           - --zap-time-encoding={{ .Values.log.timeEncoding }}
-          {{- if .Values.livenessProbe.enabled }}
+          {{- if or .Values.livenessProbe.enabled .Values.readinessProbe.enabled }}
           {{- if eq (kindOf .Values.livenessProbe.spec.httpGet.port) "string" }}
           - --live-addr={{ .Values.livenessProbe.spec.address }}:{{ .Values.livenessProbe.spec.port }}
           {{- else }}
@@ -141,7 +141,7 @@ spec:
             - containerPort: {{ .Values.metrics.listen.port }}
               protocol: TCP
               name: metrics
-            {{- if .Values.livenessProbe.enabled }}
+            {{- if or .Values.livenessProbe.enabled .Values.readinessProbe.enabled }}
             - name: live
               protocol: TCP
               {{- if eq (kindOf .Values.livenessProbe.spec.httpGet.port) "string" }}
@@ -154,6 +154,10 @@ spec:
           livenessProbe:
           {{- toYaml (omit .Values.livenessProbe.spec "address" "port") | nindent 12 }}
           {{- end }}
+          {{- if .Values.readinessProbe.enabled }}
+          readinessProbe:
+          {{- toYaml .Values.readinessProbe.spec | nindent 12 }}
+          {{- end }}
           {{- with .Values.extraEnv }}
           env:
             {{- toYaml . | nindent 12 }}

+ 142 - 0
deploy/charts/external-secrets/tests/controller_test.yaml

@@ -308,3 +308,145 @@ tests:
             - ip: "192.168.1.100"
               hostnames:
                 - "root.example.com"
+  - it: should add readinessProbe with defaults when enabled
+    set:
+      readinessProbe:
+        enabled: true
+    asserts:
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe
+          value:
+            timeoutSeconds: 5
+            failureThreshold: 3
+            periodSeconds: 10
+            successThreshold: 1
+            initialDelaySeconds: 10
+            httpGet:
+              port: live
+              path: /readyz
+      - equal:
+          path: spec.template.spec.containers[0].ports[1]
+          value:
+            containerPort: 8082
+            protocol: TCP
+            name: live
+      - contains:
+          path: spec.template.spec.containers[0].args
+          content: "--live-addr=:8082"
+      - notExists:
+          path: spec.template.spec.containers[0].livenessProbe
+  - it: should not render probes or health server when both probes are disabled
+    asserts:
+      - notExists:
+          path: spec.template.spec.containers[0].livenessProbe
+      - notExists:
+          path: spec.template.spec.containers[0].readinessProbe
+      - notContains:
+          path: spec.template.spec.containers[0].args
+          content: "--live-addr=:8082"
+  - it: should render both probes when both are enabled
+    set:
+      livenessProbe:
+        enabled: true
+      readinessProbe:
+        enabled: true
+    asserts:
+      - equal:
+          path: spec.template.spec.containers[0].livenessProbe
+          value:
+            timeoutSeconds: 5
+            failureThreshold: 5
+            periodSeconds: 10
+            successThreshold: 1
+            initialDelaySeconds: 10
+            httpGet:
+              port: live
+              path: /healthz
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe
+          value:
+            timeoutSeconds: 5
+            failureThreshold: 3
+            periodSeconds: 10
+            successThreshold: 1
+            initialDelaySeconds: 10
+            httpGet:
+              port: live
+              path: /readyz
+      - contains:
+          path: spec.template.spec.containers[0].args
+          content: "--live-addr=:8082"
+  - it: should use livenessProbe.spec.port for health server even when only readiness is enabled
+    set:
+      livenessProbe:
+        spec:
+          port: 9090
+      readinessProbe:
+        enabled: true
+    asserts:
+      - contains:
+          path: spec.template.spec.containers[0].args
+          content: "--live-addr=:9090"
+      - equal:
+          path: spec.template.spec.containers[0].ports[1]
+          value:
+            containerPort: 9090
+            protocol: TCP
+            name: live
+      - notExists:
+          path: spec.template.spec.containers[0].livenessProbe
+  - it: should use numeric httpGet.port for health server when liveness httpGet.port is numeric
+    set:
+      livenessProbe:
+        enabled: true
+        spec:
+          httpGet:
+            port: 8080
+            path: /healthz
+      readinessProbe:
+        enabled: true
+    asserts:
+      - contains:
+          path: spec.template.spec.containers[0].args
+          content: "--live-addr=:8080"
+      - equal:
+          path: spec.template.spec.containers[0].ports[1]
+          value:
+            containerPort: 8080
+            protocol: TCP
+            name: live
+  - it: should use custom address for health server
+    set:
+      livenessProbe:
+        enabled: true
+        spec:
+          address: "127.0.0.1"
+    asserts:
+      - contains:
+          path: spec.template.spec.containers[0].args
+          content: "--live-addr=127.0.0.1:8082"
+  - it: should customize readinessProbe spec independently
+    set:
+      readinessProbe:
+        enabled: true
+        spec:
+          timeoutSeconds: 3
+          failureThreshold: 5
+          periodSeconds: 15
+          successThreshold: 2
+          initialDelaySeconds: 20
+          httpGet:
+            port: live
+            path: /readyz
+    asserts:
+      - equal:
+          path: spec.template.spec.containers[0].readinessProbe
+          value:
+            timeoutSeconds: 3
+            failureThreshold: 5
+            periodSeconds: 15
+            successThreshold: 2
+            initialDelaySeconds: 20
+            httpGet:
+              port: live
+              path: /readyz

+ 42 - 0
deploy/charts/external-secrets/values.schema.json

@@ -659,6 +659,48 @@
                 }
             }
         },
+        "readinessProbe": {
+            "type": "object",
+            "properties": {
+                "enabled": {
+                    "type": "boolean"
+                },
+                "spec": {
+                    "type": "object",
+                    "properties": {
+                        "failureThreshold": {
+                            "type": "integer"
+                        },
+                        "httpGet": {
+                            "type": "object",
+                            "properties": {
+                                "path": {
+                                    "type": "string"
+                                },
+                                "port": {
+                                    "type": [
+                                        "string",
+                                        "integer"
+                                    ]
+                                }
+                            }
+                        },
+                        "initialDelaySeconds": {
+                            "type": "integer"
+                        },
+                        "periodSeconds": {
+                            "type": "integer"
+                        },
+                        "successThreshold": {
+                            "type": "integer"
+                        },
+                        "timeoutSeconds": {
+                            "type": "integer"
+                        }
+                    }
+                }
+            }
+        },
         "replicaCount": {
             "type": "integer"
         },

+ 25 - 2
deploy/charts/external-secrets/values.yaml

@@ -346,9 +346,9 @@ livenessProbe:
   enabled: false
   # -- The body of the liveness probe settings.
   spec:
-    # -- Address for liveness probe.
+    # -- Bind address for the health server used by both liveness and readiness probes (--live-addr flag).
     address: ""
-    # -- Named port for liveness probe.
+    # -- Port for the health server used by both liveness and readiness probes (--live-addr flag).
     port: 8082
     # -- Specify the maximum amount of time to wait for a probe to respond before considering it fails.
     timeoutSeconds: 5
@@ -368,6 +368,29 @@ livenessProbe:
       # -- Path for liveness probe.
       path: /healthz
 
+readinessProbe:
+  # -- Determines whether the readiness probe is enabled. Disabled by default. Enabling this will auto-start the health server (--live-addr) even if livenessProbe is disabled. Health server address/port are configured via livenessProbe.spec.address and livenessProbe.spec.port.
+  enabled: false
+  # -- The body of the readiness probe settings (standard Kubernetes probe spec).
+  spec:
+    # -- Specify the maximum amount of time to wait for a probe to respond before considering it fails.
+    timeoutSeconds: 5
+    # -- Number of consecutive probe failures that should occur before considering the probe as failed.
+    failureThreshold: 3
+    # -- Period in seconds for K8s to start performing probes.
+    periodSeconds: 10
+    # -- Number of successful probes to mark probe successful.
+    successThreshold: 1
+    # -- Delay in seconds for the container to start before performing the initial probe.
+    initialDelaySeconds: 10
+    # -- Handler for readiness probe.
+    httpGet:
+      # -- Set this value to 'live' (for named port) or an integer for readiness probes.
+      # @schema type: [string, integer]
+      port: live
+      # -- Path for readiness probe.
+      path: /readyz
+
 nodeSelector: {}
 
 tolerations: []