startupProbe: API changes

This commit is contained in:
Matthias Bertschy 2019-08-07 10:21:48 +02:00
parent 4495d09282
commit e4d26f845e
6 changed files with 76 additions and 6 deletions

View File

@ -383,6 +383,14 @@ func dropDisabledFields(
})
}
if !utilfeature.DefaultFeatureGate.Enabled(features.StartupProbe) && !startupProbeInUse(oldPodSpec) {
// drop startupProbe from all containers if the feature is disabled
VisitContainers(podSpec, func(c *api.Container) bool {
c.StartupProbe = nil
return true
})
}
dropDisabledVolumeDevicesFields(podSpec, oldPodSpec)
dropDisabledRunAsGroupField(podSpec, oldPodSpec)
@ -819,6 +827,24 @@ func subpathExprInUse(podSpec *api.PodSpec) bool {
return inUse
}
// startupProbeInUse returns true if the pod spec is non-nil and has a container that has a startupProbe defined
func startupProbeInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {
return false
}
var inUse bool
VisitContainers(podSpec, func(c *api.Container) bool {
if c.StartupProbe != nil {
inUse = true
return false
}
return true
})
return inUse
}
// csiInUse returns true if any pod's spec include inline CSI volumes.
func csiInUse(podSpec *api.PodSpec) bool {
if podSpec == nil {

View File

@ -1924,7 +1924,7 @@ type Probe struct {
// +optional
PeriodSeconds int32
// Minimum consecutive successes for the probe to be considered successful after having failed.
// Must be 1 for liveness.
// Must be 1 for liveness and startup.
// +optional
SuccessThreshold int32
// Minimum consecutive failures for the probe to be considered failed after having succeeded.
@ -2042,6 +2042,8 @@ type Container struct {
// +optional
ReadinessProbe *Probe
// +optional
StartupProbe *Probe
// +optional
Lifecycle *Lifecycle
// Required.
// +optional
@ -2090,7 +2092,7 @@ type Lifecycle struct {
// +optional
PostStart *Handler
// PreStop is called immediately before a container is terminated due to an
// API request or management event such as liveness probe failure,
// API request or management event such as liveness/startup probe failure,
// preemption, resource contention, etc. The handler is not called if the
// container crashes or exits. The reason for termination is passed to the
// handler. The Pod's termination grace period countdown begins before the
@ -2174,6 +2176,7 @@ type ContainerStatus struct {
ImageID string
// +optional
ContainerID string
Started *bool
}
// PodPhase is a label for the condition of a pod at the current time.
@ -2936,6 +2939,9 @@ type EphemeralContainerCommon struct {
// Probes are not allowed for ephemeral containers.
// +optional
ReadinessProbe *Probe
// Probes are not allowed for ephemeral containers.
// +optional
StartupProbe *Probe
// Lifecycle is not allowed for ephemeral containers.
// +optional
Lifecycle *Lifecycle

View File

@ -2696,6 +2696,9 @@ func validateInitContainers(containers, otherContainers []core.Container, device
if ctr.ReadinessProbe != nil {
allErrs = append(allErrs, field.Invalid(idxPath.Child("readinessProbe"), ctr.ReadinessProbe, "must not be set for init containers"))
}
if ctr.StartupProbe != nil {
allErrs = append(allErrs, field.Invalid(idxPath.Child("startupProbe"), ctr.StartupProbe, "must not be set for init containers"))
}
}
return allErrs
}
@ -2738,6 +2741,11 @@ func validateContainers(containers []core.Container, isInitContainers bool, volu
if ctr.LivenessProbe != nil && ctr.LivenessProbe.SuccessThreshold != 1 {
allErrs = append(allErrs, field.Invalid(idxPath.Child("livenessProbe", "successThreshold"), ctr.LivenessProbe.SuccessThreshold, "must be 1"))
}
allErrs = append(allErrs, validateProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...)
// Startup-specific validation
if ctr.StartupProbe != nil && ctr.StartupProbe.SuccessThreshold != 1 {
allErrs = append(allErrs, field.Invalid(idxPath.Child("startupProbe", "successThreshold"), ctr.StartupProbe.SuccessThreshold, "must be 1"))
}
switch ctr.TerminationMessagePolicy {
case core.TerminationMessageReadFile, core.TerminationMessageFallbackToLogsOnError:

View File

@ -489,6 +489,12 @@ const (
//
// Schedule pods evenly across available topology domains.
EvenPodsSpread featuregate.Feature = "EvenPodsSpread"
// owner: @matthyx
// alpha: v1.16
//
// Enables the startupProbe in kubelet worker.
StartupProbe featuregate.Feature = "StartupProbe"
)
func init() {
@ -569,6 +575,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
IPv6DualStack: {Default: false, PreRelease: featuregate.Alpha},
EndpointSlice: {Default: false, PreRelease: featuregate.Alpha},
EvenPodsSpread: {Default: false, PreRelease: featuregate.Alpha},
StartupProbe: {Default: false, PreRelease: featuregate.Alpha},
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side:
@ -592,6 +599,6 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
// features that enable backwards compatibility but are scheduled to be removed
// ...
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
LegacyNodeRoleBehavior: {Default: true, PreRelease: featuregate.Alpha},
}

View File

@ -2025,7 +2025,7 @@ type Probe struct {
// +optional
PeriodSeconds int32 `json:"periodSeconds,omitempty" protobuf:"varint,4,opt,name=periodSeconds"`
// Minimum consecutive successes for the probe to be considered successful after having failed.
// Defaults to 1. Must be 1 for liveness. Minimum value is 1.
// Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.
// +optional
SuccessThreshold int32 `json:"successThreshold,omitempty" protobuf:"varint,5,opt,name=successThreshold"`
// Minimum consecutive failures for the probe to be considered failed after having succeeded.
@ -2196,6 +2196,16 @@ type Container struct {
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
ReadinessProbe *Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"`
// StartupProbe indicates that the Pod has successfully initialized.
// If specified, no other probes are executed until this completes successfully.
// If this probe fails, the Pod will be restarted, just as if the livenessProbe failed.
// This can be used to provide different probe parameters at the beginning of a Pod's lifecycle,
// when it might take a long time to load data or warm a cache, than during steady-state operation.
// This cannot be updated.
// This is an alpha feature enabled by the StartupProbe feature flag.
// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
// +optional
StartupProbe *Probe `json:"startupProbe,omitempty" protobuf:"bytes,22,opt,name=startupProbe"`
// Actions that the management system should take in response to container lifecycle events.
// Cannot be updated.
// +optional
@ -2282,7 +2292,7 @@ type Lifecycle struct {
// +optional
PostStart *Handler `json:"postStart,omitempty" protobuf:"bytes,1,opt,name=postStart"`
// PreStop is called immediately before a container is terminated due to an
// API request or management event such as liveness probe failure,
// API request or management event such as liveness/startup probe failure,
// preemption, resource contention, etc. The handler is not called if the
// container crashes or exits. The reason for termination is passed to the
// handler. The Pod's termination grace period countdown begins before the
@ -2390,6 +2400,12 @@ type ContainerStatus struct {
// Container's ID in the format 'docker://<container_id>'.
// +optional
ContainerID string `json:"containerID,omitempty" protobuf:"bytes,8,opt,name=containerID"`
// Specifies whether the container has passed its startup probe.
// Initialized as false, becomes true after startupProbe is considered successful.
// Resets to false when the container is restarted, or if kubelet loses state temporarily.
// Is always true when no startupProbe is defined.
// +optional
Started *bool `json:"started,omitempty" protobuf:"varint,9,opt,name=started"`
}
// PodPhase is a label for the condition of a pod at the current time.
@ -2825,7 +2841,7 @@ type PodSpec struct {
// init container fails, the pod is considered to have failed and is handled according
// to its restartPolicy. The name for an init container or normal container must be
// unique among all containers.
// Init containers may not have Lifecycle actions, Readiness probes, or Liveness probes.
// Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes.
// The resourceRequirements of an init container are taken into account during scheduling
// by finding the highest request/limit for each resource type, and then using the max of
// of that value or the sum of the normal containers. Limits are applied to init containers
@ -3293,6 +3309,9 @@ type EphemeralContainerCommon struct {
// Probes are not allowed for ephemeral containers.
// +optional
ReadinessProbe *Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"`
// Probes are not allowed for ephemeral containers.
// +optional
StartupProbe *Probe `json:"startupProbe,omitempty" protobuf:"bytes,22,opt,name=startupProbe"`
// Lifecycle is not allowed for ephemeral containers.
// +optional
Lifecycle *Lifecycle `json:"lifecycle,omitempty" protobuf:"bytes,12,opt,name=lifecycle"`

View File

@ -1707,6 +1707,10 @@ func describeContainerProbe(container corev1.Container, w PrefixWriter) {
probe := DescribeProbe(container.ReadinessProbe)
w.Write(LEVEL_2, "Readiness:\t%s\n", probe)
}
if container.StartupProbe != nil {
probe := DescribeProbe(container.StartupProbe)
w.Write(LEVEL_2, "Startup:\t%s\n", probe)
}
}
func describeContainerVolumes(container corev1.Container, w PrefixWriter) {