Refactor the corresponding code.

This commit is contained in:
t-qini 2019-07-19 20:54:25 +08:00
parent f7c563ab06
commit 89a09ccf00
22 changed files with 225 additions and 93 deletions

View File

@ -31,9 +31,6 @@ import (
)
const (
// ProviderName is the cloud provider name for alicloud
ProviderName = "alicloud"
// GPULabel is the label added to nodes with GPU resource.
GPULabel = "aliyun.accelerator/nvidia_name"
)
@ -99,7 +96,7 @@ func (ali *aliCloudProvider) addAsg(asg *Asg) {
}
func (ali *aliCloudProvider) Name() string {
return ProviderName
return cloudprovider.AlicloudProviderName
}
// GPULabel returns the label added to nodes with GPU resource.

View File

@ -33,9 +33,6 @@ import (
)
const (
// ProviderName is the cloud provider name for AWS
ProviderName = "aws"
// GPULabel is the label added to nodes with GPU resource.
GPULabel = "k8s.amazonaws.com/accelerator"
)
@ -71,7 +68,7 @@ func (aws *awsCloudProvider) Cleanup() error {
// Name returns name of the cloud provider.
func (aws *awsCloudProvider) Name() string {
return ProviderName
return cloudprovider.AwsProviderName
}
// GPULabel returns the label added to nodes with GPU resource.

View File

@ -149,7 +149,7 @@ func TestBuildAwsCloudProvider(t *testing.T) {
func TestName(t *testing.T) {
provider := testProvider(t, testAwsManager)
assert.Equal(t, provider.Name(), ProviderName)
assert.Equal(t, provider.Name(), cloudprovider.AwsProviderName)
}
func TestNodeGroups(t *testing.T) {

View File

@ -24,16 +24,11 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
"k8s.io/autoscaler/cluster-autoscaler/config"
"k8s.io/autoscaler/cluster-autoscaler/processors/nodegroupset"
"k8s.io/autoscaler/cluster-autoscaler/utils/errors"
"k8s.io/klog"
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
)
const (
// ProviderName is the cloud provider name for Azure
ProviderName = "azure"
// GPULabel is the label added to nodes with GPU resource.
GPULabel = "cloud.google.com/gke-accelerator"
)
@ -171,24 +166,3 @@ func BuildAzure(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscov
}
return provider
}
func nodesFromSameAzureNodePool(n1, n2 *schedulernodeinfo.NodeInfo) bool {
n1AzureNodePool := n1.Node().Labels[AzureNodepoolLabel]
n2AzureNodePool := n2.Node().Labels[AzureNodepoolLabel]
return n1AzureNodePool != "" && n1AzureNodePool == n2AzureNodePool
}
// IsNodeInfoSimilar compares if two nodes should be considered part of the
// same NodeGroupSet. This is true if they either belong to the same Azure agentpool
// or match usual conditions checked by IsNodeInfoSimilar, even if they have different agentpool labels.
func IsNodeInfoSimilar(n1, n2 *schedulernodeinfo.NodeInfo) bool {
if nodesFromSameAzureNodePool(n1, n2) {
return true
}
azureIgnoredLabels := make(map[string]bool)
for k, v := range nodegroupset.BasicIgnoredLabels {
azureIgnoredLabels[k] = v
}
azureIgnoredLabels[AzureNodepoolLabel] = true
return nodegroupset.IsCloudProviderNodeInfoSimilar(n1, n2, azureIgnoredLabels)
}

View File

@ -76,9 +76,6 @@ const (
k8sWindowsVMAgentPoolPrefixIndex = 1
k8sWindowsVMAgentOrchestratorNameIndex = 2
k8sWindowsVMAgentPoolInfoIndex = 3
// AzureNodepoolLabel is a label specifying which Azure node pool a particular node belongs to.
AzureNodepoolLabel = "agentpool"
)
var (

View File

@ -33,9 +33,6 @@ import (
)
const (
// ProviderName is the cloud provider name for baiducloud
ProviderName = "baiducloud"
// GPULabel is the label added to nodes with GPU resource.
GPULabel = "cloud.google.com/gke-accelerator"
)
@ -147,7 +144,7 @@ func (baiducloud *baiducloudCloudProvider) addAsg(asg *Asg) {
// Name returns name of the cloud provider.
func (baiducloud *baiducloudCloudProvider) Name() string {
return ProviderName
return cloudprovider.BaiducloudProviderName
}
// NodeGroups returns all node groups configured for this cloud provider.

View File

@ -56,7 +56,7 @@ func TestBuildAwsCloudProvider(t *testing.T) {
func TestName(t *testing.T) {
provider := testProvider(t, testBaiducloudManager)
assert.Equal(t, provider.Name(), ProviderName)
assert.Equal(t, provider.Name(), cloudprovider.BaiducloudProviderName)
}
func TestNodeGroups(t *testing.T) {

View File

@ -26,15 +26,15 @@ import (
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
alicloud.ProviderName,
cloudprovider.AlicloudProviderName,
}
// DefaultCloudProvider for alicloud-only build is alicloud.
const DefaultCloudProvider = alicloud.ProviderName
const DefaultCloudProvider = cloudprovider.AlicloudProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case alicloud.ProviderName:
case cloudprovider.AlicloudProviderName:
return alicloud.BuildAlicloud(opts, do, rl)
}

View File

@ -31,30 +31,30 @@ import (
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
aws.ProviderName,
azure.ProviderName,
gce.ProviderNameGCE,
alicloud.ProviderName,
baiducloud.ProviderName,
magnum.ProviderName,
cloudprovider.AwsProviderName,
cloudprovider.AzureProviderName,
cloudprovider.GceProviderName,
cloudprovider.AlicloudProviderName,
cloudprovider.BaiducloudProviderName,
cloudprovider.MagnumProviderName,
}
// DefaultCloudProvider is GCE.
const DefaultCloudProvider = gce.ProviderNameGCE
const DefaultCloudProvider = cloudprovider.GceProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case gce.ProviderNameGCE:
case cloudprovider.GceProviderName:
return gce.BuildGCE(opts, do, rl)
case aws.ProviderName:
case cloudprovider.AwsProviderName:
return aws.BuildAWS(opts, do, rl)
case azure.ProviderName:
case cloudprovider.AzureProviderName:
return azure.BuildAzure(opts, do, rl)
case alicloud.ProviderName:
case cloudprovider.AlicloudProviderName:
return alicloud.BuildAlicloud(opts, do, rl)
case baiducloud.ProviderName:
case cloudprovider.BaiducloudProviderName:
return baiducloud.BuildBaiducloud(opts, do, rl)
case magnum.ProviderName:
case cloudprovider.MagnumProviderName:
return magnum.BuildMagnum(opts, do, rl)
}
return nil

View File

@ -26,15 +26,15 @@ import (
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
aws.ProviderName,
cloudprovider.AwsProviderName,
}
// DefaultCloudProvider for AWS-only build is AWS.
const DefaultCloudProvider = aws.ProviderName
const DefaultCloudProvider = cloudprovider.AwsProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case aws.ProviderName:
case cloudprovider.AwsProviderName:
return aws.BuildAWS(opts, do, rl)
}

View File

@ -26,15 +26,15 @@ import (
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
azure.ProviderName,
cloudprovider.AzureProviderName,
}
// DefaultCloudProvider on Azure-only build is Azure.
const DefaultCloudProvider = azure.ProviderName
const DefaultCloudProvider = cloudprovider.AzureProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case azure.ProviderName:
case cloudprovider.AzureProviderName:
return azure.BuildAzure(opts, do, rl)
}

View File

@ -20,22 +20,21 @@ package builder
import (
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/aws"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/baiducloud"
"k8s.io/autoscaler/cluster-autoscaler/config"
)
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
baiducloud.ProviderName,
cloudprovider.BaiducloudProviderName,
}
// DefaultCloudProvider for baiducloud-only build is baiducloud.
const DefaultCloudProvider = baiducloud.ProviderName
const DefaultCloudProvider = cloudprovider.BaiducloudProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case baiducloud.ProviderName:
case cloudprovider.BaiducloudProviderName:
return baiducloud.BuildBaiducloud(opts, do, rl)
}

