Răsfoiți Sursa

feat(charts): add startupProbe support to webhook deployment (#6612)

* feat(charts): add startupProbe support to webhook deployment

The webhook chart exposes livenessProbe and readinessProbe but not a
startupProbe, unlike the cert-controller which already supports one
(certController.startupProbe, #2217). Without a startupProbe, the
webhook's livenessProbe (~60s default window) can kill the container
while it is still waiting for a valid serving certificate at startup —
e.g. during initial cert provisioning or a certificate rotation —
turning a transient cert wait into a CrashLoopBackOff.

Add webhook.startupProbe mirroring the existing certController.startupProbe:
disabled by default (no change to rendered output), useReadinessProbePort
true by default, with an optional dedicated startup port. Updates values,
JSON schema, README, and adds unit tests covering both the readiness-port
and dedicated-port modes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: alpcanaydin <alpcan@reyz.ai>

* fix(charts): make webhook startupProbe timing configurable and guard empty port

Address review on the new webhook.startupProbe:

1. The startup grace period was hardcoded (initialDelaySeconds 20,
   periodSeconds 5, default failureThreshold 3 ~= 35s). Because kubelet
   suppresses liveness and readiness while the startup probe runs, this block
   is the whole startup window — and ~35s is shorter than the ~60s webhook
   liveness window it replaces, so enabling it would restart the container on
   a cert wait that liveness tolerates today. Expose initialDelaySeconds,
   periodSeconds and failureThreshold, defaulting to a ~310s window
   (10 + 30*10), comfortably above the liveness window.

2. A dedicated startup port left at its empty default rendered an invalid
   Deployment (a value-less containerPort and a startupProbe pointing at a
   port with no number). Add a template-time fail when the startup probe is
   enabled with useReadinessProbePort false and no port set.

Regenerate values.schema.json and README; add unit tests for the configurable
timing and the empty-port guard.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: alpcanaydin <alpcan@reyz.ai>

* fix(charts): drop non-functional startupProbe dedicated-port option

Per review: the webhook and cert-controller serve /readyz on a single health
address whose port number is fixed by the readiness port. A containerPort
entry is informational only in Kubernetes, so useReadinessProbePort=false
pointed the startupProbe at a port nothing listens on — a guaranteed
CrashLoopBackOff at runtime, not just a footgun when the port is unset. The
previous render-time guard only caught the unset-port case; a set-but-different
port still rendered cleanly and then CrashLooped.

Remove the dedicated-port branch, the useReadinessProbePort option, the port
value and the now-dead render guard; keep the startupProbe unconditionally on
the readiness port. Apply the same removal plus the configurable timing to
certController for consistency (it carried the same non-functional option and
the same too-short hardcoded window). Regenerate values.schema.json and README;
drop the port-override tests that locked in the broken path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: alpcanaydin <alpcan@reyz.ai>

* docs(charts): trim startupProbe failureThreshold comment

Per review, shorten the verbose multi-line grace-period explanation on the
webhook and certController startupProbe.failureThreshold to a single line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: alpcanaydin <alpcan@reyz.ai>

---------

Signed-off-by: alpcanaydin <alpcan@reyz.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Alpcan Aydın 1 săptămână în urmă
părinte
comite
5eaf0d602d

+ 8 - 3
deploy/charts/external-secrets/README.md

@@ -101,9 +101,10 @@ The command removes all the Kubernetes components associated with the chart and
 | certController.serviceAccount.create | bool | `true` | Specifies whether a service account should be created. |
 | certController.serviceAccount.extraLabels | object | `{}` | Extra Labels to add to the service account. |
 | certController.serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. |
-| certController.startupProbe.enabled | bool | `false` | Enabled determines if the startup probe should be used or not. By default it's enabled |
-| certController.startupProbe.port | string | `""` | Port for startup probe. |
-| certController.startupProbe.useReadinessProbePort | bool | `true` | whether to use the readiness probe port for startup probe. |
+| certController.startupProbe.enabled | bool | `false` | Enabled determines if the startup probe should be used or not. By default it's disabled. |
+| certController.startupProbe.failureThreshold | int | `30` | Number of consecutive failures before the container is restarted. The startup window is initialDelaySeconds + failureThreshold * periodSeconds. |
+| certController.startupProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before the startup probe is initiated. |
+| certController.startupProbe.periodSeconds | int | `10` | How often (in seconds) to perform the startup probe. |
 | certController.strategy | object | `{}` | Set deployment strategy |
 | certController.tolerations | list | `[]` |  |
 | certController.topologySpreadConstraints | list | `[]` |  |
@@ -337,6 +338,10 @@ The command removes all the Kubernetes components associated with the chart and
 | webhook.serviceAccount.create | bool | `true` | Specifies whether a service account should be created. |
 | webhook.serviceAccount.extraLabels | object | `{}` | Extra Labels to add to the service account. |
 | webhook.serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. |
+| webhook.startupProbe.enabled | bool | `false` | Enabled determines if the startup probe should be used or not. By default it's disabled. |
+| webhook.startupProbe.failureThreshold | int | `30` | Number of consecutive failures before the container is restarted. The startup window is initialDelaySeconds + failureThreshold * periodSeconds. |
+| webhook.startupProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before the startup probe is initiated. |
+| webhook.startupProbe.periodSeconds | int | `10` | How often (in seconds) to perform the startup probe. |
 | webhook.strategy | object | `{}` | Set deployment strategy |
 | webhook.tolerations | list | `[]` |  |
 | webhook.topologySpreadConstraints | list | `[]` |  |

+ 3 - 11
deploy/charts/external-secrets/templates/cert-controller-deployment.yaml

@@ -115,11 +115,6 @@ spec:
             - containerPort: {{ .Values.certController.readinessProbe.port }}
               protocol: TCP
               name: ready
-            {{- if and .Values.certController.startupProbe.enabled (not .Values.certController.startupProbe.useReadinessProbePort) }}
-            - containerPort: {{ .Values.certController.startupProbe.port }}
-              protocol: TCP
-              name: startup
-            {{- end }}
           {{- if .Values.certController.livenessProbe.enabled }}
           livenessProbe:
             httpGet:
@@ -145,14 +140,11 @@ spec:
           {{- if .Values.certController.startupProbe.enabled }}
           startupProbe:
             httpGet:
-              {{- if .Values.certController.startupProbe.useReadinessProbePort }}
               port: ready
-              {{- else }}
-              port: startup
-              {{- end }}
               path: /readyz
-            initialDelaySeconds: 20
-            periodSeconds: 5
+            initialDelaySeconds: {{ .Values.certController.startupProbe.initialDelaySeconds }}
+            periodSeconds: {{ .Values.certController.startupProbe.periodSeconds }}
+            failureThreshold: {{ .Values.certController.startupProbe.failureThreshold }}
           {{- end }}
           {{- with .Values.certController.extraEnv }}
           env:

+ 9 - 0
deploy/charts/external-secrets/templates/webhook-deployment.yaml

@@ -132,6 +132,15 @@ spec:
             failureThreshold: {{ .Values.webhook.readinessProbe.failureThreshold }}
             successThreshold: {{ .Values.webhook.readinessProbe.successThreshold }}
           {{- end }}
+          {{- if .Values.webhook.startupProbe.enabled }}
+          startupProbe:
+            httpGet:
+              port: ready
+              path: /readyz
+            initialDelaySeconds: {{ .Values.webhook.startupProbe.initialDelaySeconds }}
+            periodSeconds: {{ .Values.webhook.startupProbe.periodSeconds }}
+            failureThreshold: {{ .Values.webhook.startupProbe.failureThreshold }}
+          {{- end }}
           {{- with .Values.webhook.extraEnv }}
           env:
             {{- toYaml . | nindent 12 }}

+ 12 - 24
deploy/charts/external-secrets/tests/cert_controller_test.yaml

@@ -228,7 +228,7 @@ tests:
       - notContains:
           path: spec.template.spec.containers[0].args
           content: "--enable-http2"
-  - it: should have startup Probe if enabled
+  - it: should have startup Probe on the readiness port when enabled
     set:
       certController.startupProbe.enabled: true
     templates:
@@ -240,44 +240,32 @@ tests:
             httpGet:
               path: /readyz
               port: ready
-            initialDelaySeconds: 20
-            periodSeconds: 5
+            initialDelaySeconds: 10
+            periodSeconds: 10
+            failureThreshold: 30
       - equal:
           path: spec.template.spec.containers[0].ports[1].name
           value: ready
       - notExists:
           path: spec.template.spec.containers[0].ports[2]
-  - it: should override the startup Probe port
+  - it: should override the startup Probe timing
     set:
       certController.startupProbe.enabled: true
-      certController.startupProbe.useReadinessProbePort: false
-      certController.startupProbe.port: "8083"
+      certController.startupProbe.initialDelaySeconds: 5
+      certController.startupProbe.periodSeconds: 15
+      certController.startupProbe.failureThreshold: 40
     templates:
       - cert-controller-deployment.yaml
     asserts:
-      - equal:
-          path: spec.template.spec.containers[0].ports[2]
-          value:
-            containerPort: 8083
-            protocol: TCP
-            name: startup
       - equal:
           path: spec.template.spec.containers[0].startupProbe
           value:
             httpGet:
-              port: startup
               path: /readyz
-            initialDelaySeconds: 20
-            periodSeconds: 5
-      - equal:
-          path: spec.template.spec.containers[0].ports[2].name
-          value: startup
-      - equal:
-          path: spec.template.spec.containers[0].ports[2].protocol
-          value: TCP
-      - equal:
-          path: spec.template.spec.containers[0].ports[2].containerPort
-          value: 8083
+              port: ready
+            initialDelaySeconds: 5
+            periodSeconds: 15
+            failureThreshold: 40
   - it: should default to hostUsers absent
     set:
       certController.create: true

+ 38 - 0
deploy/charts/external-secrets/tests/webhook_test.yaml

@@ -560,3 +560,41 @@ tests:
             - ip: "192.168.1.100"
               hostnames:
                 - "webhook.example.com"
+  - it: should have startup probe on the readiness port when enabled
+    set:
+      webhook.startupProbe.enabled: true
+    templates:
+      - webhook-deployment.yaml
+    asserts:
+      - equal:
+          path: spec.template.spec.containers[0].startupProbe
+          value:
+            httpGet:
+              path: /readyz
+              port: ready
+            initialDelaySeconds: 10
+            periodSeconds: 10
+            failureThreshold: 30
+      - equal:
+          path: spec.template.spec.containers[0].ports[2].name
+          value: ready
+      - notExists:
+          path: spec.template.spec.containers[0].ports[3]
+  - it: should override the startup probe timing
+    set:
+      webhook.startupProbe.enabled: true
+      webhook.startupProbe.initialDelaySeconds: 5
+      webhook.startupProbe.periodSeconds: 15
+      webhook.startupProbe.failureThreshold: 40
+    templates:
+      - webhook-deployment.yaml
+    asserts:
+      - equal:
+          path: spec.template.spec.containers[0].startupProbe
+          value:
+            httpGet:
+              path: /readyz
+              port: ready
+            initialDelaySeconds: 5
+            periodSeconds: 15
+            failureThreshold: 40

+ 24 - 4
deploy/charts/external-secrets/values.schema.json

@@ -321,11 +321,14 @@
                         "enabled": {
                             "type": "boolean"
                         },
-                        "port": {
-                            "type": "string"
+                        "failureThreshold": {
+                            "type": "integer"
                         },
-                        "useReadinessProbePort": {
-                            "type": "boolean"
+                        "initialDelaySeconds": {
+                            "type": "integer"
+                        },
+                        "periodSeconds": {
+                            "type": "integer"
                         }
                     }
                 },
@@ -1321,6 +1324,23 @@
                         }
                     }
                 },
