1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- /*
- Copyright 2016 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package kubelet
- import (
- "fmt"
- "time"
- "k8s.io/kubernetes/pkg/api"
- "k8s.io/kubernetes/pkg/client/record"
- "k8s.io/kubernetes/pkg/kubelet/lifecycle"
- "k8s.io/kubernetes/pkg/kubelet/status"
- "k8s.io/kubernetes/pkg/util/clock"
- )
- const (
- reason = "DeadlineExceeded"
- message = "Pod was active on the node longer than the specified deadline"
- )
- // activeDeadlineHandler knows how to enforce active deadlines on pods.
- type activeDeadlineHandler struct {
- // the clock to use for deadline enforcement
- clock clock.Clock
- // the provider of pod status
- podStatusProvider status.PodStatusProvider
- // the recorder to dispatch events when we identify a pod has exceeded active deadline
- recorder record.EventRecorder
- }
- // newActiveDeadlineHandler returns an active deadline handler that can enforce pod active deadline
- func newActiveDeadlineHandler(
- podStatusProvider status.PodStatusProvider,
- recorder record.EventRecorder,
- clock clock.Clock,
- ) (*activeDeadlineHandler, error) {
- // check for all required fields
- if clock == nil || podStatusProvider == nil || recorder == nil {
- return nil, fmt.Errorf("Required arguments must not be nil: %v, %v, %v", clock, podStatusProvider, recorder)
- }
- return &activeDeadlineHandler{
- clock: clock,
- podStatusProvider: podStatusProvider,
- recorder: recorder,
- }, nil
- }
- // ShouldSync returns true if the pod is past its active deadline.
- func (m *activeDeadlineHandler) ShouldSync(pod *api.Pod) bool {
- return m.pastActiveDeadline(pod)
- }
- // ShouldEvict returns true if the pod is past its active deadline.
- // It dispatches an event that the pod should be evicted if it is past its deadline.
- func (m *activeDeadlineHandler) ShouldEvict(pod *api.Pod) lifecycle.ShouldEvictResponse {
- if !m.pastActiveDeadline(pod) {
- return lifecycle.ShouldEvictResponse{Evict: false}
- }
- m.recorder.Eventf(pod, api.EventTypeNormal, reason, message)
- return lifecycle.ShouldEvictResponse{Evict: true, Reason: reason, Message: message}
- }
- // pastActiveDeadline returns true if the pod has been active for more than its ActiveDeadlineSeconds
- func (m *activeDeadlineHandler) pastActiveDeadline(pod *api.Pod) bool {
- // no active deadline was specified
- if pod.Spec.ActiveDeadlineSeconds == nil {
- return false
- }
- // get the latest status to determine if it was started
- podStatus, ok := m.podStatusProvider.GetPodStatus(pod.UID)
- if !ok {
- podStatus = pod.Status
- }
- // we have no start time so just return
- if podStatus.StartTime.IsZero() {
- return false
- }
- // determine if the deadline was exceeded
- start := podStatus.StartTime.Time
- duration := m.clock.Since(start)
- allowedDuration := time.Duration(*pod.Spec.ActiveDeadlineSeconds) * time.Second
- return duration >= allowedDuration
- }
|