feat(deployment): make startup probe failure threshold configurable (#1086)

* feat(deployment): make startup probe failure threshold configurable

Add StartupProbeFailureThreshold field to TenantControlPlane CRD
DeploymentSpec, allowing users to configure how many consecutive
startup probe failures are tolerated before a container is considered
failed. The value is applied to all control plane components
(kube-apiserver, controller-manager, and scheduler).

Defaults to 3 (preserving current behavior). With PeriodSeconds=10,
the total startup timeout equals FailureThreshold * 10 seconds.
Setting this to 30 gives 5 minutes, which is useful for
resource-constrained environments.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

* chore: regenerate CRD manifests for startupProbeFailureThreshold

Run `make manifests` to update Helm CRD files with the new
startupProbeFailureThreshold field in DeploymentSpec.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

* feat(deployment): expand configurable probes to all probe types

Replace StartupProbeFailureThreshold with a full Probes config
supporting liveness, readiness, and startup probes with configurable
TimeoutSeconds, PeriodSeconds, and FailureThreshold parameters.
Use ptr.Deref for safe pointer dereferencing.

Ref: #471

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

* chore: regenerate CRD manifests and API documentation

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

* feat(deployment): add per-component probe overrides and expand ProbeSpec

Add cascading probe configuration: global defaults → per-component
overrides (apiServer, controllerManager, scheduler). Expand ProbeSpec
with InitialDelaySeconds and SuccessThreshold fields.

Ref: #471

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

* chore: regenerate CRD manifests and API documentation

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>

---------

Signed-off-by: Aleksei Sviridkin <f@lex.la>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Aleksei Sviridkin
2026-02-24 16:20:06 +01:00
committed by GitHub
co-authored by Claude
parent b3ddfcda27
commit 69d62273c2
7 changed files with 2095 additions and 0 deletions
+52
View File
@@ -173,6 +173,54 @@ type ControlPlaneComponentsResources struct {
Kine *corev1.ResourceRequirements `json:"kine,omitempty"`
}
// ProbeSpec defines configurable parameters for a Kubernetes probe.
type ProbeSpec struct {
// InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
//+kubebuilder:validation:Minimum=0
InitialDelaySeconds *int32 `json:"initialDelaySeconds,omitempty"`
// TimeoutSeconds is the number of seconds after which the probe times out.
//+kubebuilder:validation:Minimum=1
TimeoutSeconds *int32 `json:"timeoutSeconds,omitempty"`
// PeriodSeconds is how often (in seconds) to perform the probe.
//+kubebuilder:validation:Minimum=1
PeriodSeconds *int32 `json:"periodSeconds,omitempty"`
// SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
// Must be 1 for liveness and startup probes.
//+kubebuilder:validation:Minimum=1
SuccessThreshold *int32 `json:"successThreshold,omitempty"`
// FailureThreshold is the consecutive failure count required to consider the probe failed.
//+kubebuilder:validation:Minimum=1
FailureThreshold *int32 `json:"failureThreshold,omitempty"`
}
// ProbeSet defines per-probe-type configuration.
type ProbeSet struct {
// Liveness defines parameters for the liveness probe.
Liveness *ProbeSpec `json:"liveness,omitempty"`
// Readiness defines parameters for the readiness probe.
Readiness *ProbeSpec `json:"readiness,omitempty"`
// Startup defines parameters for the startup probe.
Startup *ProbeSpec `json:"startup,omitempty"`
}
// ControlPlaneProbes defines probe configuration for Control Plane components.
// Global probe settings (Liveness, Readiness, Startup) apply to all components.
// Per-component settings (APIServer, ControllerManager, Scheduler) override global settings.
type ControlPlaneProbes struct {
// Liveness defines default parameters for liveness probes of all Control Plane components.
Liveness *ProbeSpec `json:"liveness,omitempty"`
// Readiness defines default parameters for the readiness probe of kube-apiserver.
Readiness *ProbeSpec `json:"readiness,omitempty"`
// Startup defines default parameters for startup probes of all Control Plane components.
Startup *ProbeSpec `json:"startup,omitempty"`
// APIServer defines probe overrides for kube-apiserver, taking precedence over global probe settings.
APIServer *ProbeSet `json:"apiServer,omitempty"`
// ControllerManager defines probe overrides for kube-controller-manager, taking precedence over global probe settings.
ControllerManager *ProbeSet `json:"controllerManager,omitempty"`
// Scheduler defines probe overrides for kube-scheduler, taking precedence over global probe settings.
Scheduler *ProbeSet `json:"scheduler,omitempty"`
}
type DeploymentSpec struct {
// RegistrySettings allows to override the default images for the given Tenant Control Plane instance.
// It could be used to point to a different container registry rather than the public one.
@@ -224,6 +272,10 @@ type DeploymentSpec struct {
// AdditionalVolumeMounts allows to mount an additional volume into each component of the Control Plane
// (kube-apiserver, controller-manager, and scheduler).
AdditionalVolumeMounts *AdditionalVolumeMounts `json:"additionalVolumeMounts,omitempty"`
// Probes defines the probe configuration for the Control Plane components
// (kube-apiserver, controller-manager, and scheduler).
// Override TimeoutSeconds, PeriodSeconds, and FailureThreshold for resource-constrained environments.
Probes *ControlPlaneProbes `json:"probes,omitempty"`
//+kubebuilder:default="default"
// ServiceAccountName allows to specify the service account to be mounted to the pods of the Control plane deployment
ServiceAccountName string `json:"serviceAccountName,omitempty"`
+120
View File
@@ -449,6 +449,51 @@ func (in *ControlPlaneExtraArgs) DeepCopy() *ControlPlaneExtraArgs {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ControlPlaneProbes) DeepCopyInto(out *ControlPlaneProbes) {
*out = *in
if in.Liveness != nil {
in, out := &in.Liveness, &out.Liveness
*out = new(ProbeSpec)
(*in).DeepCopyInto(*out)
}
if in.Readiness != nil {
in, out := &in.Readiness, &out.Readiness
*out = new(ProbeSpec)
(*in).DeepCopyInto(*out)
}
if in.Startup != nil {
in, out := &in.Startup, &out.Startup
*out = new(ProbeSpec)
(*in).DeepCopyInto(*out)
}
if in.APIServer != nil {
in, out := &in.APIServer, &out.APIServer
*out = new(ProbeSet)
(*in).DeepCopyInto(*out)
}
if in.ControllerManager != nil {
in, out := &in.ControllerManager, &out.ControllerManager
*out = new(ProbeSet)
(*in).DeepCopyInto(*out)
}
if in.Scheduler != nil {
in, out := &in.Scheduler, &out.Scheduler
*out = new(ProbeSet)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneProbes.
func (in *ControlPlaneProbes) DeepCopy() *ControlPlaneProbes {
if in == nil {
return nil
}
out := new(ControlPlaneProbes)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DataStore) DeepCopyInto(out *DataStore) {
*out = *in
@@ -709,6 +754,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) {
*out = new(AdditionalVolumeMounts)
(*in).DeepCopyInto(*out)
}
if in.Probes != nil {
in, out := &in.Probes, &out.Probes
*out = new(ControlPlaneProbes)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentSpec.
@@ -1493,6 +1543,76 @@ func (in *Permissions) DeepCopy() *Permissions {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProbeSet) DeepCopyInto(out *ProbeSet) {
*out = *in
if in.Liveness != nil {
in, out := &in.Liveness, &out.Liveness
*out = new(ProbeSpec)
(*in).DeepCopyInto(*out)
}
if in.Readiness != nil {
in, out := &in.Readiness, &out.Readiness
*out = new(ProbeSpec)
(*in).DeepCopyInto(*out)
}
if in.Startup != nil {
in, out := &in.Startup, &out.Startup
*out = new(ProbeSpec)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProbeSet.
func (in *ProbeSet) DeepCopy() *ProbeSet {
if in == nil {
return nil
}
out := new(ProbeSet)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProbeSpec) DeepCopyInto(out *ProbeSpec) {
*out = *in
if in.InitialDelaySeconds != nil {
in, out := &in.InitialDelaySeconds, &out.InitialDelaySeconds
*out = new(int32)
**out = **in
}
if in.TimeoutSeconds != nil {
in, out := &in.TimeoutSeconds, &out.TimeoutSeconds
*out = new(int32)
**out = **in
}
if in.PeriodSeconds != nil {
in, out := &in.PeriodSeconds, &out.PeriodSeconds
*out = new(int32)
**out = **in
}
if in.SuccessThreshold != nil {
in, out := &in.SuccessThreshold, &out.SuccessThreshold
*out = new(int32)
**out = **in
}
if in.FailureThreshold != nil {
in, out := &in.FailureThreshold, &out.FailureThreshold
*out = new(int32)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProbeSpec.
func (in *ProbeSpec) DeepCopy() *ProbeSpec {
if in == nil {
return nil
}
out := new(ProbeSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *PublicKeyPrivateKeyPairStatus) DeepCopyInto(out *PublicKeyPrivateKeyPairStatus) {
*out = *in
@@ -6165,6 +6165,397 @@ versions:
type: string
type: object
type: object
probes:
description: |-
Probes defines the probe configuration for the Control Plane components
(kube-apiserver, controller-manager, and scheduler).
Override TimeoutSeconds, PeriodSeconds, and FailureThreshold for resource-constrained environments.
properties:
apiServer:
description: APIServer defines probe overrides for kube-apiserver, taking precedence over global probe settings.
properties:
liveness:
description: Liveness defines parameters for the liveness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines parameters for the readiness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
startup:
description: Startup defines parameters for the startup probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
controllerManager:
description: ControllerManager defines probe overrides for kube-controller-manager, taking precedence over global probe settings.
properties:
liveness:
description: Liveness defines parameters for the liveness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines parameters for the readiness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
startup:
description: Startup defines parameters for the startup probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
liveness:
description: Liveness defines default parameters for liveness probes of all Control Plane components.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines default parameters for the readiness probe of kube-apiserver.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
scheduler:
description: Scheduler defines probe overrides for kube-scheduler, taking precedence over global probe settings.
properties:
liveness:
description: Liveness defines parameters for the liveness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines parameters for the readiness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
startup:
description: Startup defines parameters for the startup probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
startup:
description: Startup defines default parameters for startup probes of all Control Plane components.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
registrySettings:
default:
apiServerImage: kube-apiserver
@@ -6173,6 +6173,397 @@ spec:
type: string
type: object
type: object
probes:
description: |-
Probes defines the probe configuration for the Control Plane components
(kube-apiserver, controller-manager, and scheduler).
Override TimeoutSeconds, PeriodSeconds, and FailureThreshold for resource-constrained environments.
properties:
apiServer:
description: APIServer defines probe overrides for kube-apiserver, taking precedence over global probe settings.
properties:
liveness:
description: Liveness defines parameters for the liveness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines parameters for the readiness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
startup:
description: Startup defines parameters for the startup probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
controllerManager:
description: ControllerManager defines probe overrides for kube-controller-manager, taking precedence over global probe settings.
properties:
liveness:
description: Liveness defines parameters for the liveness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines parameters for the readiness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
startup:
description: Startup defines parameters for the startup probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
liveness:
description: Liveness defines default parameters for liveness probes of all Control Plane components.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines default parameters for the readiness probe of kube-apiserver.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
scheduler:
description: Scheduler defines probe overrides for kube-scheduler, taking precedence over global probe settings.
properties:
liveness:
description: Liveness defines parameters for the liveness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
readiness:
description: Readiness defines parameters for the readiness probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
startup:
description: Startup defines parameters for the startup probe.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
startup:
description: Startup defines default parameters for startup probes of all Control Plane components.
properties:
failureThreshold:
description: FailureThreshold is the consecutive failure count required to consider the probe failed.
format: int32
minimum: 1
type: integer
initialDelaySeconds:
description: InitialDelaySeconds is the number of seconds after the container has started before the probe is initiated.
format: int32
minimum: 0
type: integer
periodSeconds:
description: PeriodSeconds is how often (in seconds) to perform the probe.
format: int32
minimum: 1
type: integer
successThreshold:
description: |-
SuccessThreshold is the minimum consecutive successes for the probe to be considered successful.
Must be 1 for liveness and startup probes.
format: int32
minimum: 1
type: integer
timeoutSeconds:
description: TimeoutSeconds is the number of seconds after which the probe times out.
format: int32
minimum: 1
type: integer
type: object
type: object
registrySettings:
default:
apiServerImage: kube-apiserver
File diff suppressed because it is too large Load Diff
@@ -51,6 +51,18 @@ const (
kineInitContainerName = "chmod"
)
func applyProbeOverrides(probe *corev1.Probe, spec *kamajiv1alpha1.ProbeSpec) {
if spec == nil {
return
}
probe.InitialDelaySeconds = pointer.Deref(spec.InitialDelaySeconds, probe.InitialDelaySeconds)
probe.TimeoutSeconds = pointer.Deref(spec.TimeoutSeconds, probe.TimeoutSeconds)
probe.PeriodSeconds = pointer.Deref(spec.PeriodSeconds, probe.PeriodSeconds)
probe.SuccessThreshold = pointer.Deref(spec.SuccessThreshold, probe.SuccessThreshold)
probe.FailureThreshold = pointer.Deref(spec.FailureThreshold, probe.FailureThreshold)
}
type DataStoreOverrides struct {
Resource string
DataStore kamajiv1alpha1.DataStore
@@ -384,6 +396,16 @@ func (d Deployment) buildScheduler(podSpec *corev1.PodSpec, tenantControlPlane k
FailureThreshold: 3,
}
if probes := tenantControlPlane.Spec.ControlPlane.Deployment.Probes; probes != nil {
applyProbeOverrides(podSpec.Containers[index].LivenessProbe, probes.Liveness)
applyProbeOverrides(podSpec.Containers[index].StartupProbe, probes.Startup)
if probes.Scheduler != nil {
applyProbeOverrides(podSpec.Containers[index].LivenessProbe, probes.Scheduler.Liveness)
applyProbeOverrides(podSpec.Containers[index].StartupProbe, probes.Scheduler.Startup)
}
}
switch {
case tenantControlPlane.Spec.ControlPlane.Deployment.Resources == nil:
podSpec.Containers[index].Resources = corev1.ResourceRequirements{}
@@ -475,6 +497,17 @@ func (d Deployment) buildControllerManager(podSpec *corev1.PodSpec, tenantContro
SuccessThreshold: 1,
FailureThreshold: 3,
}
if probes := tenantControlPlane.Spec.ControlPlane.Deployment.Probes; probes != nil {
applyProbeOverrides(podSpec.Containers[index].LivenessProbe, probes.Liveness)
applyProbeOverrides(podSpec.Containers[index].StartupProbe, probes.Startup)
if probes.ControllerManager != nil {
applyProbeOverrides(podSpec.Containers[index].LivenessProbe, probes.ControllerManager.Liveness)
applyProbeOverrides(podSpec.Containers[index].StartupProbe, probes.ControllerManager.Startup)
}
}
switch {
case tenantControlPlane.Spec.ControlPlane.Deployment.Resources == nil:
podSpec.Containers[index].Resources = corev1.ResourceRequirements{}
@@ -606,6 +639,19 @@ func (d Deployment) buildKubeAPIServer(podSpec *corev1.PodSpec, tenantControlPla
SuccessThreshold: 1,
FailureThreshold: 3,
}
if probes := tenantControlPlane.Spec.ControlPlane.Deployment.Probes; probes != nil {
applyProbeOverrides(podSpec.Containers[index].LivenessProbe, probes.Liveness)
applyProbeOverrides(podSpec.Containers[index].ReadinessProbe, probes.Readiness)
applyProbeOverrides(podSpec.Containers[index].StartupProbe, probes.Startup)
if probes.APIServer != nil {
applyProbeOverrides(podSpec.Containers[index].LivenessProbe, probes.APIServer.Liveness)
applyProbeOverrides(podSpec.Containers[index].ReadinessProbe, probes.APIServer.Readiness)
applyProbeOverrides(podSpec.Containers[index].StartupProbe, probes.APIServer.Startup)
}
}
podSpec.Containers[index].ImagePullPolicy = corev1.PullAlways
// Volume mounts
var extraVolumeMounts []corev1.VolumeMount
@@ -4,12 +4,21 @@
package controlplane
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
pointer "k8s.io/utils/ptr"
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
)
func TestControlplaneDeployment(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Controlplane Deployment Suite")
}
var _ = Describe("Controlplane Deployment", func() {
var d Deployment
BeforeEach(func() {
@@ -43,4 +52,74 @@ var _ = Describe("Controlplane Deployment", func() {
Expect(etcdSerVersOverrides).To(Equal("/events#https://etcd-0;https://etcd-1;https://etcd-2,/pods#https://etcd-3;https://etcd-4;https://etcd-5"))
})
})
Describe("applyProbeOverrides", func() {
var probe *corev1.Probe
BeforeEach(func() {
probe = &corev1.Probe{
InitialDelaySeconds: 0,
TimeoutSeconds: 1,
PeriodSeconds: 10,
SuccessThreshold: 1,
FailureThreshold: 3,
}
})
It("should not modify probe when spec is nil", func() {
applyProbeOverrides(probe, nil)
Expect(probe.InitialDelaySeconds).To(Equal(int32(0)))
Expect(probe.TimeoutSeconds).To(Equal(int32(1)))
Expect(probe.PeriodSeconds).To(Equal(int32(10)))
Expect(probe.SuccessThreshold).To(Equal(int32(1)))
Expect(probe.FailureThreshold).To(Equal(int32(3)))
})
It("should override only FailureThreshold when only it is set", func() {
spec := &kamajiv1alpha1.ProbeSpec{
FailureThreshold: pointer.To(int32(30)),
}
applyProbeOverrides(probe, spec)
Expect(probe.FailureThreshold).To(Equal(int32(30)))
Expect(probe.InitialDelaySeconds).To(Equal(int32(0)))
Expect(probe.TimeoutSeconds).To(Equal(int32(1)))
Expect(probe.PeriodSeconds).To(Equal(int32(10)))
Expect(probe.SuccessThreshold).To(Equal(int32(1)))
})
It("should override all fields when all are set", func() {
spec := &kamajiv1alpha1.ProbeSpec{
InitialDelaySeconds: pointer.To(int32(15)),
TimeoutSeconds: pointer.To(int32(5)),
PeriodSeconds: pointer.To(int32(30)),
SuccessThreshold: pointer.To(int32(2)),
FailureThreshold: pointer.To(int32(10)),
}
applyProbeOverrides(probe, spec)
Expect(probe.InitialDelaySeconds).To(Equal(int32(15)))
Expect(probe.TimeoutSeconds).To(Equal(int32(5)))
Expect(probe.PeriodSeconds).To(Equal(int32(30)))
Expect(probe.SuccessThreshold).To(Equal(int32(2)))
Expect(probe.FailureThreshold).To(Equal(int32(10)))
})
It("should cascade global then component overrides", func() {
global := &kamajiv1alpha1.ProbeSpec{
FailureThreshold: pointer.To(int32(10)),
PeriodSeconds: pointer.To(int32(20)),
}
applyProbeOverrides(probe, global)
component := &kamajiv1alpha1.ProbeSpec{
FailureThreshold: pointer.To(int32(60)),
}
applyProbeOverrides(probe, component)
Expect(probe.FailureThreshold).To(Equal(int32(60)))
Expect(probe.PeriodSeconds).To(Equal(int32(20)))
Expect(probe.TimeoutSeconds).To(Equal(int32(1)))
Expect(probe.InitialDelaySeconds).To(Equal(int32(0)))
Expect(probe.SuccessThreshold).To(Equal(int32(1)))
})
})
})