mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
rebase: update kubernetes to v1.20.0
updated kubernetes packages to latest release. Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
4abe128bd8
commit
83559144b1
71
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/BUILD
generated
vendored
71
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/BUILD
generated
vendored
@ -1,71 +0,0 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"admission_failure_handler_stub.go",
|
||||
"doc.go",
|
||||
"handlers.go",
|
||||
"interfaces.go",
|
||||
"predicate.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/lifecycle",
|
||||
deps = [
|
||||
"//pkg/apis/core/v1/helper:go_default_library",
|
||||
"//pkg/kubelet/container:go_default_library",
|
||||
"//pkg/kubelet/types:go_default_library",
|
||||
"//pkg/kubelet/util/format:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/helper:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/nodeaffinity:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/nodename:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/nodeports:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/noderesources:go_default_library",
|
||||
"//pkg/scheduler/nodeinfo:go_default_library",
|
||||
"//pkg/security/apparmor:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/utils/io:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"handlers_test.go",
|
||||
"predicate_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core/v1/helper:go_default_library",
|
||||
"//pkg/kubelet/container:go_default_library",
|
||||
"//pkg/kubelet/util/format:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/nodename:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/nodeports:go_default_library",
|
||||
"//pkg/scheduler/nodeinfo:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
35
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go
generated
vendored
35
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go
generated
vendored
@ -1,35 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 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 lifecycle
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
// AdmissionFailureHandlerStub is an AdmissionFailureHandler that does not perform any handling of admission failure.
|
||||
// It simply passes the failure on.
|
||||
type AdmissionFailureHandlerStub struct{}
|
||||
|
||||
var _ AdmissionFailureHandler = &AdmissionFailureHandlerStub{}
|
||||
|
||||
func NewAdmissionFailureHandlerStub() *AdmissionFailureHandlerStub {
|
||||
return &AdmissionFailureHandlerStub{}
|
||||
}
|
||||
|
||||
func (n *AdmissionFailureHandlerStub) HandleAdmissionFailure(admitPod *v1.Pod, failureReasons []PredicateFailureReason) ([]PredicateFailureReason, error) {
|
||||
return failureReasons, nil
|
||||
}
|
19
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go
generated
vendored
19
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 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.
|
||||
*/
|
||||
|
||||
// Handlers for pod lifecycle events and interfaces to integrate
|
||||
// with kubelet admission, synchronization, and eviction of pods.
|
||||
package lifecycle // import "k8s.io/kubernetes/pkg/kubelet/lifecycle"
|
307
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go
generated
vendored
307
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go
generated
vendored
@ -1,307 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 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 lifecycle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/klog"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
"k8s.io/kubernetes/pkg/security/apparmor"
|
||||
utilio "k8s.io/utils/io"
|
||||
)
|
||||
|
||||
const (
|
||||
maxRespBodyLength = 10 * 1 << 10 // 10KB
|
||||
)
|
||||
|
||||
type HandlerRunner struct {
|
||||
httpGetter kubetypes.HTTPGetter
|
||||
commandRunner kubecontainer.ContainerCommandRunner
|
||||
containerManager podStatusProvider
|
||||
}
|
||||
|
||||
type podStatusProvider interface {
|
||||
GetPodStatus(uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error)
|
||||
}
|
||||
|
||||
func NewHandlerRunner(httpGetter kubetypes.HTTPGetter, commandRunner kubecontainer.ContainerCommandRunner, containerManager podStatusProvider) kubecontainer.HandlerRunner {
|
||||
return &HandlerRunner{
|
||||
httpGetter: httpGetter,
|
||||
commandRunner: commandRunner,
|
||||
containerManager: containerManager,
|
||||
}
|
||||
}
|
||||
|
||||
func (hr *HandlerRunner) Run(containerID kubecontainer.ContainerID, pod *v1.Pod, container *v1.Container, handler *v1.Handler) (string, error) {
|
||||
switch {
|
||||
case handler.Exec != nil:
|
||||
var msg string
|
||||
// TODO(tallclair): Pass a proper timeout value.
|
||||
output, err := hr.commandRunner.RunInContainer(containerID, handler.Exec.Command, 0)
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("Exec lifecycle hook (%v) for Container %q in Pod %q failed - error: %v, message: %q", handler.Exec.Command, container.Name, format.Pod(pod), err, string(output))
|
||||
klog.V(1).Infof(msg)
|
||||
}
|
||||
return msg, err
|
||||
case handler.HTTPGet != nil:
|
||||
msg, err := hr.runHTTPHandler(pod, container, handler)
|
||||
if err != nil {
|
||||
msg = fmt.Sprintf("Http lifecycle hook (%s) for Container %q in Pod %q failed - error: %v, message: %q", handler.HTTPGet.Path, container.Name, format.Pod(pod), err, msg)
|
||||
klog.V(1).Infof(msg)
|
||||
}
|
||||
return msg, err
|
||||
default:
|
||||
err := fmt.Errorf("invalid handler: %v", handler)
|
||||
msg := fmt.Sprintf("Cannot run handler: %v", err)
|
||||
klog.Errorf(msg)
|
||||
return msg, err
|
||||
}
|
||||
}
|
||||
|
||||
// resolvePort attempts to turn an IntOrString port reference into a concrete port number.
|
||||
// If portReference has an int value, it is treated as a literal, and simply returns that value.
|
||||
// If portReference is a string, an attempt is first made to parse it as an integer. If that fails,
|
||||
// an attempt is made to find a port with the same name in the container spec.
|
||||
// If a port with the same name is found, it's ContainerPort value is returned. If no matching
|
||||
// port is found, an error is returned.
|
||||
func resolvePort(portReference intstr.IntOrString, container *v1.Container) (int, error) {
|
||||
if portReference.Type == intstr.Int {
|
||||
return portReference.IntValue(), nil
|
||||
}
|
||||
portName := portReference.StrVal
|
||||
port, err := strconv.Atoi(portName)
|
||||
if err == nil {
|
||||
return port, nil
|
||||
}
|
||||
for _, portSpec := range container.Ports {
|
||||
if portSpec.Name == portName {
|
||||
return int(portSpec.ContainerPort), nil
|
||||
}
|
||||
}
|
||||
return -1, fmt.Errorf("couldn't find port: %v in %v", portReference, container)
|
||||
}
|
||||
|
||||
func (hr *HandlerRunner) runHTTPHandler(pod *v1.Pod, container *v1.Container, handler *v1.Handler) (string, error) {
|
||||
host := handler.HTTPGet.Host
|
||||
if len(host) == 0 {
|
||||
status, err := hr.containerManager.GetPodStatus(pod.UID, pod.Name, pod.Namespace)
|
||||
if err != nil {
|
||||
klog.Errorf("Unable to get pod info, event handlers may be invalid.")
|
||||
return "", err
|
||||
}
|
||||
if len(status.IPs) == 0 {
|
||||
return "", fmt.Errorf("failed to find networking container: %v", status)
|
||||
}
|
||||
host = status.IPs[0]
|
||||
}
|
||||
var port int
|
||||
if handler.HTTPGet.Port.Type == intstr.String && len(handler.HTTPGet.Port.StrVal) == 0 {
|
||||
port = 80
|
||||
} else {
|
||||
var err error
|
||||
port, err = resolvePort(handler.HTTPGet.Port, container)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
url := fmt.Sprintf("http://%s/%s", net.JoinHostPort(host, strconv.Itoa(port)), handler.HTTPGet.Path)
|
||||
resp, err := hr.httpGetter.Get(url)
|
||||
return getHttpRespBody(resp), err
|
||||
}
|
||||
|
||||
func getHttpRespBody(resp *http.Response) string {
|
||||
if resp == nil {
|
||||
return ""
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bytes, err := utilio.ReadAtMost(resp.Body, maxRespBodyLength)
|
||||
if err == nil || err == utilio.ErrLimitReached {
|
||||
return string(bytes)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func NewAppArmorAdmitHandler(validator apparmor.Validator) PodAdmitHandler {
|
||||
return &appArmorAdmitHandler{
|
||||
Validator: validator,
|
||||
}
|
||||
}
|
||||
|
||||
type appArmorAdmitHandler struct {
|
||||
apparmor.Validator
|
||||
}
|
||||
|
||||
func (a *appArmorAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
// If the pod is already running or terminated, no need to recheck AppArmor.
|
||||
if attrs.Pod.Status.Phase != v1.PodPending {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
err := a.Validate(attrs.Pod)
|
||||
if err == nil {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "AppArmor",
|
||||
Message: fmt.Sprintf("Cannot enforce AppArmor: %v", err),
|
||||
}
|
||||
}
|
||||
|
||||
func NewNoNewPrivsAdmitHandler(runtime kubecontainer.Runtime) PodAdmitHandler {
|
||||
return &noNewPrivsAdmitHandler{
|
||||
Runtime: runtime,
|
||||
}
|
||||
}
|
||||
|
||||
type noNewPrivsAdmitHandler struct {
|
||||
kubecontainer.Runtime
|
||||
}
|
||||
|
||||
func (a *noNewPrivsAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
// If the pod is already running or terminated, no need to recheck NoNewPrivs.
|
||||
if attrs.Pod.Status.Phase != v1.PodPending {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// If the containers in a pod do not require no-new-privs, admit it.
|
||||
if !noNewPrivsRequired(attrs.Pod) {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Always admit runtimes except docker.
|
||||
if a.Runtime.Type() != kubetypes.DockerContainerRuntime {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Make sure docker api version is valid.
|
||||
rversion, err := a.Runtime.APIVersion()
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "NoNewPrivs",
|
||||
Message: fmt.Sprintf("Cannot enforce NoNewPrivs: %v", err),
|
||||
}
|
||||
}
|
||||
v, err := rversion.Compare("1.23.0")
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "NoNewPrivs",
|
||||
Message: fmt.Sprintf("Cannot enforce NoNewPrivs: %v", err),
|
||||
}
|
||||
}
|
||||
// If the version is less than 1.23 it will return -1 above.
|
||||
if v == -1 {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "NoNewPrivs",
|
||||
Message: fmt.Sprintf("Cannot enforce NoNewPrivs: docker runtime API version %q must be greater than or equal to 1.23", rversion.String()),
|
||||
}
|
||||
}
|
||||
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
func noNewPrivsRequired(pod *v1.Pod) bool {
|
||||
// Iterate over pod containers and check if we added no-new-privs.
|
||||
for _, c := range pod.Spec.Containers {
|
||||
if c.SecurityContext != nil && c.SecurityContext.AllowPrivilegeEscalation != nil && !*c.SecurityContext.AllowPrivilegeEscalation {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func NewProcMountAdmitHandler(runtime kubecontainer.Runtime) PodAdmitHandler {
|
||||
return &procMountAdmitHandler{
|
||||
Runtime: runtime,
|
||||
}
|
||||
}
|
||||
|
||||
type procMountAdmitHandler struct {
|
||||
kubecontainer.Runtime
|
||||
}
|
||||
|
||||
func (a *procMountAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
// If the pod is already running or terminated, no need to recheck NoNewPrivs.
|
||||
if attrs.Pod.Status.Phase != v1.PodPending {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// If the containers in a pod only need the default ProcMountType, admit it.
|
||||
if procMountIsDefault(attrs.Pod) {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Always admit runtimes except docker.
|
||||
if a.Runtime.Type() != kubetypes.DockerContainerRuntime {
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
// Make sure docker api version is valid.
|
||||
// Merged in https://github.com/moby/moby/pull/36644
|
||||
rversion, err := a.Runtime.APIVersion()
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "ProcMount",
|
||||
Message: fmt.Sprintf("Cannot enforce ProcMount: %v", err),
|
||||
}
|
||||
}
|
||||
v, err := rversion.Compare("1.38.0")
|
||||
if err != nil {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "ProcMount",
|
||||
Message: fmt.Sprintf("Cannot enforce ProcMount: %v", err),
|
||||
}
|
||||
}
|
||||
// If the version is less than 1.38 it will return -1 above.
|
||||
if v == -1 {
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "ProcMount",
|
||||
Message: fmt.Sprintf("Cannot enforce ProcMount: docker runtime API version %q must be greater than or equal to 1.38", rversion.String()),
|
||||
}
|
||||
}
|
||||
|
||||
return PodAdmitResult{Admit: true}
|
||||
}
|
||||
|
||||
func procMountIsDefault(pod *v1.Pod) bool {
|
||||
// Iterate over pod containers and check if we are using the DefaultProcMountType
|
||||
// for all containers.
|
||||
for _, c := range pod.Spec.Containers {
|
||||
if c.SecurityContext != nil {
|
||||
if c.SecurityContext.ProcMount != nil && *c.SecurityContext.ProcMount != v1.DefaultProcMount {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
122
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go
generated
vendored
122
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go
generated
vendored
@ -1,122 +0,0 @@
|
||||
/*
|
||||
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 lifecycle
|
||||
|
||||
import "k8s.io/api/core/v1"
|
||||
|
||||
// PodAdmitAttributes is the context for a pod admission decision.
|
||||
// The member fields of this struct should never be mutated.
|
||||
type PodAdmitAttributes struct {
|
||||
// the pod to evaluate for admission
|
||||
Pod *v1.Pod
|
||||
// all pods bound to the kubelet excluding the pod being evaluated
|
||||
OtherPods []*v1.Pod
|
||||
}
|
||||
|
||||
// PodAdmitResult provides the result of a pod admission decision.
|
||||
type PodAdmitResult struct {
|
||||
// if true, the pod should be admitted.
|
||||
Admit bool
|
||||
// a brief single-word reason why the pod could not be admitted.
|
||||
Reason string
|
||||
// a brief message explaining why the pod could not be admitted.
|
||||
Message string
|
||||
}
|
||||
|
||||
// PodAdmitHandler is notified during pod admission.
|
||||
type PodAdmitHandler interface {
|
||||
// Admit evaluates if a pod can be admitted.
|
||||
Admit(attrs *PodAdmitAttributes) PodAdmitResult
|
||||
}
|
||||
|
||||
// PodAdmitTarget maintains a list of handlers to invoke.
|
||||
type PodAdmitTarget interface {
|
||||
// AddPodAdmitHandler adds the specified handler.
|
||||
AddPodAdmitHandler(a PodAdmitHandler)
|
||||
}
|
||||
|
||||
// PodSyncLoopHandler is invoked during each sync loop iteration.
|
||||
type PodSyncLoopHandler interface {
|
||||
// ShouldSync returns true if the pod needs to be synced.
|
||||
// This operation must return immediately as its called for each pod.
|
||||
// The provided pod should never be modified.
|
||||
ShouldSync(pod *v1.Pod) bool
|
||||
}
|
||||
|
||||
// PodSyncLoopTarget maintains a list of handlers to pod sync loop.
|
||||
type PodSyncLoopTarget interface {
|
||||
// AddPodSyncLoopHandler adds the specified handler.
|
||||
AddPodSyncLoopHandler(a PodSyncLoopHandler)
|
||||
}
|
||||
|
||||
// ShouldEvictResponse provides the result of a should evict request.
|
||||
type ShouldEvictResponse struct {
|
||||
// if true, the pod should be evicted.
|
||||
Evict bool
|
||||
// a brief CamelCase reason why the pod should be evicted.
|
||||
Reason string
|
||||
// a brief message why the pod should be evicted.
|
||||
Message string
|
||||
}
|
||||
|
||||
// PodSyncHandler is invoked during each sync pod operation.
|
||||
type PodSyncHandler interface {
|
||||
// ShouldEvict is invoked during each sync pod operation to determine
|
||||
// if the pod should be evicted from the kubelet. If so, the pod status
|
||||
// is updated to mark its phase as failed with the provided reason and message,
|
||||
// and the pod is immediately killed.
|
||||
// This operation must return immediately as its called for each sync pod.
|
||||
// The provided pod should never be modified.
|
||||
ShouldEvict(pod *v1.Pod) ShouldEvictResponse
|
||||
}
|
||||
|
||||
// PodSyncTarget maintains a list of handlers to pod sync.
|
||||
type PodSyncTarget interface {
|
||||
// AddPodSyncHandler adds the specified handler
|
||||
AddPodSyncHandler(a PodSyncHandler)
|
||||
}
|
||||
|
||||
// PodLifecycleTarget groups a set of lifecycle interfaces for convenience.
|
||||
type PodLifecycleTarget interface {
|
||||
PodAdmitTarget
|
||||
PodSyncLoopTarget
|
||||
PodSyncTarget
|
||||
}
|
||||
|
||||
// PodAdmitHandlers maintains a list of handlers to pod admission.
|
||||
type PodAdmitHandlers []PodAdmitHandler
|
||||
|
||||
// AddPodAdmitHandler adds the specified observer.
|
||||
func (handlers *PodAdmitHandlers) AddPodAdmitHandler(a PodAdmitHandler) {
|
||||
*handlers = append(*handlers, a)
|
||||
}
|
||||
|
||||
// PodSyncLoopHandlers maintains a list of handlers to pod sync loop.
|
||||
type PodSyncLoopHandlers []PodSyncLoopHandler
|
||||
|
||||
// AddPodSyncLoopHandler adds the specified observer.
|
||||
func (handlers *PodSyncLoopHandlers) AddPodSyncLoopHandler(a PodSyncLoopHandler) {
|
||||
*handlers = append(*handlers, a)
|
||||
}
|
||||
|
||||
// PodSyncHandlers maintains a list of handlers to pod sync.
|
||||
type PodSyncHandlers []PodSyncHandler
|
||||
|
||||
// AddPodSyncHandler adds the specified handler.
|
||||
func (handlers *PodSyncHandlers) AddPodSyncHandler(a PodSyncHandler) {
|
||||
*handlers = append(*handlers, a)
|
||||
}
|
249
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go
generated
vendored
249
vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go
generated
vendored
@ -1,249 +0,0 @@
|
||||
/*
|
||||
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 lifecycle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/klog"
|
||||
pluginhelper "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||
)
|
||||
|
||||
type getNodeAnyWayFuncType func() (*v1.Node, error)
|
||||
|
||||
type pluginResourceUpdateFuncType func(*schedulernodeinfo.NodeInfo, *PodAdmitAttributes) error
|
||||
|
||||
// AdmissionFailureHandler is an interface which defines how to deal with a failure to admit a pod.
|
||||
// This allows for the graceful handling of pod admission failure.
|
||||
type AdmissionFailureHandler interface {
|
||||
HandleAdmissionFailure(admitPod *v1.Pod, failureReasons []PredicateFailureReason) ([]PredicateFailureReason, error)
|
||||
}
|
||||
|
||||
type predicateAdmitHandler struct {
|
||||
getNodeAnyWayFunc getNodeAnyWayFuncType
|
||||
pluginResourceUpdateFunc pluginResourceUpdateFuncType
|
||||
admissionFailureHandler AdmissionFailureHandler
|
||||
}
|
||||
|
||||
var _ PodAdmitHandler = &predicateAdmitHandler{}
|
||||
|
||||
func NewPredicateAdmitHandler(getNodeAnyWayFunc getNodeAnyWayFuncType, admissionFailureHandler AdmissionFailureHandler, pluginResourceUpdateFunc pluginResourceUpdateFuncType) *predicateAdmitHandler {
|
||||
return &predicateAdmitHandler{
|
||||
getNodeAnyWayFunc,
|
||||
pluginResourceUpdateFunc,
|
||||
admissionFailureHandler,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *predicateAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
|
||||
node, err := w.getNodeAnyWayFunc()
|
||||
if err != nil {
|
||||
klog.Errorf("Cannot get Node info: %v", err)
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "InvalidNodeInfo",
|
||||
Message: "Kubelet cannot get node info.",
|
||||
}
|
||||
}
|
||||
admitPod := attrs.Pod
|
||||
pods := attrs.OtherPods
|
||||
nodeInfo := schedulernodeinfo.NewNodeInfo(pods...)
|
||||
nodeInfo.SetNode(node)
|
||||
// ensure the node has enough plugin resources for that required in pods
|
||||
if err = w.pluginResourceUpdateFunc(nodeInfo, attrs); err != nil {
|
||||
message := fmt.Sprintf("Update plugin resources failed due to %v, which is unexpected.", err)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: false,
|
||||
Reason: "UnexpectedAdmissionError",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the requests of the extended resources that are missing in the
|
||||
// node info. This is required to support cluster-level resources, which
|
||||
// are extended resources unknown to nodes.
|
||||
//
|
||||
// Caveat: If a pod was manually bound to a node (e.g., static pod) where a
|
||||
// node-level extended resource it requires is not found, then kubelet will
|
||||
// not fail admission while it should. This issue will be addressed with
|
||||
// the Resource Class API in the future.
|
||||
podWithoutMissingExtendedResources := removeMissingExtendedResources(admitPod, nodeInfo)
|
||||
|
||||
reasons, err := GeneralPredicates(podWithoutMissingExtendedResources, nodeInfo)
|
||||
fit := len(reasons) == 0 && err == nil
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("GeneralPredicates failed due to %v, which is unexpected.", err)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: "UnexpectedAdmissionError",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
if !fit {
|
||||
reasons, err = w.admissionFailureHandler.HandleAdmissionFailure(admitPod, reasons)
|
||||
fit = len(reasons) == 0 && err == nil
|
||||
if err != nil {
|
||||
message := fmt.Sprintf("Unexpected error while attempting to recover from admission failure: %v", err)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: "UnexpectedAdmissionError",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
}
|
||||
if !fit {
|
||||
var reason string
|
||||
var message string
|
||||
if len(reasons) == 0 {
|
||||
message = fmt.Sprint("GeneralPredicates failed due to unknown reason, which is unexpected.")
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: "UnknownReason",
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
// If there are failed predicates, we only return the first one as a reason.
|
||||
r := reasons[0]
|
||||
switch re := r.(type) {
|
||||
case *PredicateFailureError:
|
||||
reason = re.PredicateName
|
||||
message = re.Error()
|
||||
klog.V(2).Infof("Predicate failed on Pod: %v, for reason: %v", format.Pod(admitPod), message)
|
||||
case *InsufficientResourceError:
|
||||
reason = fmt.Sprintf("OutOf%s", re.ResourceName)
|
||||
message = re.Error()
|
||||
klog.V(2).Infof("Predicate failed on Pod: %v, for reason: %v", format.Pod(admitPod), message)
|
||||
default:
|
||||
reason = "UnexpectedPredicateFailureType"
|
||||
message = fmt.Sprintf("GeneralPredicates failed due to %v, which is unexpected.", r)
|
||||
klog.Warningf("Failed to admit pod %v - %s", format.Pod(admitPod), message)
|
||||
}
|
||||
return PodAdmitResult{
|
||||
Admit: fit,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
return PodAdmitResult{
|
||||
Admit: true,
|
||||
}
|
||||
}
|
||||
|
||||
func removeMissingExtendedResources(pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) *v1.Pod {
|
||||
podCopy := pod.DeepCopy()
|
||||
for i, c := range pod.Spec.Containers {
|
||||
// We only handle requests in Requests but not Limits because the
|
||||
// PodFitsResources predicate, to which the result pod will be passed,
|
||||
// does not use Limits.
|
||||
podCopy.Spec.Containers[i].Resources.Requests = make(v1.ResourceList)
|
||||
for rName, rQuant := range c.Resources.Requests {
|
||||
if v1helper.IsExtendedResourceName(rName) {
|
||||
if _, found := nodeInfo.AllocatableResource().ScalarResources[rName]; !found {
|
||||
continue
|
||||
}
|
||||
}
|
||||
podCopy.Spec.Containers[i].Resources.Requests[rName] = rQuant
|
||||
}
|
||||
}
|
||||
return podCopy
|
||||
}
|
||||
|
||||
// InsufficientResourceError is an error type that indicates what kind of resource limit is
|
||||
// hit and caused the unfitting failure.
|
||||
type InsufficientResourceError struct {
|
||||
ResourceName v1.ResourceName
|
||||
Requested int64
|
||||
Used int64
|
||||
Capacity int64
|
||||
}
|
||||
|
||||
func (e *InsufficientResourceError) Error() string {
|
||||
return fmt.Sprintf("Node didn't have enough resource: %s, requested: %d, used: %d, capacity: %d",
|
||||
e.ResourceName, e.Requested, e.Used, e.Capacity)
|
||||
}
|
||||
|
||||
// PredicateFailureReason interface represents the failure reason of a predicate.
|
||||
type PredicateFailureReason interface {
|
||||
GetReason() string
|
||||
}
|
||||
|
||||
// GetReason returns the reason of the InsufficientResourceError.
|
||||
func (e *InsufficientResourceError) GetReason() string {
|
||||
return fmt.Sprintf("Insufficient %v", e.ResourceName)
|
||||
}
|
||||
|
||||
// GetInsufficientAmount returns the amount of the insufficient resource of the error.
|
||||
func (e *InsufficientResourceError) GetInsufficientAmount() int64 {
|
||||
return e.Requested - (e.Capacity - e.Used)
|
||||
}
|
||||
|
||||
// PredicateFailureError describes a failure error of predicate.
|
||||
type PredicateFailureError struct {
|
||||
PredicateName string
|
||||
PredicateDesc string
|
||||
}
|
||||
|
||||
func (e *PredicateFailureError) Error() string {
|
||||
return fmt.Sprintf("Predicate %s failed", e.PredicateName)
|
||||
}
|
||||
|
||||
// GetReason returns the reason of the PredicateFailureError.
|
||||
func (e *PredicateFailureError) GetReason() string {
|
||||
return e.PredicateDesc
|
||||
}
|
||||
|
||||
// GeneralPredicates checks a group of predicates that the kubelet cares about.
|
||||
func GeneralPredicates(pod *v1.Pod, nodeInfo *schedulernodeinfo.NodeInfo) ([]PredicateFailureReason, error) {
|
||||
if nodeInfo.Node() == nil {
|
||||
return nil, fmt.Errorf("node not found")
|
||||
}
|
||||
|
||||
var reasons []PredicateFailureReason
|
||||
for _, r := range noderesources.Fits(pod, nodeInfo, nil) {
|
||||
reasons = append(reasons, &InsufficientResourceError{
|
||||
ResourceName: r.ResourceName,
|
||||
Requested: r.Requested,
|
||||
Used: r.Used,
|
||||
Capacity: r.Capacity,
|
||||
})
|
||||
}
|
||||
|
||||
if !pluginhelper.PodMatchesNodeSelectorAndAffinityTerms(pod, nodeInfo.Node()) {
|
||||
reasons = append(reasons, &PredicateFailureError{nodeaffinity.Name, nodeaffinity.ErrReason})
|
||||
}
|
||||
if !nodename.Fits(pod, nodeInfo) {
|
||||
reasons = append(reasons, &PredicateFailureError{nodename.Name, nodename.ErrReason})
|
||||
}
|
||||
if !nodeports.Fits(pod, nodeInfo) {
|
||||
reasons = append(reasons, &PredicateFailureError{nodeports.Name, nodeports.ErrReason})
|
||||
}
|
||||
|
||||
return reasons, nil
|
||||
}
|
Reference in New Issue
Block a user