Skip to content

Commit

Permalink
Increase ProgressDeadlineSeconds when startup probe is present
Browse files Browse the repository at this point in the history
  • Loading branch information
ReToCode committed Jun 6, 2024
1 parent 187e7c2 commit e2f4c8a
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 5 deletions.
20 changes: 19 additions & 1 deletion pkg/reconciler/revision/resources/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,24 @@ func MakeDeployment(rev *v1.Revision, cfg *config.Config) (*appsv1.Deployment, e
progressDeadline = int32(pd.Seconds())
}

startupProbeMaxDuration := int32(0)
for _, container := range podSpec.Containers {
if container.StartupProbe != nil {
maxSuccessDuration := container.StartupProbe.PeriodSeconds *
container.StartupProbe.SuccessThreshold *
container.StartupProbe.TimeoutSeconds

maxFailDuration := container.StartupProbe.PeriodSeconds *
container.StartupProbe.FailureThreshold *
container.StartupProbe.TimeoutSeconds

maxDuration := max(maxSuccessDuration, maxFailDuration)
if maxDuration > startupProbeMaxDuration {
startupProbeMaxDuration = container.StartupProbe.InitialDelaySeconds + maxDuration
}
}
}

labels := makeLabels(rev)
anns := makeAnnotations(rev)