+                "startupProbe": {
+                    "type": "object",
+                    "properties": {
+                        "enabled": {
+                            "type": "boolean"
+                        },
+                        "failureThreshold": {
+                            "type": "integer"
+                        },
+                        "initialDelaySeconds": {
+                            "type": "integer"
+                        },
+                        "periodSeconds": {
+                            "type": "integer"
+                        }
+                    }
+                },
                 "strategy": {
                     "type": "object"
                 },

+ 17 - 5
deploy/charts/external-secrets/values.yaml

@@ -612,6 +612,16 @@ webhook:
     successThreshold: 1
     initialDelaySeconds: 20
 
+  startupProbe:
+    # -- Enabled determines if the startup probe should be used or not. By default it's disabled.
+    enabled: false
+    # -- Number of seconds after the container has started before the startup probe is initiated.
+    initialDelaySeconds: 10
+    # -- How often (in seconds) to perform the startup probe.
+    periodSeconds: 10
+    # -- Number of consecutive failures before the container is restarted. The startup window is initialDelaySeconds + failureThreshold * periodSeconds.
+    failureThreshold: 30
+
 
     ## -- Extra environment variables to add to container.
   extraEnv: []
@@ -788,12 +798,14 @@ certController:
     initialDelaySeconds: 20
 
   startupProbe:
-    # -- Enabled determines if the startup probe should be used or not. By default it's enabled
+    # -- Enabled determines if the startup probe should be used or not. By default it's disabled.
     enabled: false
-    # -- whether to use the readiness probe port for startup probe.
-    useReadinessProbePort: true
-    # -- Port for startup probe.
-    port: ""
+    # -- Number of seconds after the container has started before the startup probe is initiated.
+    initialDelaySeconds: 10
+    # -- How often (in seconds) to perform the startup probe.
+    periodSeconds: 10
+    # -- Number of consecutive failures before the container is restarted. The startup window is initialDelaySeconds + failureThreshold * periodSeconds.
+    failureThreshold: 30
 
     ## -- Extra environment variables to add to container.
   extraEnv: []