mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 10:20:51 +00:00
Merge pull request #99375 from ehashman/probe-kep-2238
Add Probe-level terminationGracePeriodSeconds
This commit is contained in:
commit
faa5c8ccd4
7
api/openapi-spec/swagger.json
generated
7
api/openapi-spec/swagger.json
generated
@ -8957,7 +8957,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"terminationGracePeriodSeconds": {
|
||||
"description": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.",
|
||||
"description": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.",
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
@ -9249,6 +9249,11 @@
|
||||
"$ref": "#/definitions/io.k8s.api.core.v1.TCPSocketAction",
|
||||
"description": "TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported"
|
||||
},
|
||||
"terminationGracePeriodSeconds": {
|
||||
"description": "Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.",
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"timeoutSeconds": {
|
||||
"description": "Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes",
|
||||
"format": "int32",
|
||||
|
@ -551,6 +551,20 @@ func dropDisabledFields(
|
||||
})
|
||||
}
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.ProbeTerminationGracePeriod) && !probeGracePeriodInUse(oldPodSpec) {
|
||||
// Set pod-level terminationGracePeriodSeconds to nil if the feature is disabled and it is not used
|
||||
VisitContainers(podSpec, AllContainers, func(c *api.Container, containerType ContainerType) bool {
|
||||
if c.LivenessProbe != nil {
|
||||
c.LivenessProbe.TerminationGracePeriodSeconds = nil
|
||||
}
|
||||
if c.StartupProbe != nil {
|
||||
c.StartupProbe.TerminationGracePeriodSeconds = nil
|
||||
}
|
||||
// cannot be set for readiness probes
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
dropDisabledFSGroupFields(podSpec, oldPodSpec)
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PodOverhead) && !overheadInUse(oldPodSpec) {
|
||||
@ -811,6 +825,27 @@ func subpathExprInUse(podSpec *api.PodSpec) bool {
|
||||
return inUse
|
||||
}
|
||||
|
||||
// probeGracePeriodInUse returns true if the pod spec is non-nil and has a probe that makes use
|
||||
// of the probe-level terminationGracePeriodSeconds feature
|
||||
func probeGracePeriodInUse(podSpec *api.PodSpec) bool {
|
||||
if podSpec == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var inUse bool
|
||||
VisitContainers(podSpec, AllContainers, func(c *api.Container, containerType ContainerType) bool {
|
||||
// cannot be set for readiness probes
|
||||
if (c.LivenessProbe != nil && c.LivenessProbe.TerminationGracePeriodSeconds != nil) ||
|
||||
(c.StartupProbe != nil && c.StartupProbe.TerminationGracePeriodSeconds != 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 {
|
||||
|
@ -1140,6 +1140,103 @@ func TestDropSubPathExpr(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropProbeGracePeriod(t *testing.T) {
|
||||
gracePeriod := int64(10)
|
||||
probe := api.Probe{TerminationGracePeriodSeconds: &gracePeriod}
|
||||
podWithProbeGracePeriod := func() *api.Pod {
|
||||
return &api.Pod{
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyNever,
|
||||
Containers: []api.Container{{Name: "container1", Image: "testimage", LivenessProbe: &probe, StartupProbe: &probe}},
|
||||
},
|
||||
}
|
||||
}
|
||||
podWithoutProbeGracePeriod := func() *api.Pod {
|
||||
p := podWithProbeGracePeriod()
|
||||
p.Spec.Containers[0].LivenessProbe.TerminationGracePeriodSeconds = nil
|
||||
p.Spec.Containers[0].StartupProbe.TerminationGracePeriodSeconds = nil
|
||||
return p
|
||||
}
|
||||
|
||||
podInfo := []struct {
|
||||
description string
|
||||
hasGracePeriod bool
|
||||
pod func() *api.Pod
|
||||
}{
|
||||
{
|
||||
description: "has probe-level terminationGracePeriod",
|
||||
hasGracePeriod: true,
|
||||
pod: podWithProbeGracePeriod,
|
||||
},
|
||||
{
|
||||
description: "does not have probe-level terminationGracePeriod",
|
||||
hasGracePeriod: false,
|
||||
pod: podWithoutProbeGracePeriod,
|
||||
},
|
||||
{
|
||||
description: "only has liveness probe-level terminationGracePeriod",
|
||||
hasGracePeriod: true,
|
||||
pod: func() *api.Pod {
|
||||
p := podWithProbeGracePeriod()
|
||||
p.Spec.Containers[0].StartupProbe.TerminationGracePeriodSeconds = nil
|
||||
return p
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "is nil",
|
||||
hasGracePeriod: false,
|
||||
pod: func() *api.Pod { return nil },
|
||||
},
|
||||
}
|
||||
|
||||
enabled := true
|
||||
for _, oldPodInfo := range podInfo {
|
||||
for _, newPodInfo := range podInfo {
|
||||
oldPodHasGracePeriod, oldPod := oldPodInfo.hasGracePeriod, oldPodInfo.pod()
|
||||
newPodHasGracePeriod, newPod := newPodInfo.hasGracePeriod, newPodInfo.pod()
|
||||
if newPod == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
t.Run(fmt.Sprintf("feature enabled=%v, old pod %v, new pod %v", enabled, oldPodInfo.description, newPodInfo.description), func(t *testing.T) {
|
||||
|
||||
var oldPodSpec *api.PodSpec
|
||||
if oldPod != nil {
|
||||
oldPodSpec = &oldPod.Spec
|
||||
}
|
||||
dropDisabledFields(&newPod.Spec, nil, oldPodSpec, nil)
|
||||
|
||||
// old pod should never be changed
|
||||
if !reflect.DeepEqual(oldPod, oldPodInfo.pod()) {
|
||||
t.Errorf("old pod changed: %v", diff.ObjectReflectDiff(oldPod, oldPodInfo.pod()))
|
||||
}
|
||||
|
||||
switch {
|
||||
case enabled || oldPodHasGracePeriod:
|
||||
// new pod should not be changed if the feature is enabled, or if the old pod had subpaths
|
||||
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
|
||||
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodInfo.pod()))
|
||||
}
|
||||
case newPodHasGracePeriod:
|
||||
// new pod should be changed
|
||||
if reflect.DeepEqual(newPod, newPodInfo.pod()) {
|
||||
t.Errorf("new pod was not changed")
|
||||
}
|
||||
// new pod should not have subpaths
|
||||
if !reflect.DeepEqual(newPod, podWithoutProbeGracePeriod()) {
|
||||
t.Errorf("new pod had probe-level terminationGracePeriod: %v", diff.ObjectReflectDiff(newPod, podWithoutProbeGracePeriod()))
|
||||
}
|
||||
default:
|
||||
// new pod should not need to be changed
|
||||
if !reflect.DeepEqual(newPod, newPodInfo.pod()) {
|
||||
t.Errorf("new pod changed: %v", diff.ObjectReflectDiff(newPod, newPodInfo.pod()))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helper creates a podStatus with list of PodIPs
|
||||
func makePodStatus(podIPs []api.PodIP) *api.PodStatus {
|
||||
return &api.PodStatus{
|
||||
|
@ -2020,6 +2020,17 @@ type Probe struct {
|
||||
// Minimum consecutive failures for the probe to be considered failed after having succeeded.
|
||||
// +optional
|
||||
FailureThreshold int32
|
||||
// Optional duration in seconds the pod needs to terminate gracefully upon probe failure.
|
||||
// The grace period is the duration in seconds after the processes running in the pod are sent
|
||||
// a termination signal and the time when the processes are forcibly halted with a kill signal.
|
||||
// Set this value longer than the expected cleanup time for your process.
|
||||
// If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this
|
||||
// value overrides the value provided by the pod spec.
|
||||
// Value must be non-negative integer. The value zero indicates stop immediately via
|
||||
// the kill signal (no opportunity to shut down).
|
||||
// This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
// +optional
|
||||
TerminationGracePeriodSeconds *int64
|
||||
}
|
||||
|
||||
// PullPolicy describes a policy for if/when to pull a container image
|
||||
@ -2719,7 +2730,8 @@ type PodSpec struct {
|
||||
// +optional
|
||||
RestartPolicy RestartPolicy
|
||||
// Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request.
|
||||
// Value must be non-negative integer. The value zero indicates delete immediately.
|
||||
// Value must be non-negative integer. The value zero indicates stop immediately via the kill
|
||||
// signal (no opportunity to shut down).
|
||||
// If this value is nil, the default grace period will be used instead.
|
||||
// The grace period is the duration in seconds after the processes running in the pod are sent
|
||||
// a termination signal and the time when the processes are forcibly halted with a kill signal.
|
||||
|
2
pkg/apis/core/v1/zz_generated.conversion.go
generated
2
pkg/apis/core/v1/zz_generated.conversion.go
generated
@ -6467,6 +6467,7 @@ func autoConvert_v1_Probe_To_core_Probe(in *v1.Probe, out *core.Probe, s convers
|
||||
out.PeriodSeconds = in.PeriodSeconds
|
||||
out.SuccessThreshold = in.SuccessThreshold
|
||||
out.FailureThreshold = in.FailureThreshold
|
||||
out.TerminationGracePeriodSeconds = (*int64)(unsafe.Pointer(in.TerminationGracePeriodSeconds))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -6484,6 +6485,7 @@ func autoConvert_core_Probe_To_v1_Probe(in *core.Probe, out *v1.Probe, s convers
|
||||
out.PeriodSeconds = in.PeriodSeconds
|
||||
out.SuccessThreshold = in.SuccessThreshold
|
||||
out.FailureThreshold = in.FailureThreshold
|
||||
out.TerminationGracePeriodSeconds = (*int64)(unsafe.Pointer(in.TerminationGracePeriodSeconds))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2859,6 +2859,11 @@ func validateContainers(containers []core.Container, isInitContainers bool, volu
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, idxPath.Child("lifecycle"))...)
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(ctr.LivenessProbe, idxPath.Child("livenessProbe"))...)
|
||||
// Readiness-specific validation
|
||||
if ctr.ReadinessProbe != nil && ctr.ReadinessProbe.TerminationGracePeriodSeconds != nil {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("readinessProbe", "terminationGracePeriodSeconds"), ctr.ReadinessProbe.TerminationGracePeriodSeconds, "must not be set for readinessProbes"))
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(ctr.StartupProbe, idxPath.Child("startupProbe"))...)
|
||||
// Liveness-specific validation
|
||||
if ctr.LivenessProbe != nil && ctr.LivenessProbe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("livenessProbe", "successThreshold"), ctr.LivenessProbe.SuccessThreshold, "must be 1"))
|
||||
|
@ -6284,6 +6284,20 @@ func TestValidateContainers(t *testing.T) {
|
||||
TerminationMessagePolicy: "File",
|
||||
},
|
||||
},
|
||||
"invalid readiness probe, terminationGracePeriodSeconds set.": {
|
||||
{
|
||||
Name: "life-123",
|
||||
Image: "image",
|
||||
ReadinessProbe: &core.Probe{
|
||||
Handler: core.Handler{
|
||||
TCPSocket: &core.TCPSocketAction{},
|
||||
},
|
||||
TerminationGracePeriodSeconds: utilpointer.Int64Ptr(10),
|
||||
},
|
||||
ImagePullPolicy: "IfNotPresent",
|
||||
TerminationMessagePolicy: "File",
|
||||
},
|
||||
},
|
||||
"invalid liveness probe, no tcp socket port.": {
|
||||
{
|
||||
Name: "life-123",
|
||||
|
5
pkg/apis/core/zz_generated.deepcopy.go
generated
5
pkg/apis/core/zz_generated.deepcopy.go
generated
@ -4192,6 +4192,11 @@ func (in *PreferredSchedulingTerm) DeepCopy() *PreferredSchedulingTerm {
|
||||
func (in *Probe) DeepCopyInto(out *Probe) {
|
||||
*out = *in
|
||||
in.Handler.DeepCopyInto(&out.Handler)
|
||||
if in.TerminationGracePeriodSeconds != nil {
|
||||
in, out := &in.TerminationGracePeriodSeconds, &out.TerminationGracePeriodSeconds
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -696,6 +696,12 @@ const (
|
||||
// Enables topology aware hints for EndpointSlices
|
||||
TopologyAwareHints featuregate.Feature = "TopologyAwareHints"
|
||||
|
||||
// owner: @ehashman
|
||||
// alpha: v1.21
|
||||
//
|
||||
// Allows user to override pod-level terminationGracePeriod for probes
|
||||
ProbeTerminationGracePeriod featuregate.Feature = "ProbeTerminationGracePeriod"
|
||||
|
||||
// owner: @ahg-g
|
||||
// alpha: v1.21
|
||||
//
|
||||
@ -850,6 +856,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
MixedProtocolLBService: {Default: false, PreRelease: featuregate.Alpha},
|
||||
VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PreferNominatedNode: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ProbeTerminationGracePeriod: {Default: false, PreRelease: featuregate.Alpha},
|
||||
RunAsGroup: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.22
|
||||
PodDeletionCost: {Default: false, PreRelease: featuregate.Alpha},
|
||||
TopologyAwareHints: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
@ -227,7 +227,7 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb
|
||||
msg, handlerErr := m.runner.Run(kubeContainerID, pod, container, container.Lifecycle.PostStart)
|
||||
if handlerErr != nil {
|
||||
m.recordContainerEvent(pod, container, kubeContainerID.ID, v1.EventTypeWarning, events.FailedPostStartHook, msg)
|
||||
if err := m.killContainer(pod, kubeContainerID, container.Name, "FailedPostStartHook", nil); err != nil {
|
||||
if err := m.killContainer(pod, kubeContainerID, container.Name, "FailedPostStartHook", reasonFailedPostStartHook, nil); err != nil {
|
||||
klog.ErrorS(fmt.Errorf("%s: %v", ErrPostStartHook, handlerErr), "Failed to kill container", "pod", klog.KObj(pod),
|
||||
"podUID", pod.UID, "containerName", container.Name, "containerID", kubeContainerID.String())
|
||||
}
|
||||
@ -596,7 +596,7 @@ func (m *kubeGenericRuntimeManager) restoreSpecsFromContainerLabels(containerID
|
||||
// killContainer kills a container through the following steps:
|
||||
// * Run the pre-stop lifecycle hooks (if applicable).
|
||||
// * Stop the container.
|
||||
func (m *kubeGenericRuntimeManager) killContainer(pod *v1.Pod, containerID kubecontainer.ContainerID, containerName string, message string, gracePeriodOverride *int64) error {
|
||||
func (m *kubeGenericRuntimeManager) killContainer(pod *v1.Pod, containerID kubecontainer.ContainerID, containerName string, message string, reason containerKillReason, gracePeriodOverride *int64) error {
|
||||
var containerSpec *v1.Container
|
||||
if pod != nil {
|
||||
if containerSpec = kubecontainer.GetContainerSpec(pod, containerName); containerSpec == nil {
|
||||
@ -619,6 +619,19 @@ func (m *kubeGenericRuntimeManager) killContainer(pod *v1.Pod, containerID kubec
|
||||
gracePeriod = *pod.DeletionGracePeriodSeconds
|
||||
case pod.Spec.TerminationGracePeriodSeconds != nil:
|
||||
gracePeriod = *pod.Spec.TerminationGracePeriodSeconds
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ProbeTerminationGracePeriod) {
|
||||
switch reason {
|
||||
case reasonStartupProbe:
|
||||
if containerSpec.StartupProbe != nil && containerSpec.StartupProbe.TerminationGracePeriodSeconds != nil {
|
||||
gracePeriod = *containerSpec.StartupProbe.TerminationGracePeriodSeconds
|
||||
}
|
||||
case reasonLivenessProbe:
|
||||
if containerSpec.LivenessProbe != nil && containerSpec.LivenessProbe.TerminationGracePeriodSeconds != nil {
|
||||
gracePeriod = *containerSpec.LivenessProbe.TerminationGracePeriodSeconds
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(message) == 0 {
|
||||
@ -672,7 +685,7 @@ func (m *kubeGenericRuntimeManager) killContainersWithSyncResult(pod *v1.Pod, ru
|
||||
defer wg.Done()
|
||||
|
||||
killContainerResult := kubecontainer.NewSyncResult(kubecontainer.KillContainer, container.Name)
|
||||
if err := m.killContainer(pod, container.ID, container.Name, "", gracePeriodOverride); err != nil {
|
||||
if err := m.killContainer(pod, container.ID, container.Name, "", reasonUnknown, gracePeriodOverride); err != nil {
|
||||
killContainerResult.Fail(kubecontainer.ErrKillContainer, err.Error())
|
||||
klog.ErrorS(err, "Kill container failed", "pod", klog.KObj(pod), "podUID", pod.UID,
|
||||
"containerName", container.Name, "containerID", container.ID)
|
||||
|
@ -120,7 +120,7 @@ func TestKillContainer(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := m.killContainer(test.pod, test.containerID, test.containerName, test.reason, &test.gracePeriodOverride)
|
||||
err := m.killContainer(test.pod, test.containerID, test.containerName, test.reason, "", &test.gracePeriodOverride)
|
||||
if test.succeed != (err == nil) {
|
||||
t.Errorf("%s: expected %v, got %v (%v)", test.caseName, test.succeed, (err == nil), err)
|
||||
}
|
||||
@ -290,7 +290,7 @@ func TestLifeCycleHook(t *testing.T) {
|
||||
// Configured and works as expected
|
||||
t.Run("PreStop-CMDExec", func(t *testing.T) {
|
||||
testPod.Spec.Containers[0].Lifecycle = cmdLifeCycle
|
||||
m.killContainer(testPod, cID, "foo", "testKill", &gracePeriod)
|
||||
m.killContainer(testPod, cID, "foo", "testKill", "", &gracePeriod)
|
||||
if fakeRunner.Cmd[0] != cmdLifeCycle.PreStop.Exec.Command[0] {
|
||||
t.Errorf("CMD Prestop hook was not invoked")
|
||||
}
|
||||
@ -300,7 +300,7 @@ func TestLifeCycleHook(t *testing.T) {
|
||||
t.Run("PreStop-HTTPGet", func(t *testing.T) {
|
||||
defer func() { fakeHTTP.url = "" }()
|
||||
testPod.Spec.Containers[0].Lifecycle = httpLifeCycle
|
||||
m.killContainer(testPod, cID, "foo", "testKill", &gracePeriod)
|
||||
m.killContainer(testPod, cID, "foo", "testKill", "", &gracePeriod)
|
||||
|
||||
if !strings.Contains(fakeHTTP.url, httpLifeCycle.PreStop.HTTPGet.Host) {
|
||||
t.Errorf("HTTP Prestop hook was not invoked")
|
||||
@ -314,7 +314,7 @@ func TestLifeCycleHook(t *testing.T) {
|
||||
testPod.DeletionGracePeriodSeconds = &gracePeriodLocal
|
||||
testPod.Spec.TerminationGracePeriodSeconds = &gracePeriodLocal
|
||||
|
||||
m.killContainer(testPod, cID, "foo", "testKill", &gracePeriodLocal)
|
||||
m.killContainer(testPod, cID, "foo", "testKill", "", &gracePeriodLocal)
|
||||
|
||||
if strings.Contains(fakeHTTP.url, httpLifeCycle.PreStop.HTTPGet.Host) {
|
||||
t.Errorf("HTTP Should not execute when gracePeriod is 0")
|
||||
|
@ -137,7 +137,7 @@ func (cgc *containerGC) removeOldestN(containers []containerGCInfo, toRemove int
|
||||
ID: containers[i].id,
|
||||
}
|
||||
message := "Container is in unknown state, try killing it before removal"
|
||||
if err := cgc.manager.killContainer(nil, id, containers[i].name, message, nil); err != nil {
|
||||
if err := cgc.manager.killContainer(nil, id, containers[i].name, message, reasonUnknown, nil); err != nil {
|
||||
klog.Errorf("Failed to stop container %q: %v", containers[i].id, err)
|
||||
continue
|
||||
}
|
||||
|
@ -403,6 +403,16 @@ func (m *kubeGenericRuntimeManager) GetPods(all bool) ([]*kubecontainer.Pod, err
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// containerKillReason explains what killed a given container
|
||||
type containerKillReason string
|
||||
|
||||
const (
|
||||
reasonStartupProbe containerKillReason = "StartupProbe"
|
||||
reasonLivenessProbe containerKillReason = "LivenessProbe"
|
||||
reasonFailedPostStartHook containerKillReason = "FailedPostStartHook"
|
||||
reasonUnknown containerKillReason = "Unknown"
|
||||
)
|
||||
|
||||
// containerToKillInfo contains necessary information to kill a container.
|
||||
type containerToKillInfo struct {
|
||||
// The spec of the container.
|
||||
@ -411,6 +421,9 @@ type containerToKillInfo struct {
|
||||
name string
|
||||
// The message indicates why the container will be killed.
|
||||
message string
|
||||
// The reason is a clearer source of info on why a container will be killed
|
||||
// TODO: replace message with reason?
|
||||
reason containerKillReason
|
||||
}
|
||||
|
||||
// podActions keeps information what to do for a pod.
|
||||
@ -582,6 +595,7 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku
|
||||
container: next,
|
||||
message: fmt.Sprintf("Init container is in %q state, try killing it before restart",
|
||||
initLastStatus.State),
|
||||
reason: reasonUnknown,
|
||||
}
|
||||
}
|
||||
changes.NextInitContainerToStart = next
|
||||
@ -623,6 +637,7 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku
|
||||
container: &pod.Spec.Containers[idx],
|
||||
message: fmt.Sprintf("Container is in %q state, try killing it before restart",
|
||||
containerStatus.State),
|
||||
reason: reasonUnknown,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -630,6 +645,7 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku
|
||||
}
|
||||
// The container is running, but kill the container if any of the following condition is met.
|
||||
var message string
|
||||
var reason containerKillReason
|
||||
restart := shouldRestartOnFailure(pod)
|
||||
if _, _, changed := containerChanged(&container, containerStatus); changed {
|
||||
message = fmt.Sprintf("Container %s definition changed", container.Name)
|
||||
@ -639,9 +655,11 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku
|
||||
} else if liveness, found := m.livenessManager.Get(containerStatus.ID); found && liveness == proberesults.Failure {
|
||||
// If the container failed the liveness probe, we should kill it.
|
||||
message = fmt.Sprintf("Container %s failed liveness probe", container.Name)
|
||||
reason = reasonLivenessProbe
|
||||
} else if startup, found := m.startupManager.Get(containerStatus.ID); found && startup == proberesults.Failure {
|
||||
// If the container failed the startup probe, we should kill it.
|
||||
message = fmt.Sprintf("Container %s failed startup probe", container.Name)
|
||||
reason = reasonStartupProbe
|
||||
} else {
|
||||
// Keep the container.
|
||||
keepCount++
|
||||
@ -660,6 +678,7 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku
|
||||
name: containerStatus.Name,
|
||||
container: &pod.Spec.Containers[idx],
|
||||
message: message,
|
||||
reason: reason,
|
||||
}
|
||||
klog.V(2).InfoS("Message for Container of pod", "containerName", container.Name, "containerStatusID", containerStatus.ID, "pod", klog.KObj(pod), "containerMessage", message)
|
||||
}
|
||||
@ -720,7 +739,7 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, podStatus *kubecontaine
|
||||
klog.V(3).InfoS("Killing unwanted container for pod", "containerName", containerInfo.name, "containerID", containerID, "pod", klog.KObj(pod))
|
||||
killContainerResult := kubecontainer.NewSyncResult(kubecontainer.KillContainer, containerInfo.name)
|
||||
result.AddSyncResult(killContainerResult)
|
||||
if err := m.killContainer(pod, containerID, containerInfo.name, containerInfo.message, nil); err != nil {
|
||||
if err := m.killContainer(pod, containerID, containerInfo.name, containerInfo.message, containerInfo.reason, nil); err != nil {
|
||||
killContainerResult.Fail(kubecontainer.ErrKillContainer, err.Error())
|
||||
klog.ErrorS(err, "killContainer for pod failed", "containerName", containerInfo.name, "containerID", containerID, "pod", klog.KObj(pod))
|
||||
return
|
||||
|
@ -1002,9 +1002,10 @@ func getKillMapWithInitContainers(pod *v1.Pod, status *kubecontainer.PodStatus,
|
||||
|
||||
func verifyActions(t *testing.T, expected, actual *podActions, desc string) {
|
||||
if actual.ContainersToKill != nil {
|
||||
// Clear the message field since we don't need to verify the message.
|
||||
// Clear the message and reason fields since we don't need to verify them.
|
||||
for k, info := range actual.ContainersToKill {
|
||||
info.message = ""
|
||||
info.reason = ""
|
||||
actual.ContainersToKill[k] = info
|
||||
}
|
||||
}
|
||||
|
1788
staging/src/k8s.io/api/core/v1/generated.pb.go
generated
1788
staging/src/k8s.io/api/core/v1/generated.pb.go
generated
File diff suppressed because it is too large
Load Diff
@ -3421,7 +3421,8 @@ message PodSpec {
|
||||
optional string restartPolicy = 3;
|
||||
|
||||
// Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request.
|
||||
// Value must be non-negative integer. The value zero indicates delete immediately.
|
||||
// Value must be non-negative integer. The value zero indicates stop immediately via
|
||||
// the kill signal (no opportunity to shut down).
|
||||
// If this value is nil, the default grace period will be used instead.
|
||||
// The grace period is the duration in seconds after the processes running in the pod are sent
|
||||
// a termination signal and the time when the processes are forcibly halted with a kill signal.
|
||||
@ -3883,6 +3884,18 @@ message Probe {
|
||||
// Defaults to 3. Minimum value is 1.
|
||||
// +optional
|
||||
optional int32 failureThreshold = 6;
|
||||
|
||||
// Optional duration in seconds the pod needs to terminate gracefully upon probe failure.
|
||||
// The grace period is the duration in seconds after the processes running in the pod are sent
|
||||
// a termination signal and the time when the processes are forcibly halted with a kill signal.
|
||||
// Set this value longer than the expected cleanup time for your process.
|
||||
// If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this
|
||||
// value overrides the value provided by the pod spec.
|
||||
// Value must be non-negative integer. The value zero indicates stop immediately via
|
||||
// the kill signal (no opportunity to shut down).
|
||||
// This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
// +optional
|
||||
optional int64 terminationGracePeriodSeconds = 7;
|
||||
}
|
||||
|
||||
// Represents a projected volume source
|
||||
|
@ -2117,6 +2117,17 @@ type Probe struct {
|
||||
// Defaults to 3. Minimum value is 1.
|
||||
// +optional
|
||||
FailureThreshold int32 `json:"failureThreshold,omitempty" protobuf:"varint,6,opt,name=failureThreshold"`
|
||||
// Optional duration in seconds the pod needs to terminate gracefully upon probe failure.
|
||||
// The grace period is the duration in seconds after the processes running in the pod are sent
|
||||
// a termination signal and the time when the processes are forcibly halted with a kill signal.
|
||||
// Set this value longer than the expected cleanup time for your process.
|
||||
// If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this
|
||||
// value overrides the value provided by the pod spec.
|
||||
// Value must be non-negative integer. The value zero indicates stop immediately via
|
||||
// the kill signal (no opportunity to shut down).
|
||||
// This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.
|
||||
// +optional
|
||||
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty" protobuf:"varint,7,opt,name=terminationGracePeriodSeconds"`
|
||||
}
|
||||
|
||||
// PullPolicy describes a policy for if/when to pull a container image
|
||||
@ -2968,7 +2979,8 @@ type PodSpec struct {
|
||||
// +optional
|
||||
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" protobuf:"bytes,3,opt,name=restartPolicy,casttype=RestartPolicy"`
|
||||
// Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request.
|
||||
// Value must be non-negative integer. The value zero indicates delete immediately.
|
||||
// Value must be non-negative integer. The value zero indicates stop immediately via
|
||||
// the kill signal (no opportunity to shut down).
|
||||
// If this value is nil, the default grace period will be used instead.
|
||||
// The grace period is the duration in seconds after the processes running in the pod are sent
|
||||
// a termination signal and the time when the processes are forcibly halted with a kill signal.
|
||||
|
@ -1627,7 +1627,7 @@ var map_PodSpec = map[string]string{
|
||||
"containers": "List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated.",
|
||||
"ephemeralContainers": "List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. This field is alpha-level and is only honored by servers that enable the EphemeralContainers feature.",
|
||||
"restartPolicy": "Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy",
|
||||
"terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.",
|
||||
"terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds.",
|
||||
"activeDeadlineSeconds": "Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer.",
|
||||
"dnsPolicy": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.",
|
||||
"nodeSelector": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/",
|
||||
@ -1783,6 +1783,7 @@ var map_Probe = map[string]string{
|
||||
"periodSeconds": "How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1.",
|
||||
"successThreshold": "Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.",
|
||||
"failureThreshold": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1.",
|
||||
"terminationGracePeriodSeconds": "Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is an alpha field and requires enabling ProbeTerminationGracePeriod feature gate.",
|
||||
}
|
||||
|
||||
func (Probe) SwaggerDoc() map[string]string {
|
||||
|
@ -4190,6 +4190,11 @@ func (in *PreferredSchedulingTerm) DeepCopy() *PreferredSchedulingTerm {
|
||||
func (in *Probe) DeepCopyInto(out *Probe) {
|
||||
*out = *in
|
||||
in.Handler.DeepCopyInto(&out.Handler)
|
||||
if in.TerminationGracePeriodSeconds != nil {
|
||||
in, out := &in.TerminationGracePeriodSeconds, &out.TerminationGracePeriodSeconds
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.pb
vendored
BIN
staging/src/k8s.io/api/testdata/HEAD/batch.v1.Job.pb
vendored
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -148,7 +148,8 @@
|
||||
"timeoutSeconds": 1563658126,
|
||||
"periodSeconds": -1771047449,
|
||||
"successThreshold": -1280107919,
|
||||
"failureThreshold": -54954325
|
||||
"failureThreshold": -54954325,
|
||||
"terminationGracePeriodSeconds": 8559948711650432497
|
||||
},
|
||||
"readinessProbe": {
|
||||
"exec": {
|
||||
@ -158,138 +159,141 @@
|
||||
},
|
||||
"httpGet": {
|
||||
"path": "53",
|
||||
"port": "54",
|
||||
"host": "55",
|
||||
"scheme": "OŖ樅尷",
|
||||
"port": -1395989138,
|
||||
"host": "54",
|
||||
"scheme": "斎AO6ĴC浔Ű壝ž",
|
||||
"httpHeaders": [
|
||||
{
|
||||
"name": "56",
|
||||
"value": "57"
|
||||
"name": "55",
|
||||
"value": "56"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tcpSocket": {
|
||||
"port": 2136826132,
|
||||
"host": "58"
|
||||
"port": 180803110,
|
||||
"host": "57"
|
||||
},
|
||||
"initialDelaySeconds": 819364842,
|
||||
"timeoutSeconds": 933484239,
|
||||
"periodSeconds": -983896210,
|
||||
"successThreshold": 552512122,
|
||||
"failureThreshold": -833209928
|
||||
"initialDelaySeconds": -2014231015,
|
||||
"timeoutSeconds": 1488277679,
|
||||
"periodSeconds": -1679907303,
|
||||
"successThreshold": -1051545416,
|
||||
"failureThreshold": 1305372099,
|
||||
"terminationGracePeriodSeconds": -1220632347188845753
|
||||
},
|
||||
"startupProbe": {
|
||||
"exec": {
|
||||
"command": [
|
||||
"59"
|
||||
"58"
|
||||
]
|
||||
},
|
||||
"httpGet": {
|
||||
"path": "60",
|
||||
"port": 180803110,
|
||||
"host": "61",
|
||||
"scheme": "ņ錕?øēƺ",
|
||||
"path": "59",
|
||||
"port": 1229400382,
|
||||
"host": "60",
|
||||
"scheme": "3ƆìQ喞艋涽託仭",
|
||||
"httpHeaders": [
|
||||
{
|
||||
"name": "62",
|
||||
"value": "63"
|
||||
"name": "61",
|
||||
"value": "62"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tcpSocket": {
|
||||
"port": "64",
|
||||
"host": "65"
|
||||
"port": "63",
|
||||
"host": "64"
|
||||
},
|
||||
"initialDelaySeconds": -816398166,
|
||||
"timeoutSeconds": 1229400382,
|
||||
"periodSeconds": -1583208879,
|
||||
"successThreshold": 1088264954,
|
||||
"failureThreshold": 13573196
|
||||
"initialDelaySeconds": 2076966617,
|
||||
"timeoutSeconds": 202362764,
|
||||
"periodSeconds": -560446848,
|
||||
"successThreshold": -1098992377,
|
||||
"failureThreshold": -1009864962,
|
||||
"terminationGracePeriodSeconds": 2618170937706035036
|
||||
},
|
||||
"lifecycle": {
|
||||
"postStart": {
|
||||
"exec": {
|
||||
"command": [
|
||||
"66"
|
||||
"65"
|
||||
]
|
||||
},
|
||||
"httpGet": {
|
||||
"path": "67",
|
||||
"port": -1293912096,
|
||||
"host": "68",
|
||||
"scheme": "託仭",
|
||||
"path": "66",
|
||||
"port": -503563033,
|
||||
"host": "67",
|
||||
"scheme": "趕ã/鈱$-议}ȧ外ĺ稥氹Ç|¶鎚¡ ",
|
||||
"httpHeaders": [
|
||||
{
|
||||
"name": "69",
|
||||
"value": "70"
|
||||
"name": "68",
|
||||
"value": "69"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tcpSocket": {
|
||||
"port": "71",
|
||||
"host": "72"
|
||||
"port": "70",
|
||||
"host": "71"
|
||||
}
|
||||
},
|
||||
"preStop": {
|
||||
"exec": {
|
||||
"command": [
|
||||
"73"
|
||||
"72"
|
||||
]
|
||||
},
|
||||
"httpGet": {
|
||||
"path": "74",
|
||||
"port": "75",
|
||||
"host": "76",
|
||||
"scheme": "鴜Ł%Ũ",
|
||||
"path": "73",
|
||||
"port": 991085362,
|
||||
"host": "74",
|
||||
"scheme": "磩窮秳ķ蟒苾h^樅燴壩卄",
|
||||
"httpHeaders": [
|
||||
{
|
||||
"name": "77",
|
||||
"value": "78"
|
||||
"name": "75",
|
||||
"value": "76"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tcpSocket": {
|
||||
"port": "79",
|
||||
"host": "80"
|
||||
"port": -479087071,
|
||||
"host": "77"
|
||||
}
|
||||
}
|
||||
},
|
||||
"terminationMessagePath": "81",
|
||||
"terminationMessagePolicy": "Ņ£",
|
||||
"terminationMessagePath": "78",
|
||||
"terminationMessagePolicy": "?讦ĭÐ",
|
||||
"imagePullPolicy": "/C龷ȪÆl殛瓷雼浢Ü礽绅",
|
||||
"securityContext": {
|
||||
"capabilities": {
|
||||
"add": [
|
||||
"2Ō¾\\ĒP鄸靇杧ž"
|
||||
"\"ŵw^Ü郀叚Fi皬择,Q"
|
||||
],
|
||||
"drop": [
|
||||
"娲瘹ɭȊɚɎ(dɅ囥糷磩窮秳ķ蟒苾h^"
|
||||
"ȸ{+"
|
||||
]
|
||||
},
|
||||
"privileged": false,
|
||||
"seLinuxOptions": {
|
||||
"user": "82",
|
||||
"role": "83",
|
||||
"type": "84",
|
||||
"level": "85"
|
||||
"user": "79",
|
||||
"role": "80",
|
||||
"type": "81",
|
||||
"level": "82"
|
||||
},
|
||||
"windowsOptions": {
|
||||
"gmsaCredentialSpecName": "86",
|
||||
"gmsaCredentialSpec": "87",
|
||||
"runAsUserName": "88"
|
||||
"gmsaCredentialSpecName": "83",
|
||||
"gmsaCredentialSpec": "84",
|
||||
"runAsUserName": "85"
|
||||
},
|
||||
"runAsUser": 4491726672505793472,
|
||||
"runAsGroup": -5441351197948631872,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": -1466062763730980131,
|
||||
"runAsGroup": 8360795821384820753,
|
||||
"runAsNonRoot": false,
|
||||
"readOnlyRootFilesystem": true,
|
||||
"allowPrivilegeEscalation": true,
|
||||
"procMount": "ĭÐl恕ɍȇ廄裭4懙",
|
||||
"procMount": "Ƙq/",
|
||||
"seccompProfile": {
|
||||
"type": "嵒ƫS捕ɷD¡轫n",
|
||||
"localhostProfile": "89"
|
||||
"type": " u衲\u003c¿燥",
|
||||
"localhostProfile": "86"
|
||||
}
|
||||
},
|
||||
"stdin": true,
|
||||
"targetContainerName": "90"
|
||||
"tty": true,
|
||||
"targetContainerName": "87"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
@ -32,37 +32,38 @@ ephemeralContainers:
|
||||
name: "28"
|
||||
optional: false
|
||||
image: "20"
|
||||
imagePullPolicy: /C龷ȪÆl殛瓷雼浢Ü礽绅
|
||||
lifecycle:
|
||||
postStart:
|
||||
exec:
|
||||
command:
|
||||
- "66"
|
||||
- "65"
|
||||
httpGet:
|
||||
host: "68"
|
||||
host: "67"
|
||||
httpHeaders:
|
||||
- name: "69"
|
||||
value: "70"
|
||||
path: "67"
|
||||
port: -1293912096
|
||||
scheme: 託仭
|
||||
- name: "68"
|
||||
value: "69"
|
||||
path: "66"
|
||||
port: -503563033
|
||||
scheme: '趕ã/鈱$-议}ȧ外ĺ稥氹Ç|¶鎚¡ '
|
||||
tcpSocket:
|
||||
host: "72"
|
||||
port: "71"
|
||||
host: "71"
|
||||
port: "70"
|
||||
preStop:
|
||||
exec:
|
||||
command:
|
||||
- "73"
|
||||
- "72"
|
||||
httpGet:
|
||||
host: "76"
|
||||
host: "74"
|
||||
httpHeaders:
|
||||
- name: "77"
|
||||
value: "78"
|
||||
path: "74"
|
||||
port: "75"
|
||||
scheme: 鴜Ł%Ũ
|
||||
- name: "75"
|
||||
value: "76"
|
||||
path: "73"
|
||||
port: 991085362
|
||||
scheme: 磩窮秳ķ蟒苾h^樅燴壩卄
|
||||
tcpSocket:
|
||||
host: "80"
|
||||
port: "79"
|
||||
host: "77"
|
||||
port: -479087071
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
@ -82,6 +83,7 @@ ephemeralContainers:
|
||||
tcpSocket:
|
||||
host: "51"
|
||||
port: 1366345526
|
||||
terminationGracePeriodSeconds: 8559948711650432497
|
||||
timeoutSeconds: 1563658126
|
||||
name: "19"
|
||||
ports:
|
||||
@ -93,22 +95,23 @@ ephemeralContainers:
|
||||
exec:
|
||||
command:
|
||||
- "52"
|
||||
failureThreshold: -833209928
|
||||
failureThreshold: 1305372099
|
||||
httpGet:
|
||||
host: "55"
|
||||
host: "54"
|
||||
httpHeaders:
|
||||
- name: "56"
|
||||
value: "57"
|
||||
- name: "55"
|
||||
value: "56"
|
||||
path: "53"
|
||||
port: "54"
|
||||
scheme: OŖ樅尷
|
||||
initialDelaySeconds: 819364842
|
||||
periodSeconds: -983896210
|
||||
successThreshold: 552512122
|
||||
port: -1395989138
|
||||
scheme: 斎AO6ĴC浔Ű壝ž
|
||||
initialDelaySeconds: -2014231015
|
||||
periodSeconds: -1679907303
|
||||
successThreshold: -1051545416
|
||||
tcpSocket:
|
||||
host: "58"
|
||||
port: 2136826132
|
||||
timeoutSeconds: 933484239
|
||||
host: "57"
|
||||
port: 180803110
|
||||
terminationGracePeriodSeconds: -1220632347188845753
|
||||
timeoutSeconds: 1488277679
|
||||
resources:
|
||||
limits:
|
||||
V夸eɑeʤ: "420"
|
||||
@ -118,51 +121,52 @@ ephemeralContainers:
|
||||
allowPrivilegeEscalation: true
|
||||
capabilities:
|
||||
add:
|
||||
- 2Ō¾\ĒP鄸靇杧ž
|
||||
- '"ŵw^Ü郀叚Fi皬择,Q'
|
||||
drop:
|
||||
- 娲瘹ɭȊɚɎ(dɅ囥糷磩窮秳ķ蟒苾h^
|
||||
- ȸ{+
|
||||
privileged: false
|
||||
procMount: ĭÐl恕ɍȇ廄裭4懙
|
||||
procMount: Ƙq/
|
||||
readOnlyRootFilesystem: true
|
||||
runAsGroup: -5441351197948631872
|
||||
runAsNonRoot: true
|
||||
runAsUser: 4491726672505793472
|
||||
runAsGroup: 8360795821384820753
|
||||
runAsNonRoot: false
|
||||
runAsUser: -1466062763730980131
|
||||
seLinuxOptions:
|
||||
level: "85"
|
||||
role: "83"
|
||||
type: "84"
|
||||
user: "82"
|
||||
level: "82"
|
||||
role: "80"
|
||||
type: "81"
|
||||
user: "79"
|
||||
seccompProfile:
|
||||
localhostProfile: "89"
|
||||
type: 嵒ƫS捕ɷD¡轫n
|
||||
localhostProfile: "86"
|
||||
type: ' u衲<¿燥'
|
||||
windowsOptions:
|
||||
gmsaCredentialSpec: "87"
|
||||
gmsaCredentialSpecName: "86"
|
||||
runAsUserName: "88"
|
||||
gmsaCredentialSpec: "84"
|
||||
gmsaCredentialSpecName: "83"
|
||||
runAsUserName: "85"
|
||||
startupProbe:
|
||||
exec:
|
||||
command:
|
||||
- "59"
|
||||
failureThreshold: 13573196
|
||||
- "58"
|
||||
failureThreshold: -1009864962
|
||||
httpGet:
|
||||
host: "61"
|
||||
host: "60"
|
||||
httpHeaders:
|
||||
- name: "62"
|
||||
value: "63"
|
||||
path: "60"
|
||||
port: 180803110
|
||||
scheme: ņ錕?øēƺ
|
||||
initialDelaySeconds: -816398166
|
||||
periodSeconds: -1583208879
|
||||
successThreshold: 1088264954
|
||||
- name: "61"
|
||||
value: "62"
|
||||
path: "59"
|
||||
port: 1229400382
|
||||
scheme: 3ƆìQ喞艋涽託仭
|
||||
initialDelaySeconds: 2076966617
|
||||
periodSeconds: -560446848
|
||||
successThreshold: -1098992377
|
||||
tcpSocket:
|
||||
host: "65"
|
||||
port: "64"
|
||||
timeoutSeconds: 1229400382
|
||||
stdin: true
|
||||
targetContainerName: "90"
|
||||
terminationMessagePath: "81"
|
||||
terminationMessagePolicy: ң
|
||||
host: "64"
|
||||
port: "63"
|
||||
terminationGracePeriodSeconds: 2618170937706035036
|
||||
timeoutSeconds: 202362764
|
||||
targetContainerName: "87"
|
||||
terminationMessagePath: "78"
|
||||
terminationMessagePolicy: ?讦ĭÐ
|
||||
tty: true
|
||||
volumeDevices:
|
||||
- devicePath: "44"
|
||||
name: "43"
|
||||
|
File diff suppressed because it is too large
Load Diff
BIN
staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.pb
vendored
BIN
staging/src/k8s.io/api/testdata/HEAD/core.v1.Pod.pb
vendored
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -27,6 +27,7 @@ type ProbeApplyConfiguration struct {
|
||||
PeriodSeconds *int32 `json:"periodSeconds,omitempty"`
|
||||
SuccessThreshold *int32 `json:"successThreshold,omitempty"`
|
||||
FailureThreshold *int32 `json:"failureThreshold,omitempty"`
|
||||
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
|
||||
}
|
||||
|
||||
// ProbeApplyConfiguration constructs an declarative configuration of the Probe type for use with
|
||||
@ -98,3 +99,11 @@ func (b *ProbeApplyConfiguration) WithFailureThreshold(value int32) *ProbeApplyC
|
||||
b.FailureThreshold = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithTerminationGracePeriodSeconds sets the TerminationGracePeriodSeconds field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the TerminationGracePeriodSeconds field is set to the value of the last call.
|
||||
func (b *ProbeApplyConfiguration) WithTerminationGracePeriodSeconds(value int64) *ProbeApplyConfiguration {
|
||||
b.TerminationGracePeriodSeconds = &value
|
||||
return b
|
||||
}
|
||||
|
@ -5514,6 +5514,9 @@ var schemaYAML = typed.YAMLObject(`types:
|
||||
- name: tcpSocket
|
||||
type:
|
||||
namedType: io.k8s.api.core.v1.TCPSocketAction
|
||||
- name: terminationGracePeriodSeconds
|
||||
type:
|
||||
scalar: numeric
|
||||
- name: timeoutSeconds
|
||||
type:
|
||||
scalar: numeric
|
||||
|
@ -420,6 +420,67 @@ var _ = SIGDescribe("Probing container", func() {
|
||||
framework.Failf("Pod became ready in %v, more than 5s after startupProbe succeeded. It means that the delay readiness probes were not initiated immediately after startup finished.", readyIn)
|
||||
}
|
||||
})
|
||||
|
||||
/*
|
||||
Release: v1.21
|
||||
Testname: Set terminationGracePeriodSeconds for livenessProbe
|
||||
Description: A pod with a long terminationGracePeriod is created with a shorter livenessProbe-level terminationGracePeriodSeconds. We confirm the shorter termination period is used.
|
||||
*/
|
||||
ginkgo.It("should override timeoutGracePeriodSeconds when LivenessProbe field is set [Feature:ProbeTerminationGracePeriod]", func() {
|
||||
pod := e2epod.NewAgnhostPod(f.Namespace.Name, "liveness-override-"+string(uuid.NewUUID()), nil, nil, nil, "/bin/sh", "-c", "sleep 1000")
|
||||
longGracePeriod := int64(500)
|
||||
pod.Spec.TerminationGracePeriodSeconds = &longGracePeriod
|
||||
|
||||
// probe will fail since pod has no http endpoints
|
||||
shortGracePeriod := int64(5)
|
||||
pod.Spec.Containers[0].LivenessProbe = &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
HTTPGet: &v1.HTTPGetAction{
|
||||
Path: "/healthz",
|
||||
Port: intstr.FromInt(8080),
|
||||
},
|
||||
},
|
||||
InitialDelaySeconds: 10,
|
||||
FailureThreshold: 1,
|
||||
TerminationGracePeriodSeconds: &shortGracePeriod,
|
||||
}
|
||||
|
||||
// 10s delay + 10s period + 5s grace period = 25s < 30s << pod-level timeout 500
|
||||
RunLivenessTest(f, pod, 1, time.Second*30)
|
||||
})
|
||||
|
||||
/*
|
||||
Release: v1.21
|
||||
Testname: Set terminationGracePeriodSeconds for startupProbe
|
||||
Description: A pod with a long terminationGracePeriod is created with a shorter startupProbe-level terminationGracePeriodSeconds. We confirm the shorter termination period is used.
|
||||
*/
|
||||
ginkgo.It("should override timeoutGracePeriodSeconds when StartupProbe field is set [Feature:ProbeTerminationGracePeriod]", func() {
|
||||
pod := e2epod.NewAgnhostPod(f.Namespace.Name, "startup-override-"+string(uuid.NewUUID()), nil, nil, nil, "/bin/sh", "-c", "sleep 1000")
|
||||
longGracePeriod := int64(500)
|
||||
pod.Spec.TerminationGracePeriodSeconds = &longGracePeriod
|
||||
|
||||
// startup probe will fail since pod will sleep for 1000s before becoming ready
|
||||
shortGracePeriod := int64(5)
|
||||
pod.Spec.Containers[0].StartupProbe = &v1.Probe{
|
||||
Handler: execHandler([]string{"/bin/cat", "/tmp/startup"}),
|
||||
InitialDelaySeconds: 10,
|
||||
FailureThreshold: 1,
|
||||
TerminationGracePeriodSeconds: &shortGracePeriod,
|
||||
}
|
||||
// liveness probe always succeeds
|
||||
pod.Spec.Containers[0].LivenessProbe = &v1.Probe{
|
||||
Handler: v1.Handler{
|
||||
Exec: &v1.ExecAction{
|
||||
Command: []string{"/bin/true"},
|
||||
},
|
||||
},
|
||||
InitialDelaySeconds: 15,
|
||||
FailureThreshold: 1,
|
||||
}
|
||||
|
||||
// 10s delay + 10s period + 5s grace period = 25s < 30s << pod-level timeout 500
|
||||
RunLivenessTest(f, pod, 1, time.Second*30)
|
||||
})
|
||||
})
|
||||
|
||||
// GetContainerStartedTime returns the time when the given container started and error if any
|
||||
|
Loading…
Reference in New Issue
Block a user