View File

@ -26,15 +26,15 @@ import (
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
gce.ProviderNameGCE,
cloudprovider.GceProviderName,
}
// DefaultCloudProvider is GCE.
const DefaultCloudProvider = gce.ProviderNameGCE
const DefaultCloudProvider = cloudprovider.GceProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case gce.ProviderNameGCE:
case cloudprovider.GceProviderName:
return gce.BuildGCE(opts, do, rl)
}

View File

@ -26,15 +26,15 @@ import (
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
kubemark.ProviderName,
cloudprovider.KubemarkProviderName,
}
// DefaultCloudProvider for Kubemark-only build is Kubemark.
const DefaultCloudProvider = kubemark.ProviderName
const DefaultCloudProvider = cloudprovider.KubemarkProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case kubemark.ProviderName:
case cloudprovider.KubemarkProviderName:
return kubemark.BuildKubemark(opts, do, rl)
}

View File

@ -26,15 +26,15 @@ import (
// AvailableCloudProviders supported by the cloud provider builder.
var AvailableCloudProviders = []string{
magnum.ProviderName,
cloudprovider.MagnumProviderName,
}
// DefaultCloudProvider for OpenStack-only build is OpenStack.
const DefaultCloudProvider = magnum.ProviderName
const DefaultCloudProvider = cloudprovider.MagnumProviderName
func buildCloudProvider(opts config.AutoscalingOptions, do cloudprovider.NodeGroupDiscoveryOptions, rl *cloudprovider.ResourceLimiter) cloudprovider.CloudProvider {
switch opts.CloudProviderName {
case magnum.ProviderName:
case cloudprovider.MagnumProviderName:
return magnum.BuildMagnum(opts, do, rl)
}

View File

@ -27,9 +27,20 @@ import (
)
const (
// AzureProviderName gets the azure.ProviderName. To prevent the cyclic importation,
// `azure.ProviderName` cannot be directly used here.
// AzureProviderName gets the provider name of azure
AzureProviderName = "azure"
// AlicloudProviderName gets the provider name of alicloud
AlicloudProviderName = "alicloud"
// AwsProviderName gets the provider name of aws
AwsProviderName = "aws"
// BaiducloudProviderName gets the provider name of baiducloud
BaiducloudProviderName = "baiducloud"
// GceProviderName gets the provider name of gce
GceProviderName = "gce"
// MagnumProviderName gets the provider name of magnum
MagnumProviderName = "magnum"
// KubemarkProviderName gets the provider name of kubemark
KubemarkProviderName = "kubemark"
)
// CloudProvider contains configuration info and functions for interacting with

View File

@ -32,9 +32,6 @@ import (
)
const (
// ProviderNameGCE is the name of GCE cloud provider.
ProviderNameGCE = "gce"
// GPULabel is the label added to nodes with GPU resource.
GPULabel = "cloud.google.com/gke-accelerator"
)
@ -69,7 +66,7 @@ func (gce *GceCloudProvider) Cleanup() error {
// Name returns name of the cloud provider.
func (gce *GceCloudProvider) Name() string {
return ProviderNameGCE
return cloudprovider.GceProviderName
}
// GPULabel returns the label added to nodes with GPU resource.

View File

@ -30,9 +30,6 @@ import (
)
const (
// ProviderName is the cloud provider name for kubemark
ProviderName = "kubemark"
// GPULabel is the label added to nodes with GPU resource.
GPULabel = "cloud.google.com/gke-accelerator"
)

View File

@ -31,8 +31,6 @@ import (
)
const (
// ProviderName is the cloud provider name for Magnum
ProviderName = "magnum"
// GPULabel is the label added to nodes with GPU resource.
GPULabel = "cloud.google.com/gke-accelerator"
)
@ -63,7 +61,7 @@ func buildMagnumCloudProvider(magnumManager magnumManager, resourceLimiter *clou
// Name returns the name of the cloud provider.
func (mcp *magnumCloudProvider) Name() string {
return ProviderName
return cloudprovider.MagnumProviderName
}
// GPULabel returns the label added to nodes with GPU resource.

View File

@ -29,8 +29,6 @@ import (
"syscall"
"time"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider/azure"
"github.com/prometheus/client_golang/prometheus"
"github.com/spf13/pflag"
@ -292,7 +290,7 @@ func buildAutoscaler() (core.Autoscaler, error) {
processors.PodListProcessor = core.NewFilterOutSchedulablePodListProcessor()
if autoscalingOptions.CloudProviderName == cloudprovider.AzureProviderName {
processors.NodeGroupSetProcessor = &nodegroupset.BalancingNodeGroupSetProcessor{
Comparator: azure.IsNodeInfoSimilar}
Comparator: nodegroupset.IsAzureNodeInfoSimilar}
}
opts := core.AutoscalerOptions{

View File

@ -0,0 +1,45 @@
/*
Copyright 2019 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 nodegroupset
import (
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
)
// AzureNodepoolLabel is a label specifying which Azure node pool a particular node belongs to.
const AzureNodepoolLabel = "agentpool"
func nodesFromSameAzureNodePool(n1, n2 *schedulernodeinfo.NodeInfo) bool {
n1AzureNodePool := n1.Node().Labels[AzureNodepoolLabel]
n2AzureNodePool := n2.Node().Labels[AzureNodepoolLabel]
return n1AzureNodePool != "" && n1AzureNodePool == n2AzureNodePool
}
// IsAzureNodeInfoSimilar compares if two nodes should be considered part of the
// same NodeGroupSet. This is true if they either belong to the same Azure agentpool
// or match usual conditions checked by IsAzureNodeInfoSimilar, even if they have different agentpool labels.
func IsAzureNodeInfoSimilar(n1, n2 *schedulernodeinfo.NodeInfo) bool {
if nodesFromSameAzureNodePool(n1, n2) {
return true
}
azureIgnoredLabels := make(map[string]bool)
for k, v := range BasicIgnoredLabels {
azureIgnoredLabels[k] = v
}
azureIgnoredLabels[AzureNodepoolLabel] = true
return IsCloudProviderNodeInfoSimilar(n1, n2, azureIgnoredLabels)
}

View File

@ -0,0 +1,125 @@
/*
Copyright 2019 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 nodegroupset
import (
"testing"
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
testprovider "k8s.io/autoscaler/cluster-autoscaler/cloudprovider/test"
"k8s.io/autoscaler/cluster-autoscaler/context"
. "k8s.io/autoscaler/cluster-autoscaler/utils/test"
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
"github.com/stretchr/testify/assert"
)
func TestIsAzureNodeInfoSimilar(t *testing.T) {
n1 := BuildTestNode("node1", 1000, 2000)
n1.ObjectMeta.Labels["test-label"] = "test-value"
n1.ObjectMeta.Labels["character"] = "thing"
n2 := BuildTestNode("node2", 1000, 2000)
n2.ObjectMeta.Labels["test-label"] = "test-value"
// No node-pool labels.
checkNodesSimilar(t, n1, n2, IsAzureNodeInfoSimilar, false)
// Empty agentpool labels
n1.ObjectMeta.Labels["agentpool"] = ""
n2.ObjectMeta.Labels["agentpool"] = ""
checkNodesSimilar(t, n1, n2, IsAzureNodeInfoSimilar, false)
// Only one non empty
n1.ObjectMeta.Labels["agentpool"] = ""
n2.ObjectMeta.Labels["agentpool"] = "foo"
checkNodesSimilar(t, n1, n2, IsAzureNodeInfoSimilar, false)
// Only one present
delete(n1.ObjectMeta.Labels, "agentpool")
n2.ObjectMeta.Labels["agentpool"] = "foo"
checkNodesSimilar(t, n1, n2, IsAzureNodeInfoSimilar, false)
// Different vales
n1.ObjectMeta.Labels["agentpool"] = "foo1"
n2.ObjectMeta.Labels["agentpool"] = "foo2"
checkNodesSimilar(t, n1, n2, IsAzureNodeInfoSimilar, false)
// Same values
n1.ObjectMeta.Labels["agentpool"] = "foo"
n2.ObjectMeta.Labels["agentpool"] = "foo"
checkNodesSimilar(t, n1, n2, IsAzureNodeInfoSimilar, true)
// Same labels except for agentpool
delete(n1.ObjectMeta.Labels, "character")
n1.ObjectMeta.Labels["agentpool"] = "foo"
n2.ObjectMeta.Labels["agentpool"] = "bar"
checkNodesSimilar(t, n1, n2, IsAzureNodeInfoSimilar, true)
}
func TestFindSimilarNodeGroupsAzureBasic(t *testing.T) {
processor := &BalancingNodeGroupSetProcessor{Comparator: IsAzureNodeInfoSimilar}
basicSimilarNodeGroupsTest(t, processor)
}
func TestFindSimilarNodeGroupsAzureByLabel(t *testing.T) {
processor := &BalancingNodeGroupSetProcessor{Comparator: IsAzureNodeInfoSimilar}
context := &context.AutoscalingContext{}
n1 := BuildTestNode("n1", 1000, 1000)
n2 := BuildTestNode("n2", 2000, 2000)
provider := testprovider.NewTestCloudProvider(nil, nil)
provider.AddNodeGroup("ng1", 1, 10, 1)
provider.AddNodeGroup("ng2", 1, 10, 1)
provider.AddNode("ng1", n1)
provider.AddNode("ng2", n2)
ni1 := schedulernodeinfo.NewNodeInfo()
ni1.SetNode(n1)
ni2 := schedulernodeinfo.NewNodeInfo()
ni2.SetNode(n2)
nodeInfosForGroups := map[string]*schedulernodeinfo.NodeInfo{
"ng1": ni1, "ng2": ni2,
}
ng1, _ := provider.NodeGroupForNode(n1)
ng2, _ := provider.NodeGroupForNode(n2)
context.CloudProvider = provider
// Groups with different cpu and mem are not similar.
similar, err := processor.FindSimilarNodeGroups(context, ng1, nodeInfosForGroups)
assert.NoError(t, err)
assert.Equal(t, similar, []cloudprovider.NodeGroup{})
// Unless we give them nodepool label.
n1.ObjectMeta.Labels["agentpool"] = "foobar"
n2.ObjectMeta.Labels["agentpool"] = "foobar"
similar, err = processor.FindSimilarNodeGroups(context, ng1, nodeInfosForGroups)
assert.NoError(t, err)
assert.Equal(t, similar, []cloudprovider.NodeGroup{ng2})
// Groups with the same cpu and mem are similar if they belong to different pools.
n3 := BuildTestNode("n1", 1000, 1000)
provider.AddNodeGroup("ng3", 1, 10, 1)
provider.AddNode("ng3", n3)
ni3 := schedulernodeinfo.NewNodeInfo()
ni3.SetNode(n3)
nodeInfosForGroups["ng3"] = ni3
ng3, _ := provider.NodeGroupForNode(n3)
n1.ObjectMeta.Labels["agentpool"] = "foobar1"
n2.ObjectMeta.Labels["agentpool"] = "foobar2"
n3.ObjectMeta.Labels["agentpool"] = "foobar3"
similar, err = processor.FindSimilarNodeGroups(context, ng1, nodeInfosForGroups)
assert.NoError(t, err)
assert.Equal(t, similar, []cloudprovider.NodeGroup{ng3})
}