Skip to content

Commit 1d4bb80

Browse files
authored
Merge pull request #5400 from sreeram-venkitesh/kep-4960-changes-for-1.34-alpha2
KEP 4960: Container Stop Signals - Update for v1.34
2 parents c64eaed + 9b31072 commit 1d4bb80

File tree

2 files changed

+72
-23
lines changed

2 files changed

+72
-23
lines changed

keps/sig-node/4960-container-stop-signals/README.md

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- [Non-Goals](#non-goals)
1010
- [Proposal](#proposal)
1111
- [API](#api)
12+
- [Cross validation with Pod spec.os.name](#cross-validation-with-pod-specosname)
1213
- [CRI API](#cri-api)
1314
- [Container runtime changes](#container-runtime-changes)
1415
- [Windows support](#windows-support)
@@ -46,20 +47,20 @@
4647

4748
Items marked with (R) are required *prior to targeting to a milestone / release*.
4849

49-
- [ ] (R) Enhancement issue in release milestone, which links to KEP dir in [kubernetes/enhancements] (not the initial KEP PR)
50-
- [ ] (R) KEP approvers have approved the KEP status as `implementable`
51-
- [ ] (R) Design details are appropriately documented
52-
- [ ] (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors)
50+
- [x] (R) Enhancement issue in release milestone, which links to KEP dir in [kubernetes/enhancements] (not the initial KEP PR)
51+
- [x] (R) KEP approvers have approved the KEP status as `implementable`
52+
- [x] (R) Design details are appropriately documented
53+
- [x] (R) Test plan is in place, giving consideration to SIG Architecture and SIG Testing input (including test refactors)
5354
- [ ] e2e Tests for all Beta API Operations (endpoints)
5455
- [ ] (R) Ensure GA e2e tests meet requirements for [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md)
5556
- [ ] (R) Minimum Two Week Window for GA e2e tests to prove flake free
56-
- [ ] (R) Graduation criteria is in place
57+
- [x] (R) Graduation criteria is in place
5758
- [ ] (R) [all GA Endpoints](https://github.com/kubernetes/community/pull/1806) must be hit by [Conformance Tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/conformance-tests.md)
58-
- [ ] (R) Production readiness review completed
59-
- [ ] (R) Production readiness review approved
60-
- [ ] "Implementation History" section is up-to-date for milestone
61-
- [ ] User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io]
62-
- [ ] Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes
59+
- [x] (R) Production readiness review completed
60+
- [x] (R) Production readiness review approved
61+
- [x] "Implementation History" section is up-to-date for milestone
62+
- [x] User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io]
63+
- [x] Supporting documentation—e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes
6364

6465
[kubernetes.io]: https://kubernetes.io/
6566
[kubernetes/enhancements]: https://git.k8s.io/enhancements
@@ -140,6 +141,42 @@ status:
140141
startedAt: "2025-01-16T09:13:15Z"
141142
```
142143
144+
### Cross validation with Pod spec.os.name
145+
146+
In order to make sure that users are setting valid stop signals for the nodes the pods are being scheduled to, we cross validate the `ContainerSpec.Lifecycle.StopSignal` with `spec.os.name`. Here are the details of this validation:
147+
- We require `spec.os.name` to be set to a valid value (`linux` or `windows`) to use `ContainerSpec.Lifecycle.StopSignal`.
148+
- We have a list of valid stop signals for both linux and windows nodes (as shown below). If the Pod OS is set to `linux`, only the signals supported for `linux` would be allowed.
149+
- Similarly for Pods with OS set to `windows`, we only allow SIGTERM and SIGKILL as valid stop signals.
150+
151+
The full list of valid signals for the two platforms are as follows:
152+
153+
```go
154+
var supportedStopSignalsLinux = sets.New(
155+
core.SIGABRT, core.SIGALRM, core.SIGBUS, core.SIGCHLD,
156+
core.SIGCLD, core.SIGCONT, core.SIGFPE, core.SIGHUP,
157+
core.SIGILL, core.SIGINT, core.SIGIO, core.SIGIOT,
158+
core.SIGKILL, core.SIGPIPE, core.SIGPOLL, core.SIGPROF,
159+
core.SIGPWR, core.SIGQUIT, core.SIGSEGV, core.SIGSTKFLT,
160+
core.SIGSTOP, core.SIGSYS, core.SIGTERM, core.SIGTRAP,
161+
core.SIGTSTP, core.SIGTTIN, core.SIGTTOU, core.SIGURG,
162+
core.SIGUSR1, core.SIGUSR2, core.SIGVTALRM, core.SIGWINCH,
163+
core.SIGXCPU, core.SIGXFSZ, core.SIGRTMIN, core.SIGRTMINPLUS1,
164+
core.SIGRTMINPLUS2, core.SIGRTMINPLUS3, core.SIGRTMINPLUS4,
165+
core.SIGRTMINPLUS5, core.SIGRTMINPLUS6, core.SIGRTMINPLUS7,
166+
core.SIGRTMINPLUS8, core.SIGRTMINPLUS9, core.SIGRTMINPLUS10,
167+
core.SIGRTMINPLUS11, core.SIGRTMINPLUS12, core.SIGRTMINPLUS13,
168+
core.SIGRTMINPLUS14, core.SIGRTMINPLUS15, core.SIGRTMAXMINUS14,
169+
core.SIGRTMAXMINUS13, core.SIGRTMAXMINUS12, core.SIGRTMAXMINUS11,
170+
core.SIGRTMAXMINUS10, core.SIGRTMAXMINUS9, core.SIGRTMAXMINUS8,
171+
core.SIGRTMAXMINUS7, core.SIGRTMAXMINUS6, core.SIGRTMAXMINUS5,
172+
core.SIGRTMAXMINUS4, core.SIGRTMAXMINUS3, core.SIGRTMAXMINUS2,
173+
core.SIGRTMAXMINUS1, core.SIGRTMAX)
174+
175+
var supportedStopSignalsWindows = sets.New(core.SIGKILL, core.SIGTERM)
176+
```
177+
178+
You can find the validation logic implemented in [this commit](https://github.com/kubernetes/kubernetes/pull/130556/commits/0380f2c41cdc4df992294603f7844709072628b1#diff-c713e8919642d873fdf48fe8fb6d43e5cb2f53fd601066ff53580ea655948f0d).
179+
143180
### CRI API
144181

145182
The CRI API would be updated so the stop signal in the container spec (if it is not nil or unset) is sent to the container runtime via ContainerConfig. This would be passed down to the container runtime's StopContainer method ultimately:
@@ -149,12 +186,16 @@ The CRI API would be updated so the stop signal in the container spec (if it is
149186
// container.
150187
message ContainerConfig {
151188
// ...
152-
+ Lifecycle lifecycle = 18;
189+
+ Signal stop_signal = 18;
153190
}
154191
155-
+message Lifecycle {
156-
+ string stop_signal = 1;
157-
+}
192+
+ enum Signal {
193+
+ RUNTIME_DEFAULT = 0;
194+
+ SIGABRT = 1;
195+
+ SIGALRM = 2;
196+
+ ...
197+
+ SIGRTMAX = 65;
198+
+ }
158199
```
159200

160201
We can pass the container's stop signal to the container runtime with this new field to ContainerConfig.
@@ -183,17 +224,20 @@ func (m *kubeGenericRuntimeManager) generateContainerConfig(...) (*runtimeapi.Co
183224
Stdin: container.Stdin,
184225
StdinOnce: container.StdinOnce,
185226
Tty: container.TTY,
186-
+ Lifecycle: &runtimeapi.Lifecycle{
187-
+ StopSignal: container.Lifecycle.StopSignal
188-
+ },
189227
}
228+
229+
+ stopsignal := getContainerConfigStopSignal(container)
230+
231+
+ if stopsignal != nil {
232+
+ config.StopSignal = *stopsignal
233+
+ }
190234
// ...
191235
}
192236
```
193237

194238
Since the new stop lifecycle is optional, the default stop signal for a container can be unset or nil. In this case, the container runtime will fallback to the existing behaviour.
195239

196-
Additionally, the stop signal would also be added to `ContainerStatus` (as `containerStatus[].Lifecycle.StopSignal`) so that we can pass the stop signal extracted from the image/container runtime back to the container status at the Kubernetes API level.
240+
Additionally, the stop signal would also be added to `ContainerStatus` (as `containerStatus[].StopSignal`) so that we can pass the stop signal extracted from the image/container runtime back to the container status at the Kubernetes API level.
197241

198242
### Container runtime changes
199243

@@ -205,7 +249,7 @@ Once the stop signal from `containerSpec.Lifecycle.StopSignal` is passed down to
205249
func (c *criService) StopContainer(ctx context.Context, r *runtime.StopContainerRequest) (*runtime.StopContainerResponse, error) {
206250
// ...
207251
- if err := c.stopContainer(ctx, container, time.Duration(r.GetTimeout())*time.Second); err != nil {
208-
+ if err := c.stopContainer(ctx, container, time.Duration(r.GetTimeout())*time.Second, container.Config.Lifecycle.StopSignal); err != nil {
252+
+ if err := c.stopContainer(ctx, container, time.Duration(r.GetTimeout())*time.Second, container.Config.GetStopSignal().String()); err != nil {
209253
return nil, err
210254
}
211255
// ...
@@ -233,7 +277,7 @@ Find the entire diff for containerd which was done for the POC [here](https://gi
233277

234278
Currently using the hcsshim is the only way to run containers on Windows nodes. hcsshim [supports SIGTERM and SIGKILL and a few Windows specific CTRL events](https://github.com/microsoft/hcsshim/blob/e5c83a121b980b1b85f4df0813cfba2d83572bac/internal/signals/signal.go#L74-L126). After discussing with SIG Windows, we came to the decision that for Windows Pods we'll only support SIGTERM and SIGKILL as the valid stop signals. The behaviour of how kubelet handles stop signals is not different for Linux and Windows environments and the CRI API works in both cases.
235279

236-
We will have additional validation for Windows Pods to restrict the set of valid stop signals to SIGTERM and SIGKILL. There will be an admission check that validates that the stop signal is only set to either SIGTERM or SIGKILL if spec.Os.Name == windows.
280+
We will have additional validation for Windows Pods to restrict the set of valid stop signals to SIGTERM and SIGKILL. There will be an admission check that validates that the stop signal is only set to either SIGTERM or SIGKILL if `spec.os.name` == windows. This OS specific cross validation is further described in [Cross validation with Pod spec.os.name](#cross-validation-with-pod-specosname).
237281

238282
### User Stories (Optional)
239283

@@ -491,6 +535,10 @@ Disable the ContainerStopSignal feature gate, and restart the kube-apiserver and
491535

492536
## Implementation History
493537

538+
- 2025-02-13: Alpha [KEP PR](https://github.com/kubernetes/enhancements/pull/5122) approved and merged for v1.33
539+
- 2025-03-25: Alpha [code changes to k/k](https://github.com/kubernetes/kubernetes/pull/130556) merged with API changes, validation and CRI API implementation
540+
- 2025-04-04: [CRI-O implementation PR](https://github.com/cri-o/cri-o/pull/9086) merged
541+
494542
## Drawbacks
495543

496544
One of the drawbacks of introducing stop signal to the container spec is that this introduces the scope of users misconfiguring the stop signal leading to unexpected behaviour such as the hanging pods as mentioned in the [Risks and Mitigations](#risks-and-mitigations) section.
@@ -508,7 +556,6 @@ lifecycle:
508556
command: ["/bin/sh", "-c", "kill -SIGUSR1 $(pidof my-app)"]
509557
```
510558

511-
512559
## Infrastructure Needed (Optional)
513560

514561
N/A

keps/sig-node/4960-container-stop-signals/kep.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ approvers:
1717

1818
status: implementable
1919
stage: alpha
20-
latest-milestone: "v1.33"
20+
latest-milestone: "v1.34"
2121
milestone:
2222
alpha: "v1.33"
2323
beta: ""
@@ -30,4 +30,6 @@ feature-gates:
3030
- kubelet
3131
disable-supported: true
3232

33-
metrics: []
33+
metrics:
34+
- kubelet_pod_stop_signals_count
35+
- kubelet_pod_termination_grace_period_exceeded_total

0 commit comments

Comments
 (0)