mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
rebase: update kubernetes to v1.21.2
Updated kubernetes packages to latest release. resizefs package has been included into k8s.io/mount-utils package. updated code to use the same. Updates: #1968 Signed-off-by: Rakshith R <rar@redhat.com>
This commit is contained in:
141
vendor/k8s.io/kubernetes/pkg/controller/BUILD
generated
vendored
141
vendor/k8s.io/kubernetes/pkg/controller/BUILD
generated
vendored
@ -1,141 +0,0 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client_builder_dynamic.go",
|
||||
"controller_ref_manager.go",
|
||||
"controller_utils.go",
|
||||
"doc.go",
|
||||
"lookup_cache.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/controller",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api/v1/pod:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/apis/core/validation:go_default_library",
|
||||
"//pkg/util/hash:go_default_library",
|
||||
"//pkg/util/taints:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/authentication/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/rand:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/strategicpatch:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/transport:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/retry:go_default_library",
|
||||
"//staging/src/k8s.io/controller-manager/pkg/clientbuilder:go_default_library",
|
||||
"//vendor/github.com/golang/groupcache/lru:go_default_library",
|
||||
"//vendor/golang.org/x/oauth2:go_default_library",
|
||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||
"//vendor/k8s.io/utils/integer:go_default_library",
|
||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"controller_ref_manager_test.go",
|
||||
"controller_utils_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/controller/testutil:go_default_library",
|
||||
"//pkg/securitycontext:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/tools/record:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/util/testing:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/controller/apis/config:all-srcs",
|
||||
"//pkg/controller/bootstrap:all-srcs",
|
||||
"//pkg/controller/certificates:all-srcs",
|
||||
"//pkg/controller/clusterroleaggregation:all-srcs",
|
||||
"//pkg/controller/cronjob:all-srcs",
|
||||
"//pkg/controller/daemon:all-srcs",
|
||||
"//pkg/controller/deployment:all-srcs",
|
||||
"//pkg/controller/disruption:all-srcs",
|
||||
"//pkg/controller/endpoint:all-srcs",
|
||||
"//pkg/controller/endpointslice:all-srcs",
|
||||
"//pkg/controller/endpointslicemirroring:all-srcs",
|
||||
"//pkg/controller/garbagecollector:all-srcs",
|
||||
"//pkg/controller/history:all-srcs",
|
||||
"//pkg/controller/job:all-srcs",
|
||||
"//pkg/controller/namespace:all-srcs",
|
||||
"//pkg/controller/nodeipam:all-srcs",
|
||||
"//pkg/controller/nodelifecycle:all-srcs",
|
||||
"//pkg/controller/podautoscaler:all-srcs",
|
||||
"//pkg/controller/podgc:all-srcs",
|
||||
"//pkg/controller/replicaset:all-srcs",
|
||||
"//pkg/controller/replication:all-srcs",
|
||||
"//pkg/controller/resourcequota:all-srcs",
|
||||
"//pkg/controller/serviceaccount:all-srcs",
|
||||
"//pkg/controller/statefulset:all-srcs",
|
||||
"//pkg/controller/storageversiongc:all-srcs",
|
||||
"//pkg/controller/testutil:all-srcs",
|
||||
"//pkg/controller/ttl:all-srcs",
|
||||
"//pkg/controller/ttlafterfinished:all-srcs",
|
||||
"//pkg/controller/util/endpoint:all-srcs",
|
||||
"//pkg/controller/util/node:all-srcs",
|
||||
"//pkg/controller/volume/attachdetach:all-srcs",
|
||||
"//pkg/controller/volume/common:all-srcs",
|
||||
"//pkg/controller/volume/ephemeral:all-srcs",
|
||||
"//pkg/controller/volume/events:all-srcs",
|
||||
"//pkg/controller/volume/expand:all-srcs",
|
||||
"//pkg/controller/volume/persistentvolume:all-srcs",
|
||||
"//pkg/controller/volume/protectionutil:all-srcs",
|
||||
"//pkg/controller/volume/pvcprotection:all-srcs",
|
||||
"//pkg/controller/volume/pvprotection:all-srcs",
|
||||
"//pkg/controller/volume/scheduling:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
1
vendor/k8s.io/kubernetes/pkg/controller/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/controller/OWNERS
generated
vendored
@ -8,6 +8,7 @@ approvers:
|
||||
- cheftako
|
||||
- sig-apps-approvers
|
||||
reviewers:
|
||||
- andrewsykim
|
||||
- deads2k
|
||||
- cheftako
|
||||
- sig-apps-reviewers
|
||||
|
219
vendor/k8s.io/kubernetes/pkg/controller/client_builder_dynamic.go
generated
vendored
219
vendor/k8s.io/kubernetes/pkg/controller/client_builder_dynamic.go
generated
vendored
@ -1,219 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
v1authenticationapi "k8s.io/api/authentication/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/clock"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/transport"
|
||||
"k8s.io/controller-manager/pkg/clientbuilder"
|
||||
"k8s.io/klog/v2"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
var (
|
||||
// defaultExpirationSeconds defines the duration of a TokenRequest in seconds.
|
||||
defaultExpirationSeconds = int64(3600)
|
||||
// defaultLeewayPercent defines the percentage of expiration left before the client trigger a token rotation.
|
||||
// range[0, 100]
|
||||
defaultLeewayPercent = 20
|
||||
)
|
||||
|
||||
type DynamicControllerClientBuilder struct {
|
||||
// ClientConfig is a skeleton config to clone and use as the basis for each controller client
|
||||
ClientConfig *restclient.Config
|
||||
|
||||
// CoreClient is used to provision service accounts if needed and watch for their associated tokens
|
||||
// to construct a controller client
|
||||
CoreClient v1core.CoreV1Interface
|
||||
|
||||
// Namespace is the namespace used to host the service accounts that will back the
|
||||
// controllers. It must be highly privileged namespace which normal users cannot inspect.
|
||||
Namespace string
|
||||
|
||||
// roundTripperFuncMap is a cache stores the corresponding roundtripper func for each
|
||||
// service account
|
||||
roundTripperFuncMap map[string]func(http.RoundTripper) http.RoundTripper
|
||||
|
||||
// expirationSeconds defines the token expiration seconds
|
||||
expirationSeconds int64
|
||||
|
||||
// leewayPercent defines the percentage of expiration left before the client trigger a token rotation.
|
||||
leewayPercent int
|
||||
|
||||
mutex sync.Mutex
|
||||
|
||||
clock clock.Clock
|
||||
}
|
||||
|
||||
func NewDynamicClientBuilder(clientConfig *restclient.Config, coreClient v1core.CoreV1Interface, ns string) clientbuilder.ControllerClientBuilder {
|
||||
builder := &DynamicControllerClientBuilder{
|
||||
ClientConfig: clientConfig,
|
||||
CoreClient: coreClient,
|
||||
Namespace: ns,
|
||||
roundTripperFuncMap: map[string]func(http.RoundTripper) http.RoundTripper{},
|
||||
expirationSeconds: defaultExpirationSeconds,
|
||||
leewayPercent: defaultLeewayPercent,
|
||||
clock: clock.RealClock{},
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
// this function only for test purpose, don't call it
|
||||
func NewTestDynamicClientBuilder(clientConfig *restclient.Config, coreClient v1core.CoreV1Interface, ns string, expirationSeconds int64, leewayPercent int) clientbuilder.ControllerClientBuilder {
|
||||
builder := &DynamicControllerClientBuilder{
|
||||
ClientConfig: clientConfig,
|
||||
CoreClient: coreClient,
|
||||
Namespace: ns,
|
||||
roundTripperFuncMap: map[string]func(http.RoundTripper) http.RoundTripper{},
|
||||
expirationSeconds: expirationSeconds,
|
||||
leewayPercent: leewayPercent,
|
||||
clock: clock.RealClock{},
|
||||
}
|
||||
return builder
|
||||
}
|
||||
|
||||
func (t *DynamicControllerClientBuilder) Config(saName string) (*restclient.Config, error) {
|
||||
_, err := getOrCreateServiceAccount(t.CoreClient, t.Namespace, saName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
configCopy := constructClient(t.Namespace, saName, t.ClientConfig)
|
||||
|
||||
t.mutex.Lock()
|
||||
defer t.mutex.Unlock()
|
||||
|
||||
rt, ok := t.roundTripperFuncMap[saName]
|
||||
if ok {
|
||||
configCopy.WrapTransport = rt
|
||||
} else {
|
||||
cachedTokenSource := transport.NewCachedTokenSource(&tokenSourceImpl{
|
||||
namespace: t.Namespace,
|
||||
serviceAccountName: saName,
|
||||
coreClient: t.CoreClient,
|
||||
expirationSeconds: t.expirationSeconds,
|
||||
leewayPercent: t.leewayPercent,
|
||||
})
|
||||
configCopy.WrapTransport = transport.TokenSourceWrapTransport(cachedTokenSource)
|
||||
|
||||
t.roundTripperFuncMap[saName] = configCopy.WrapTransport
|
||||
}
|
||||
|
||||
return &configCopy, nil
|
||||
}
|
||||
|
||||
func (t *DynamicControllerClientBuilder) ConfigOrDie(name string) *restclient.Config {
|
||||
clientConfig, err := t.Config(name)
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
return clientConfig
|
||||
}
|
||||
|
||||
func (t *DynamicControllerClientBuilder) Client(name string) (clientset.Interface, error) {
|
||||
clientConfig, err := t.Config(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return clientset.NewForConfig(clientConfig)
|
||||
}
|
||||
|
||||
func (t *DynamicControllerClientBuilder) ClientOrDie(name string) clientset.Interface {
|
||||
client, err := t.Client(name)
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
type tokenSourceImpl struct {
|
||||
namespace string
|
||||
serviceAccountName string
|
||||
coreClient v1core.CoreV1Interface
|
||||
expirationSeconds int64
|
||||
leewayPercent int
|
||||
}
|
||||
|
||||
func (ts *tokenSourceImpl) Token() (*oauth2.Token, error) {
|
||||
var retTokenRequest *v1authenticationapi.TokenRequest
|
||||
|
||||
backoff := wait.Backoff{
|
||||
Duration: 500 * time.Millisecond,
|
||||
Factor: 2, // double the timeout for every failure
|
||||
Steps: 4,
|
||||
}
|
||||
if err := wait.ExponentialBackoff(backoff, func() (bool, error) {
|
||||
if _, inErr := getOrCreateServiceAccount(ts.coreClient, ts.namespace, ts.serviceAccountName); inErr != nil {
|
||||
klog.Warningf("get or create service account failed: %v", inErr)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
tr, inErr := ts.coreClient.ServiceAccounts(ts.namespace).CreateToken(context.TODO(), ts.serviceAccountName, &v1authenticationapi.TokenRequest{
|
||||
Spec: v1authenticationapi.TokenRequestSpec{
|
||||
ExpirationSeconds: utilpointer.Int64Ptr(ts.expirationSeconds),
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
if inErr != nil {
|
||||
klog.Warningf("get token failed: %v", inErr)
|
||||
return false, nil
|
||||
}
|
||||
retTokenRequest = tr
|
||||
return true, nil
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("failed to get token for %s/%s: %v", ts.namespace, ts.serviceAccountName, err)
|
||||
}
|
||||
|
||||
if retTokenRequest.Spec.ExpirationSeconds == nil {
|
||||
return nil, fmt.Errorf("nil pointer of expiration in token request")
|
||||
}
|
||||
|
||||
lifetime := retTokenRequest.Status.ExpirationTimestamp.Time.Sub(time.Now())
|
||||
if lifetime < time.Minute*10 {
|
||||
// possible clock skew issue, pin to minimum token lifetime
|
||||
lifetime = time.Minute * 10
|
||||
}
|
||||
|
||||
leeway := time.Duration(int64(lifetime) * int64(ts.leewayPercent) / 100)
|
||||
expiry := time.Now().Add(lifetime).Add(-1 * leeway)
|
||||
|
||||
return &oauth2.Token{
|
||||
AccessToken: retTokenRequest.Status.Token,
|
||||
TokenType: "Bearer",
|
||||
Expiry: expiry,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func constructClient(saNamespace, saName string, config *restclient.Config) restclient.Config {
|
||||
username := apiserverserviceaccount.MakeUsername(saNamespace, saName)
|
||||
ret := *restclient.AnonymousClientConfig(config)
|
||||
restclient.AddUserAgent(&ret, username)
|
||||
return ret
|
||||
}
|
114
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
114
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
@ -22,6 +22,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"math"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
@ -39,14 +40,16 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
clientretry "k8s.io/client-go/util/retry"
|
||||
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
||||
taintutils "k8s.io/kubernetes/pkg/util/taints"
|
||||
"k8s.io/utils/integer"
|
||||
@ -257,11 +260,6 @@ func (r *ControllerExpectations) DeletionObserved(controllerKey string) {
|
||||
r.LowerExpectations(controllerKey, 0, 1)
|
||||
}
|
||||
|
||||
// Expectations are either fulfilled, or expire naturally.
|
||||
type Expectations interface {
|
||||
Fulfilled() bool
|
||||
}
|
||||
|
||||
// ControlleeExpectations track controllee creates/deletes.
|
||||
type ControlleeExpectations struct {
|
||||
// Important: Since these two int64 fields are using sync/atomic, they have to be at the top of the struct due to a bug on 32-bit platforms
|
||||
@ -797,17 +795,23 @@ func (s ActivePods) Less(i, j int) bool {
|
||||
// is unknown, and a pod whose phase is unknown comes before a running pod.
|
||||
// 3. If exactly one of the pods is ready, the pod that is not ready comes
|
||||
// before the ready pod.
|
||||
// 4. If the pods' ranks differ, the pod with greater rank comes before the pod
|
||||
// 4. If controller.kubernetes.io/pod-deletion-cost annotation is set, then
|
||||
// the pod with the lower value will come first.
|
||||
// 5. If the pods' ranks differ, the pod with greater rank comes before the pod
|
||||
// with lower rank.
|
||||
// 5. If both pods are ready but have not been ready for the same amount of
|
||||
// 6. If both pods are ready but have not been ready for the same amount of
|
||||
// time, the pod that has been ready for a shorter amount of time comes
|
||||
// before the pod that has been ready for longer.
|
||||
// 6. If one pod has a container that has restarted more than any container in
|
||||
// 7. If one pod has a container that has restarted more than any container in
|
||||
// the other pod, the pod with the container with more restarts comes
|
||||
// before the other pod.
|
||||
// 7. If the pods' creation times differ, the pod that was created more recently
|
||||
// 8. If the pods' creation times differ, the pod that was created more recently
|
||||
// comes before the older pod.
|
||||
//
|
||||
// In 6 and 8, times are compared in a logarithmic scale. This allows a level
|
||||
// of randomness among equivalent Pods when sorting. If two pods have the same
|
||||
// logarithmic rank, they are sorted by UUID to provide a pseudorandom order.
|
||||
//
|
||||
// If none of these rules matches, the second pod comes before the first pod.
|
||||
//
|
||||
// The intention of this ordering is to put pods that should be preferred for
|
||||
@ -820,6 +824,10 @@ type ActivePodsWithRanks struct {
|
||||
// comparing two pods that are both scheduled, in the same phase, and
|
||||
// having the same ready status.
|
||||
Rank []int
|
||||
|
||||
// Now is a reference timestamp for doing logarithmic timestamp comparisons.
|
||||
// If zero, comparison happens without scaling.
|
||||
Now metav1.Time
|
||||
}
|
||||
|
||||
func (s ActivePodsWithRanks) Len() int {
|
||||
@ -848,7 +856,17 @@ func (s ActivePodsWithRanks) Less(i, j int) bool {
|
||||
if podutil.IsPodReady(s.Pods[i]) != podutil.IsPodReady(s.Pods[j]) {
|
||||
return !podutil.IsPodReady(s.Pods[i])
|
||||
}
|
||||
// 4. Doubled up < not doubled up
|
||||
|
||||
// 4. higher pod-deletion-cost < lower pod-deletion cost
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.PodDeletionCost) {
|
||||
pi, _ := helper.GetDeletionCostFromPodAnnotations(s.Pods[i].Annotations)
|
||||
pj, _ := helper.GetDeletionCostFromPodAnnotations(s.Pods[j].Annotations)
|
||||
if pi != pj {
|
||||
return pi < pj
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Doubled up < not doubled up
|
||||
// If one of the two pods is on the same node as one or more additional
|
||||
// ready pods that belong to the same replicaset, whichever pod has more
|
||||
// colocated ready pods is less
|
||||
@ -857,22 +875,44 @@ func (s ActivePodsWithRanks) Less(i, j int) bool {
|
||||
}
|
||||
// TODO: take availability into account when we push minReadySeconds information from deployment into pods,
|
||||
// see https://github.com/kubernetes/kubernetes/issues/22065
|
||||
// 5. Been ready for empty time < less time < more time
|
||||
// 6. Been ready for empty time < less time < more time
|
||||
// If both pods are ready, the latest ready one is smaller
|
||||
if podutil.IsPodReady(s.Pods[i]) && podutil.IsPodReady(s.Pods[j]) {
|
||||
readyTime1 := podReadyTime(s.Pods[i])
|
||||
readyTime2 := podReadyTime(s.Pods[j])
|
||||
if !readyTime1.Equal(readyTime2) {
|
||||
return afterOrZero(readyTime1, readyTime2)
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.LogarithmicScaleDown) {
|
||||
return afterOrZero(readyTime1, readyTime2)
|
||||
} else {
|
||||
if s.Now.IsZero() || readyTime1.IsZero() || readyTime2.IsZero() {
|
||||
return afterOrZero(readyTime1, readyTime2)
|
||||
}
|
||||
rankDiff := logarithmicRankDiff(*readyTime1, *readyTime2, s.Now)
|
||||
if rankDiff == 0 {
|
||||
return s.Pods[i].UID < s.Pods[j].UID
|
||||
}
|
||||
return rankDiff < 0
|
||||
}
|
||||
}
|
||||
}
|
||||
// 6. Pods with containers with higher restart counts < lower restart counts
|
||||
// 7. Pods with containers with higher restart counts < lower restart counts
|
||||
if maxContainerRestarts(s.Pods[i]) != maxContainerRestarts(s.Pods[j]) {
|
||||
return maxContainerRestarts(s.Pods[i]) > maxContainerRestarts(s.Pods[j])
|
||||
}
|
||||
// 7. Empty creation time pods < newer pods < older pods
|
||||
// 8. Empty creation time pods < newer pods < older pods
|
||||
if !s.Pods[i].CreationTimestamp.Equal(&s.Pods[j].CreationTimestamp) {
|
||||
return afterOrZero(&s.Pods[i].CreationTimestamp, &s.Pods[j].CreationTimestamp)
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.LogarithmicScaleDown) {
|
||||
return afterOrZero(&s.Pods[i].CreationTimestamp, &s.Pods[j].CreationTimestamp)
|
||||
} else {
|
||||
if s.Now.IsZero() || s.Pods[i].CreationTimestamp.IsZero() || s.Pods[j].CreationTimestamp.IsZero() {
|
||||
return afterOrZero(&s.Pods[i].CreationTimestamp, &s.Pods[j].CreationTimestamp)
|
||||
}
|
||||
rankDiff := logarithmicRankDiff(s.Pods[i].CreationTimestamp, s.Pods[j].CreationTimestamp, s.Now)
|
||||
if rankDiff == 0 {
|
||||
return s.Pods[i].UID < s.Pods[j].UID
|
||||
}
|
||||
return rankDiff < 0
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@ -886,6 +926,22 @@ func afterOrZero(t1, t2 *metav1.Time) bool {
|
||||
return t1.After(t2.Time)
|
||||
}
|
||||
|
||||
// logarithmicRankDiff calculates the base-2 logarithmic ranks of 2 timestamps,
|
||||
// compared to the current timestamp
|
||||
func logarithmicRankDiff(t1, t2, now metav1.Time) int64 {
|
||||
d1 := now.Sub(t1.Time)
|
||||
d2 := now.Sub(t2.Time)
|
||||
r1 := int64(-1)
|
||||
r2 := int64(-1)
|
||||
if d1 > 0 {
|
||||
r1 = int64(math.Log2(float64(d1)))
|
||||
}
|
||||
if d2 > 0 {
|
||||
r2 = int64(math.Log2(float64(d2)))
|
||||
}
|
||||
return r1 - r2
|
||||
}
|
||||
|
||||
func podReadyTime(pod *v1.Pod) *metav1.Time {
|
||||
if podutil.IsPodReady(pod) {
|
||||
for _, c := range pod.Status.Conditions {
|
||||
@ -1188,29 +1244,3 @@ func AddOrUpdateLabelsOnNode(kubeClient clientset.Interface, nodeName string, la
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func getOrCreateServiceAccount(coreClient v1core.CoreV1Interface, namespace, name string) (*v1.ServiceAccount, error) {
|
||||
sa, err := coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
return sa, nil
|
||||
}
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create the namespace if we can't verify it exists.
|
||||
// Tolerate errors, since we don't know whether this component has namespace creation permissions.
|
||||
if _, err := coreClient.Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{}); apierrors.IsNotFound(err) {
|
||||
if _, err = coreClient.Namespaces().Create(context.TODO(), &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}}, metav1.CreateOptions{}); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
klog.Warningf("create non-exist namespace %s failed:%v", namespace, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create the service account
|
||||
sa, err = coreClient.ServiceAccounts(namespace).Create(context.TODO(), &v1.ServiceAccount{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}}, metav1.CreateOptions{})
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
// If we're racing to init and someone else already created it, re-fetch
|
||||
return coreClient.ServiceAccounts(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
}
|
||||
return sa, err
|
||||
}
|
||||
|
68
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/BUILD
generated
vendored
68
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/BUILD
generated
vendored
@ -1,68 +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 = ["deployment_util.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/controller/deployment/util",
|
||||
deps = [
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/labels:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/apps/v1:go_default_library",
|
||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||
"//vendor/k8s.io/utils/integer:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"deployment_util_test.go",
|
||||
"hash_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/util/hash:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/storage/names:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
17
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
17
vendor/k8s.io/kubernetes/pkg/controller/deployment/util/deployment_util.go
generated
vendored
@ -319,7 +319,7 @@ func copyDeploymentAnnotationsToReplicaSet(deployment *apps.Deployment, rs *apps
|
||||
// newRS revision is updated automatically in getNewReplicaSet, and the deployment's revision number is then updated
|
||||
// by copying its newRS revision number. We should not copy deployment's revision to its newRS, since the update of
|
||||
// deployment revision number may fail (revision becomes stale) and the revision number in newRS is more reliable.
|
||||
if skipCopyAnnotation(k) || rs.Annotations[k] == v {
|
||||
if _, exist := rs.Annotations[k]; skipCopyAnnotation(k) || (exist && rs.Annotations[k] == v) {
|
||||
continue
|
||||
}
|
||||
rs.Annotations[k] = v
|
||||
@ -949,3 +949,18 @@ func GetDeploymentsForReplicaSet(deploymentLister appslisters.DeploymentLister,
|
||||
|
||||
return deployments, nil
|
||||
}
|
||||
|
||||
// ReplicaSetsByRevision sorts a list of ReplicaSet by revision, using their creation timestamp or name as a tie breaker.
|
||||
// By using the creation timestamp, this sorts from old to new replica sets.
|
||||
type ReplicaSetsByRevision []*apps.ReplicaSet
|
||||
|
||||
func (o ReplicaSetsByRevision) Len() int { return len(o) }
|
||||
func (o ReplicaSetsByRevision) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
|
||||
func (o ReplicaSetsByRevision) Less(i, j int) bool {
|
||||
revision1, err1 := Revision(o[i])
|
||||
revision2, err2 := Revision(o[j])
|
||||
if err1 != nil || err2 != nil || revision1 == revision2 {
|
||||
return controller.ReplicaSetsByCreationTimestamp(o).Less(i, j)
|
||||
}
|
||||
return revision1 < revision2
|
||||
}
|
||||
|
Reference in New Issue
Block a user