Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
2274e93b
Unverified
Commit
2274e93b
authored
Jan 26, 2018
by
Bobby (Babak) Salamat
Committed by
GitHub
Jan 26, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "Change equivalence class hashing function"
parent
2cc0ecdf
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
112 additions
and
73 deletions
+112
-73
BUILD
pkg/scheduler/algorithm/predicates/BUILD
+1
-0
utils.go
pkg/scheduler/algorithm/predicates/utils.go
+66
-0
types.go
pkg/scheduler/algorithm/types.go
+2
-0
defaults.go
pkg/scheduler/algorithmprovider/defaults/defaults.go
+7
-0
equivalence_cache.go
pkg/scheduler/core/equivalence_cache.go
+16
-68
equivalence_cache_test.go
pkg/scheduler/core/equivalence_cache_test.go
+0
-0
generic_scheduler.go
pkg/scheduler/core/generic_scheduler.go
+1
-1
factory.go
pkg/scheduler/factory/factory.go
+8
-4
plugins.go
pkg/scheduler/factory/plugins.go
+11
-0
No files found.
pkg/scheduler/algorithm/predicates/BUILD
View file @
2274e93b
...
@@ -34,6 +34,7 @@ go_library(
...
@@ -34,6 +34,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/rand:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/client-go/listers/core/v1:go_default_library",
"//vendor/k8s.io/client-go/listers/core/v1:go_default_library",
"//vendor/k8s.io/client-go/listers/storage/v1:go_default_library",
"//vendor/k8s.io/client-go/listers/storage/v1:go_default_library",
...
...
pkg/scheduler/algorithm/predicates/utils.go
View file @
2274e93b
...
@@ -17,8 +17,12 @@ limitations under the License.
...
@@ -17,8 +17,12 @@ limitations under the License.
package
predicates
package
predicates
import
(
import
(
"github.com/golang/glog"
"k8s.io/api/core/v1"
"k8s.io/api/core/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/scheduler/algorithm"
schedutil
"k8s.io/kubernetes/pkg/scheduler/util"
schedutil
"k8s.io/kubernetes/pkg/scheduler/util"
)
)
...
@@ -66,6 +70,68 @@ func CreateSelectorFromLabels(aL map[string]string) labels.Selector {
...
@@ -66,6 +70,68 @@ func CreateSelectorFromLabels(aL map[string]string) labels.Selector {
return
labels
.
Set
(
aL
)
.
AsSelector
()
return
labels
.
Set
(
aL
)
.
AsSelector
()
}
}
// EquivalencePodGenerator is a generator of equivalence class for pod with consideration of PVC info.
type
EquivalencePodGenerator
struct
{
pvcInfo
PersistentVolumeClaimInfo
}
// NewEquivalencePodGenerator returns a getEquivalencePod method with consideration of PVC info.
func
NewEquivalencePodGenerator
(
pvcInfo
PersistentVolumeClaimInfo
)
algorithm
.
GetEquivalencePodFunc
{
g
:=
&
EquivalencePodGenerator
{
pvcInfo
:
pvcInfo
,
}
return
g
.
getEquivalencePod
}
// GetEquivalencePod returns a EquivalencePod which contains a group of pod attributes which can be reused.
func
(
e
*
EquivalencePodGenerator
)
getEquivalencePod
(
pod
*
v1
.
Pod
)
interface
{}
{
// For now we only consider pods:
// 1. OwnerReferences is Controller
// 2. with same OwnerReferences
// 3. with same PVC claim
// to be equivalent
for
_
,
ref
:=
range
pod
.
OwnerReferences
{
if
ref
.
Controller
!=
nil
&&
*
ref
.
Controller
{
if
pvcSet
,
err
:=
e
.
getPVCSet
(
pod
);
err
==
nil
{
// A pod can only belongs to one controller, so let's return.
return
&
EquivalencePod
{
ControllerRef
:
ref
,
PVCSet
:
pvcSet
,
}
}
else
{
// If error encountered, log warning and return nil (i.e. no equivalent pod found)
glog
.
Warningf
(
"[EquivalencePodGenerator] for pod: %v failed due to: %v"
,
pod
.
GetName
(),
err
)
return
nil
}
}
}
return
nil
}
// getPVCSet returns a set of PVC UIDs of given pod.
func
(
e
*
EquivalencePodGenerator
)
getPVCSet
(
pod
*
v1
.
Pod
)
(
sets
.
String
,
error
)
{
result
:=
sets
.
NewString
()
for
_
,
volume
:=
range
pod
.
Spec
.
Volumes
{
if
volume
.
PersistentVolumeClaim
==
nil
{
continue
}
pvcName
:=
volume
.
PersistentVolumeClaim
.
ClaimName
pvc
,
err
:=
e
.
pvcInfo
.
GetPersistentVolumeClaimInfo
(
pod
.
GetNamespace
(),
pvcName
)
if
err
!=
nil
{
return
nil
,
err
}
result
.
Insert
(
string
(
pvc
.
UID
))
}
return
result
,
nil
}
// EquivalencePod is a group of pod attributes which can be reused as equivalence to schedule other pods.
type
EquivalencePod
struct
{
ControllerRef
metav1
.
OwnerReference
PVCSet
sets
.
String
}
// portsConflict check whether existingPorts and wantPorts conflict with each other
// portsConflict check whether existingPorts and wantPorts conflict with each other
// return true if we have a conflict
// return true if we have a conflict
func
portsConflict
(
existingPorts
schedutil
.
HostPortInfo
,
wantPorts
[]
*
v1
.
ContainerPort
)
bool
{
func
portsConflict
(
existingPorts
schedutil
.
HostPortInfo
,
wantPorts
[]
*
v1
.
ContainerPort
)
bool
{
...
...
pkg/scheduler/algorithm/types.go
View file @
2274e93b
...
@@ -75,6 +75,8 @@ type PredicateFailureReason interface {
...
@@ -75,6 +75,8 @@ type PredicateFailureReason interface {
GetReason
()
string
GetReason
()
string
}
}
type
GetEquivalencePodFunc
func
(
pod
*
v1
.
Pod
)
interface
{}
// NodeLister interface represents anything that can list nodes for a scheduler.
// NodeLister interface represents anything that can list nodes for a scheduler.
type
NodeLister
interface
{
type
NodeLister
interface
{
// We explicitly return []*v1.Node, instead of v1.NodeList, to avoid
// We explicitly return []*v1.Node, instead of v1.NodeList, to avoid
...
...
pkg/scheduler/algorithmprovider/defaults/defaults.go
View file @
2274e93b
...
@@ -77,6 +77,13 @@ func init() {
...
@@ -77,6 +77,13 @@ func init() {
// Fit is determined by node selector query.
// Fit is determined by node selector query.
factory
.
RegisterFitPredicate
(
predicates
.
MatchNodeSelectorPred
,
predicates
.
PodMatchNodeSelector
)
factory
.
RegisterFitPredicate
(
predicates
.
MatchNodeSelectorPred
,
predicates
.
PodMatchNodeSelector
)
// Use equivalence class to speed up heavy predicates phase.
factory
.
RegisterGetEquivalencePodFunction
(
func
(
args
factory
.
PluginFactoryArgs
)
algorithm
.
GetEquivalencePodFunc
{
return
predicates
.
NewEquivalencePodGenerator
(
args
.
PVCInfo
)
},
)
// ServiceSpreadingPriority is a priority config factory that spreads pods by minimizing
// ServiceSpreadingPriority is a priority config factory that spreads pods by minimizing
// the number of pods (belonging to the same service) on the same node.
// the number of pods (belonging to the same service) on the same node.
// Register the factory so that it's available, but do not include it as part of the default priorities
// Register the factory so that it's available, but do not include it as part of the default priorities
...
...
pkg/scheduler/core/equivalence_cache.go
View file @
2274e93b
...
@@ -37,7 +37,8 @@ const maxCacheEntries = 100
...
@@ -37,7 +37,8 @@ const maxCacheEntries = 100
// 2. function to get equivalence pod
// 2. function to get equivalence pod
type
EquivalenceCache
struct
{
type
EquivalenceCache
struct
{
sync
.
RWMutex
sync
.
RWMutex
algorithmCache
map
[
string
]
AlgorithmCache
getEquivalencePod
algorithm
.
GetEquivalencePodFunc
algorithmCache
map
[
string
]
AlgorithmCache
}
}
// The AlgorithmCache stores PredicateMap with predicate name as key
// The AlgorithmCache stores PredicateMap with predicate name as key
...
@@ -61,9 +62,10 @@ func newAlgorithmCache() AlgorithmCache {
...
@@ -61,9 +62,10 @@ func newAlgorithmCache() AlgorithmCache {
}
}
}
}
func
NewEquivalenceCache
()
*
EquivalenceCache
{
func
NewEquivalenceCache
(
getEquivalencePodFunc
algorithm
.
GetEquivalencePodFunc
)
*
EquivalenceCache
{
return
&
EquivalenceCache
{
return
&
EquivalenceCache
{
algorithmCache
:
make
(
map
[
string
]
AlgorithmCache
),
getEquivalencePod
:
getEquivalencePodFunc
,
algorithmCache
:
make
(
map
[
string
]
AlgorithmCache
),
}
}
}
}
...
@@ -206,69 +208,15 @@ func (ec *EquivalenceCache) InvalidateCachedPredicateItemForPodAdd(pod *v1.Pod,
...
@@ -206,69 +208,15 @@ func (ec *EquivalenceCache) InvalidateCachedPredicateItemForPodAdd(pod *v1.Pod,
ec
.
InvalidateCachedPredicateItem
(
nodeName
,
invalidPredicates
)
ec
.
InvalidateCachedPredicateItem
(
nodeName
,
invalidPredicates
)
}
}
// getEquivalenceHash computes a hash of the given pod.
// getHashEquivalencePod returns the hash of equivalence pod.
// The hashing function returns the same value for any two pods that are
// 1. equivalenceHash
// equivalent from the perspective of scheduling.
// 2. if equivalence hash is valid
func
(
ec
*
EquivalenceCache
)
getEquivalenceHash
(
pod
*
v1
.
Pod
)
(
uint64
,
bool
)
{
func
(
ec
*
EquivalenceCache
)
getHashEquivalencePod
(
pod
*
v1
.
Pod
)
(
uint64
,
bool
)
{
equivalencePod
:=
getEquivalencePod
(
pod
)
equivalencePod
:=
ec
.
getEquivalencePod
(
pod
)
hash
:=
fnv
.
New32a
()
if
equivalencePod
!=
nil
{
hashutil
.
DeepHashObject
(
hash
,
equivalencePod
)
hash
:=
fnv
.
New32a
()
return
uint64
(
hash
.
Sum32
()),
true
hashutil
.
DeepHashObject
(
hash
,
equivalencePod
)
}
return
uint64
(
hash
.
Sum32
()),
true
}
// equivalencePod is the set of pod attributes which must match for two pods to
return
0
,
false
// be considered equivalent for scheduling purposes. For correctness, this must
// include any Pod field which is used by a FitPredicate.
//
// NOTE: For equivalence hash to be formally correct, lists and maps in the
// equivalencePod should be normalized. (e.g. by sorting them) However, the
// vast majority of equivalent pod classes are expected to be created from a
// single pod template, so they will all have the same ordering.
type
equivalencePod
struct
{
Namespace
*
string
Labels
map
[
string
]
string
Affinity
*
v1
.
Affinity
Containers
[]
v1
.
Container
// See note about ordering
InitContainers
[]
v1
.
Container
// See note about ordering
NodeName
*
string
NodeSelector
map
[
string
]
string
Tolerations
[]
v1
.
Toleration
Volumes
[]
v1
.
Volume
// See note about ordering
}
// getEquivalencePod returns the equivalencePod for a Pod.
func
getEquivalencePod
(
pod
*
v1
.
Pod
)
*
equivalencePod
{
ep
:=
&
equivalencePod
{
Namespace
:
&
pod
.
Namespace
,
Labels
:
pod
.
Labels
,
Affinity
:
pod
.
Spec
.
Affinity
,
Containers
:
pod
.
Spec
.
Containers
,
InitContainers
:
pod
.
Spec
.
InitContainers
,
NodeName
:
&
pod
.
Spec
.
NodeName
,
NodeSelector
:
pod
.
Spec
.
NodeSelector
,
Tolerations
:
pod
.
Spec
.
Tolerations
,
Volumes
:
pod
.
Spec
.
Volumes
,
}
// DeepHashObject considers nil and empy slices to be different. Normalize them.
if
len
(
ep
.
Containers
)
==
0
{
ep
.
Containers
=
nil
}
if
len
(
ep
.
InitContainers
)
==
0
{
ep
.
InitContainers
=
nil
}
if
len
(
ep
.
Tolerations
)
==
0
{
ep
.
Tolerations
=
nil
}
if
len
(
ep
.
Volumes
)
==
0
{
ep
.
Volumes
=
nil
}
// Normalize empty maps also.
if
len
(
ep
.
Labels
)
==
0
{
ep
.
Labels
=
nil
}
if
len
(
ep
.
NodeSelector
)
==
0
{
ep
.
NodeSelector
=
nil
}
// TODO: Also normalize nested maps and slices.
return
ep
}
}
pkg/scheduler/core/equivalence_cache_test.go
View file @
2274e93b
This diff is collapsed.
Click to expand it.
pkg/scheduler/core/generic_scheduler.go
View file @
2274e93b
...
@@ -418,7 +418,7 @@ func podFitsOnNode(
...
@@ -418,7 +418,7 @@ func podFitsOnNode(
if
ecache
!=
nil
{
if
ecache
!=
nil
{
// getHashEquivalencePod will return immediately if no equivalence pod found
// getHashEquivalencePod will return immediately if no equivalence pod found
equivalenceHash
,
eCacheAvailable
=
ecache
.
get
EquivalenceHash
(
pod
)
equivalenceHash
,
eCacheAvailable
=
ecache
.
get
HashEquivalencePod
(
pod
)
}
}
podsAdded
:=
false
podsAdded
:=
false
// We run predicates twice in some cases. If the node has greater or equal priority
// We run predicates twice in some cases. If the node has greater or equal priority
...
...
pkg/scheduler/factory/factory.go
View file @
2274e93b
...
@@ -135,8 +135,6 @@ type configFactory struct {
...
@@ -135,8 +135,6 @@ type configFactory struct {
alwaysCheckAllPredicates
bool
alwaysCheckAllPredicates
bool
}
}
var
_
scheduler
.
Configurator
=
&
configFactory
{}
// NewConfigFactory initializes the default implementation of a Configurator To encourage eventual privatization of the struct type, we only
// NewConfigFactory initializes the default implementation of a Configurator To encourage eventual privatization of the struct type, we only
// return the interface.
// return the interface.
func
NewConfigFactory
(
func
NewConfigFactory
(
...
@@ -969,8 +967,14 @@ func (f *configFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String,
...
@@ -969,8 +967,14 @@ func (f *configFactory) CreateFromKeys(predicateKeys, priorityKeys sets.String,
}
}
// Init equivalence class cache
// Init equivalence class cache
if
f
.
enableEquivalenceClassCache
{
if
f
.
enableEquivalenceClassCache
&&
getEquivalencePodFuncFactory
!=
nil
{
f
.
equivalencePodCache
=
core
.
NewEquivalenceCache
()
pluginArgs
,
err
:=
f
.
getPluginArgs
()
if
err
!=
nil
{
return
nil
,
err
}
f
.
equivalencePodCache
=
core
.
NewEquivalenceCache
(
getEquivalencePodFuncFactory
(
*
pluginArgs
),
)
glog
.
Info
(
"Created equivalence class cache"
)
glog
.
Info
(
"Created equivalence class cache"
)
}
}
...
...
pkg/scheduler/factory/plugins.go
View file @
2274e93b
...
@@ -75,6 +75,9 @@ type PriorityConfigFactory struct {
...
@@ -75,6 +75,9 @@ type PriorityConfigFactory struct {
Weight
int
Weight
int
}
}
// EquivalencePodFuncFactory produces a function to get equivalence class for given pod.
type
EquivalencePodFuncFactory
func
(
PluginFactoryArgs
)
algorithm
.
GetEquivalencePodFunc
var
(
var
(
schedulerFactoryMutex
sync
.
Mutex
schedulerFactoryMutex
sync
.
Mutex
...
@@ -87,6 +90,9 @@ var (
...
@@ -87,6 +90,9 @@ var (
// Registered metadata producers
// Registered metadata producers
priorityMetadataProducer
PriorityMetadataProducerFactory
priorityMetadataProducer
PriorityMetadataProducerFactory
predicateMetadataProducer
PredicateMetadataProducerFactory
predicateMetadataProducer
PredicateMetadataProducerFactory
// get equivalence pod function
getEquivalencePodFuncFactory
EquivalencePodFuncFactory
)
)
const
(
const
(
...
@@ -335,6 +341,11 @@ func RegisterCustomPriorityFunction(policy schedulerapi.PriorityPolicy) string {
...
@@ -335,6 +341,11 @@ func RegisterCustomPriorityFunction(policy schedulerapi.PriorityPolicy) string {
return
RegisterPriorityConfigFactory
(
policy
.
Name
,
*
pcf
)
return
RegisterPriorityConfigFactory
(
policy
.
Name
,
*
pcf
)
}
}
// RegisterGetEquivalencePodFunction registers equivalenceFuncFactory to produce equivalence class for given pod.
func
RegisterGetEquivalencePodFunction
(
equivalenceFuncFactory
EquivalencePodFuncFactory
)
{
getEquivalencePodFuncFactory
=
equivalenceFuncFactory
}
// IsPriorityFunctionRegistered is useful for testing providers.
// IsPriorityFunctionRegistered is useful for testing providers.
func
IsPriorityFunctionRegistered
(
name
string
)
bool
{
func
IsPriorityFunctionRegistered
(
name
string
)
bool
{
schedulerFactoryMutex
.
Lock
()
schedulerFactoryMutex
.
Lock
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment