Skip to content

Commit e4d26f8

Browse files
committed
startupProbe: API changes
1 parent 4495d09 commit e4d26f8

File tree

6 files changed

+76
-6
lines changed

6 files changed

+76
-6
lines changed

pkg/api/pod/util.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,14 @@ func dropDisabledFields(
383383
})
384384
}
385385

386+
if !utilfeature.DefaultFeatureGate.Enabled(features.StartupProbe) && !startupProbeInUse(oldPodSpec) {
387+
// drop startupProbe from all containers if the feature is disabled
388+
VisitContainers(podSpec, func(c *api.Container) bool {
389+
c.StartupProbe = nil
390+
return true
391+
})
392+
}
393+
386394
dropDisabledVolumeDevicesFields(podSpec, oldPodSpec)
387395

388396
dropDisabledRunAsGroupField(podSpec, oldPodSpec)
@@ -819,6 +827,24 @@ func subpathExprInUse(podSpec *api.PodSpec) bool {
819827
return inUse
820828
}
821829

830+
// startupProbeInUse returns true if the pod spec is non-nil and has a container that has a startupProbe defined
831+
func startupProbeInUse(podSpec *api.PodSpec) bool {
832+
if podSpec == nil {
833+
return false
834+
}
835+
836+
var inUse bool
837+
VisitContainers(podSpec, func(c *api.Container) bool {
838+
if c.StartupProbe != nil {
839+
inUse = true
840+
return false
841+
}
842+
return true
843+
})
844+
845+
return inUse
846+
}
847+
822848
// csiInUse returns true if any pod's spec include inline CSI volumes.
823849
func csiInUse(podSpec *api.PodSpec) bool {
824850
if podSpec == nil {

pkg/apis/core/types.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,7 @@ type Probe struct {
19241924
// +optional
19251925
PeriodSeconds int32
19261926
// Minimum consecutive successes for the probe to be considered successful after having failed.
1927-
// Must be 1 for liveness.
1927+
// Must be 1 for liveness and startup.
19281928
// +optional
19291929
SuccessThreshold int32
19301930
// Minimum consecutive failures for the probe to be considered failed after having succeeded.
@@ -2042,6 +2042,8 @@ type Container struct {
20422042
// +optional
20432043
ReadinessProbe *Probe
20442044
// +optional
2045+
StartupProbe *Probe
2046+
// +optional
20452047
Lifecycle *Lifecycle
20462048
// Required.
20472049
// +optional
@@ -2090,7 +2092,7 @@ type Lifecycle struct {
20902092
// +optional
20912093
PostStart *Handler
20922094
// PreStop is called immediately before a container is terminated due to an
2093-
// API request or management event such as liveness probe failure,
2095+
// API request or management event such as liveness/startup probe failure,
20942096
// preemption, resource contention, etc. The handler is not called if the
20952097
// container crashes or exits. The reason for termination is passed to the
20962098
// handler. The Pod's termination grace period countdown begins before the
@@ -2174,6 +2176,7 @@ type ContainerStatus struct {
21742176
ImageID string
21752177
// +optional
21762178
ContainerID string
2179+
Started *bool
21772180
}
21782181

21792182
// PodPhase is a label for the condition of a pod at the current time.
@@ -2936,6 +2939,9 @@ type EphemeralContainerCommon struct {
29362939
// Probes are not allowed for ephemeral containers.
29372940
// +optional
29382941
ReadinessProbe *Probe
2942+
// Probes are not allowed for ephemeral containers.
2943+
// +optional
2944+
StartupProbe *Probe
29392945
// Lifecycle is not allowed for ephemeral containers.
29402946
// +optional
29412947
Lifecycle *Lifecycle

pkg/apis/core/validation/validation.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,6 +2696,9 @@ func validateInitContainers(containers, otherContainers []core.Container, device
26962696
if ctr.ReadinessProbe != nil {
26972697
allErrs = append(allErrs, field.Invalid(idxPath.Child("readinessProbe"), ctr.ReadinessProbe, "must not be set for init containers"))
26982698
}
2699+
if ctr.StartupProbe != nil {
2700+
allErrs = append(allErrs, field.Invalid(idxPath.Child("startupProbe"), ctr.StartupProbe, "must not be set for init containers"))
2701+
}
26992702
}
27002703
return allErrs
27012704
}
@@ -2738,6 +2741,11 @@ func validateContainers(containers []core.Container, isInitContainers bool, volu
27382741
if ctr.LivenessProbe != nil && ctr.LivenessProbe.SuccessThreshold != 1 {
27392742
allErrs = append(allErrs, field.Invalid(idxPath.Child("livenessProbe", "successThreshold"), ctr.LivenessProbe.SuccessThreshold, "must be 1"))
27402743
}
2744+
allErrs = append(allErrs, validateProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...)
2745+
// Startup-specific validation
2746+
if ctr.StartupProbe != nil && ctr.StartupProbe.SuccessThreshold != 1 {
2747+
allErrs = append(allErrs, field.Invalid(idxPath.Child("startupProbe", "successThreshold"), ctr.StartupProbe.SuccessThreshold, "must be 1"))
2748+
}
27412749

27422750
switch ctr.TerminationMessagePolicy {
27432751
case core.TerminationMessageReadFile, core.TerminationMessageFallbackToLogsOnError:

pkg/features/kube_features.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,12 @@ const (
489489
//
490490
// Schedule pods evenly across available topology domains.
491491
EvenPodsSpread featuregate.Feature = "EvenPodsSpread"
492+
493+
// owner: @matthyx
494+
// alpha: v1.16
495+
//
496+
// Enables the startupProbe in kubelet worker.
497+
StartupProbe featuregate.Feature = "StartupProbe"
492498
)
493499

494500
func init() {
@@ -569,6 +575,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
569575
IPv6DualStack: {Default: false, PreRelease: featuregate.Alpha},
570576
EndpointSlice: {Default: false, PreRelease: featuregate.Alpha},
571577
EvenPodsSpread: {Default: false, PreRelease: featuregate.Alpha},
578+
StartupProbe: {Default: false, PreRelease: featuregate.Alpha},
572579

573580
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
574581
// unintentionally on either side:
@@ -592,6 +599,6 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
592599

593600
// features that enable backwards compatibility but are scheduled to be removed
594601
// ...
595-
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
602+
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
596603
LegacyNodeRoleBehavior: {Default: true, PreRelease: featuregate.Alpha},
597604
}

staging/src/k8s.io/api/core/v1/types.go

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2025,7 +2025,7 @@ type Probe struct {
20252025
// +optional
20262026
PeriodSeconds int32 `json:"periodSeconds,omitempty" protobuf:"varint,4,opt,name=periodSeconds"`
20272027
// Minimum consecutive successes for the probe to be considered successful after having failed.
2028-
// Defaults to 1. Must be 1 for liveness. Minimum value is 1.
2028+
// Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
20292029
// +optional
20302030
SuccessThreshold int32 `json:"successThreshold,omitempty" protobuf:"varint,5,opt,name=successThreshold"`
20312031
// Minimum consecutive failures for the probe to be considered failed after having succeeded.
@@ -2196,6 +2196,16 @@ type Container struct {
21962196
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
21972197
// +optional
21982198
ReadinessProbe *Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"`
2199+
// StartupProbe indicates that the Pod has successfully initialized.
2200+
// If specified, no other probes are executed until this completes successfully.
2201+
// If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
2202+
// This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
2203+
// when it might take a long time to load data or warm a cache, than during steady-state operation.
2204+
// This cannot be updated.
2205+
// This is an alpha feature enabled by the StartupProbe feature flag.
2206+
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
2207+
// +optional
2208+
StartupProbe *Probe `json:"startupProbe,omitempty" protobuf:"bytes,22,opt,name=startupProbe"`
21992209
// Actions that the management system should take in response to container lifecycle events.
22002210
// Cannot be updated.
22012211
// +optional
@@ -2282,7 +2292,7 @@ type Lifecycle struct {
22822292
// +optional
22832293
PostStart *Handler `json:"postStart,omitempty" protobuf:"bytes,1,opt,name=postStart"`
22842294
// PreStop is called immediately before a container is terminated due to an
2285-
// API request or management event such as liveness probe failure,
2295+
// API request or management event such as liveness/startup probe failure,
22862296
// preemption, resource contention, etc. The handler is not called if the
22872297
// container crashes or exits. The reason for termination is passed to the
22882298
// handler. The Pod's termination grace period countdown begins before the
@@ -2390,6 +2400,12 @@ type ContainerStatus struct {
23902400
// Container's ID in the format 'docker://<container_id>'.
23912401
// +optional
23922402
ContainerID string `json:"containerID,omitempty" protobuf:"bytes,8,opt,name=containerID"`
2403+
// Specifies whether the container has passed its startup probe.
2404+
// Initialized as false, becomes true after startupProbe is considered successful.
2405+
// Resets to false when the container is restarted, or if kubelet loses state temporarily.
2406+
// Is always true when no startupProbe is defined.
2407+
// +optional
2408+
Started *bool `json:"started,omitempty" protobuf:"varint,9,opt,name=started"`
23932409
}
23942410

23952411
// PodPhase is a label for the condition of a pod at the current time.
@@ -2825,7 +2841,7 @@ type PodSpec struct {
28252841
// init container fails, the pod is considered to have failed and is handled according
28262842
// to its restartPolicy. The name for an init container or normal container must be
28272843
// unique among all containers.
2828-
// Init containers may not have Lifecycle actions, Readiness probes, or Liveness probes.
2844+
// Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes.
28292845
// The resourceRequirements of an init container are taken into account during scheduling
28302846
// by finding the highest request/limit for each resource type, and then using the max of
28312847
// of that value or the sum of the normal containers. Limits are applied to init containers
@@ -3293,6 +3309,9 @@ type EphemeralContainerCommon struct {
32933309
// Probes are not allowed for ephemeral containers.
32943310
// +optional
32953311
ReadinessProbe *Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"`
3312+
// Probes are not allowed for ephemeral containers.
3313+
// +optional
3314+
StartupProbe *Probe `json:"startupProbe,omitempty" protobuf:"bytes,22,opt,name=startupProbe"`
32963315
// Lifecycle is not allowed for ephemeral containers.
32973316
// +optional
32983317
Lifecycle *Lifecycle `json:"lifecycle,omitempty" protobuf:"bytes,12,opt,name=lifecycle"`

staging/src/k8s.io/kubectl/pkg/describe/versioned/describe.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,10 @@ func describeContainerProbe(container corev1.Container, w PrefixWriter) {
17071707
probe := DescribeProbe(container.ReadinessProbe)
17081708
w.Write(LEVEL_2, "Readiness:\t%s\n", probe)
17091709
}
1710+
if container.StartupProbe != nil {
1711+
probe := DescribeProbe(container.StartupProbe)
1712+
w.Write(LEVEL_2, "Startup:\t%s\n", probe)
1713+
}
17101714
}
17111715

17121716
func describeContainerVolumes(container corev1.Container, w PrefixWriter) {

0 commit comments

Comments
 (0)