Expand All @@ -365,7 +383,7 @@ func MakeDeployment(rev *v1.Revision, cfg *config.Config) (*appsv1.Deployment, e
Spec: appsv1.DeploymentSpec{
Replicas: ptr.Int32(replicaCount),
Selector: makeSelector(rev),
ProgressDeadlineSeconds: ptr.Int32(progressDeadline),
ProgressDeadlineSeconds: ptr.Int32(progressDeadline + startupProbeMaxDuration),
Strategy: appsv1.DeploymentStrategy{
Type: appsv1.RollingUpdateDeploymentStrategyType,
RollingUpdate: &appsv1.RollingUpdateDeployment{
Expand Down
150 changes: 146 additions & 4 deletions pkg/reconciler/revision/resources/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ var (
ReadinessProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Port: intstr.FromInt(int(queueHTTPPort.ContainerPort)),
Port: intstr.FromInt32(queueHTTPPort.ContainerPort),
HTTPHeaders: []corev1.HTTPHeader{{
Name: netheader.ProbeKey,
Value: queue.Name,
Expand Down Expand Up @@ -205,7 +205,7 @@ var (
EnableServiceLinks: ptr.Bool(false),
}

maxUnavailable = intstr.FromInt(0)
maxUnavailable = intstr.FromInt32(0)
defaultDeployment = &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Namespace: "foo",
Expand Down Expand Up @@ -376,6 +376,12 @@ func withLivenessProbe(handler corev1.ProbeHandler) containerOption {
}
}

func withStartupProbe(handler corev1.ProbeHandler) containerOption {
return func(container *corev1.Container) {
container.StartupProbe = &corev1.Probe{ProbeHandler: handler}
}
}

func withPrependedVolumeMounts(volumeMounts ...corev1.VolumeMount) containerOption {
return func(c *corev1.Container) {
c.VolumeMounts = append(volumeMounts, c.VolumeMounts...)
Expand Down Expand Up @@ -1013,7 +1019,7 @@ func TestMakePodSpec(t *testing.T) {
withLivenessProbe(corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/",
Port: intstr.FromInt(v1.DefaultUserPort),
Port: intstr.FromInt32(v1.DefaultUserPort),
},
}),
),
Expand Down Expand Up @@ -1043,8 +1049,69 @@ func TestMakePodSpec(t *testing.T) {
},
withLivenessProbe(corev1.ProbeHandler{
TCPSocket: &corev1.TCPSocketAction{
Port: intstr.FromInt(v1.DefaultUserPort),
Port: intstr.FromInt32(v1.DefaultUserPort),
},
}),
),
queueContainer(),
}),
}, {
name: "with HTTP startup probe",
rev: revision("bar", "foo",
withContainers([]corev1.Container{{
Name: servingContainerName,
Image: "busybox",
ReadinessProbe: withTCPReadinessProbe(v1.DefaultUserPort),
StartupProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/",
},
},
},
}}),
WithContainerStatuses([]v1.ContainerStatus{{
ImageDigest: "busybox@sha256:deadbeef",
}}),
),
want: podSpec(
[]corev1.Container{
servingContainer(
func(container *corev1.Container) {
container.Image = "busybox@sha256:deadbeef"
},
withStartupProbe(corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/",
},
}),
),
queueContainer(),
}),
}, {
name: "with TCP startup probe",
rev: revision("bar", "foo",
withContainers([]corev1.Container{{
Name: servingContainerName,
Image: "busybox",
ReadinessProbe: withTCPReadinessProbe(v1.DefaultUserPort),
StartupProbe: &corev1.Probe{
ProbeHandler: corev1.ProbeHandler{
TCPSocket: &corev1.TCPSocketAction{},
}}}},
),
WithContainerStatuses([]v1.ContainerStatus{{
ImageDigest: "busybox@sha256:deadbeef",
}}),
),
want: podSpec(
[]corev1.Container{
servingContainer(
func(container *corev1.Container) {
container.Image = "busybox@sha256:deadbeef"
},
withStartupProbe(corev1.ProbeHandler{
TCPSocket: &corev1.TCPSocketAction{},
}),
),
queueContainer(),
Expand Down Expand Up @@ -1554,6 +1621,81 @@ func TestMakeDeployment(t *testing.T) {
deploy.Annotations = map[string]string{serving.ProgressDeadlineAnnotationKey: "42s"}
deploy.Spec.Template.Annotations = map[string]string{serving.ProgressDeadlineAnnotationKey: "42s"}
}),
}, {
name: "with progress-deadline increase from single startup probe",
dc: deployment.Config{
ProgressDeadline: 42 * time.Second,
},
rev: revision("bar", "foo",
withContainers([]corev1.Container{{
Name: servingContainerName,
Image: "ubuntu",
ReadinessProbe: withTCPReadinessProbe(12345),
StartupProbe: &corev1.Probe{
InitialDelaySeconds: 10,
TimeoutSeconds: 30,
PeriodSeconds: 5,
SuccessThreshold: 1,
FailureThreshold: 3,
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/",
},
},
},
}}),
WithContainerStatuses([]v1.ContainerStatus{{
ImageDigest: "busybox@sha256:deadbeef",
}}), withoutLabels),
want: appsv1deployment(func(deploy *appsv1.Deployment) {
deploy.Spec.ProgressDeadlineSeconds = ptr.Int32(42 + 10 + (5 * 3 * 30))
}),
}, {
name: "with progress-deadline increase from multiple startup probes",
dc: deployment.Config{
ProgressDeadline: 42 * time.Second,
},
rev: revision("bar", "foo",
withContainers([]corev1.Container{{
Name: servingContainerName,
Image: "ubuntu",
ReadinessProbe: withTCPReadinessProbe(12345),
StartupProbe: &corev1.Probe{
InitialDelaySeconds: 10,
TimeoutSeconds: 30,
PeriodSeconds: 5,
SuccessThreshold: 1,
FailureThreshold: 3,
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/",
},
},
},
}, {
Name: servingContainerName + "-2",
Image: "sidecar",
StartupProbe: &corev1.Probe{
InitialDelaySeconds: 10,
TimeoutSeconds: 30,
PeriodSeconds: 5,
SuccessThreshold: 5,
FailureThreshold: 3,
ProbeHandler: corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/",
},
},
},
}}),
WithContainerStatuses([]v1.ContainerStatus{{
ImageDigest: "busybox@sha256:deadbeef",
}, {
ImageDigest: "busybox@sha256:deadbeef",
}}), withoutLabels),
want: appsv1deployment(func(deploy *appsv1.Deployment) {
deploy.Spec.ProgressDeadlineSeconds = ptr.Int32(42 + 10 + (5 * 5 * 30))
}),
}, {
name: "cluster initial scale",
acMutator: func(ac *autoscalerconfig.Config) {
Expand Down

0 comments on commit e2f4c8a

Please sign in to comment.