-
Notifications
You must be signed in to change notification settings - Fork 105
WIP [OCPBUGS-82081] Add preStop lifecycle hook to DNS pods to reduce upgrade disruption #475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -78,6 +78,11 @@ func TestDesiredDNSDaemonset(t *testing.T) { | |||||||||||||||||||||
| if e, a := coreDNSImage, c.Image; e != a { | ||||||||||||||||||||||
| t.Errorf("expected daemonset dns image %q, got %q", e, a) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if c.Lifecycle == nil || c.Lifecycle.PreStop == nil { | ||||||||||||||||||||||
| t.Error("expected dns container to have a preStop lifecycle hook") | ||||||||||||||||||||||
| } else if !reflect.DeepEqual(c.Lifecycle.PreStop.Exec.Command, []string{"sleep", "5"}) { | ||||||||||||||||||||||
| t.Errorf("unexpected preStop command: %v", c.Lifecycle.PreStop.Exec.Command) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+81
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard against nil Current assertion can panic if Suggested fix- if c.Lifecycle == nil || c.Lifecycle.PreStop == nil {
+ if c.Lifecycle == nil || c.Lifecycle.PreStop == nil || c.Lifecycle.PreStop.Exec == nil {
t.Error("expected dns container to have a preStop lifecycle hook")
} else if !reflect.DeepEqual(c.Lifecycle.PreStop.Exec.Command, []string{"sleep", "5"}) {
t.Errorf("unexpected preStop command: %v", c.Lifecycle.PreStop.Exec.Command)
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| case "kube-rbac-proxy": | ||||||||||||||||||||||
| if e, a := kubeRBACProxyImage, c.Image; e != a { | ||||||||||||||||||||||
| t.Errorf("expected daemonset kube rbac proxy image %q, got %q", e, a) | ||||||||||||||||||||||
|
|
@@ -86,6 +91,11 @@ func TestDesiredDNSDaemonset(t *testing.T) { | |||||||||||||||||||||
| t.Errorf("unexpected daemonset container %q", c.Name) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if ds.Spec.Template.Spec.TerminationGracePeriodSeconds == nil { | ||||||||||||||||||||||
| t.Error("expected terminationGracePeriodSeconds to be set") | ||||||||||||||||||||||
| } else if *ds.Spec.Template.Spec.TerminationGracePeriodSeconds != 40 { | ||||||||||||||||||||||
| t.Errorf("expected terminationGracePeriodSeconds=40, got %d", *ds.Spec.Template.Spec.TerminationGracePeriodSeconds) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -426,6 +436,19 @@ func TestDaemonsetConfigChanged(t *testing.T) { | |||||||||||||||||||||
| }, | ||||||||||||||||||||||
| expect: true, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| description: "if a container lifecycle is added", | ||||||||||||||||||||||
| mutate: func(daemonset *appsv1.DaemonSet) { | ||||||||||||||||||||||
| daemonset.Spec.Template.Spec.Containers[0].Lifecycle = &corev1.Lifecycle{ | ||||||||||||||||||||||
| PreStop: &corev1.LifecycleHandler{ | ||||||||||||||||||||||
| Exec: &corev1.ExecAction{ | ||||||||||||||||||||||
| Command: []string{"sleep", "5"}, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| expect: true, | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| description: "if an unexpected additional container is added", | ||||||||||||||||||||||
| mutate: func(daemonset *appsv1.DaemonSet) { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Does the OpenShift CoreDNS image used by cluster-dns-operator include asleepexecutable in PATH for Kubernetes preStop exec hooks?💡 Result:
No—the OpenShift CoreDNS image used by cluster-dns-operator does not include a general-purpose
sleepexecutable in PATH for KubernetespreStopexec hooks. Evidence: 1) The OpenShift-specific CoreDNS image Dockerfile only copies the CoreDNS binary into /usr/bin/ and does not addsleep(or any other shell tooling) into the image, so there is no basis to assume/bin/sleepor/usr/bin/sleepexists and is on PATH. The Dockerfile shows only a COPY ofcorednsto/usr/bin/and an ENTRYPOINT of/usr/bin/coredns. [1] 2) The OpenShift DNS operator’s “graceful shutdown” behavior is implemented via the CoreDNS health plugin being configured to sleep during shutdown, not via a Pod lifecyclepreStop execthat would require an in-imagesleepbinary. The operator commit explicitly says it configures “CoreDNS’s health plugin to sleep … when CoreDNS is shut down.” [2] Practical implication: - If you try to configure a KubernetespreStop: exec: ['sleep', 'N']for the OpenShift CoreDNS container, it is likely to fail becausesleepis not present in the image by design. (This aligns with the general CoreDNS ecosystem issue wherepreStopcan fail when the image lackssleep.) [3] If you want, tell me your OpenShift version (e.g., 4.14/4.15/4.16/4.17) and I can point you to the exact image tag/digest that your cluster-dns-operator uses and whether it matches the Dockerfile behavior above.Citations:
The
sleepcommand is not available in the OpenShift CoreDNS image and will cause thepreStophook to fail.The OpenShift CoreDNS container image is a minimal image containing only the CoreDNS binary, with no shell utilities like
sleep. Usingcommand: ["sleep", "5"]in thepreStop.exechook will fail at runtime, and the intended drain delay will not occur. If graceful shutdown is required, use the CoreDNS health plugin configuration (which is the operator's standard approach) rather than a Pod lifecycle hook that depends on missing binaries.🤖 Prompt for AI Agents