NAP interface implementation - part 1
This commit is contained in:
parent
21c575f0ac
commit
ac2c471eb1
|
|
@ -213,6 +213,11 @@ func (asg *Asg) Create() error {
|
|||
return cloudprovider.ErrAlreadyExist
|
||||
}
|
||||
|
||||
// Autoprovisioned returns true if the node group is autoprovisioned.
|
||||
func (asg *Asg) Autoprovisioned() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Delete deletes the node group on the cloud provider side.
|
||||
// This will be executed only for autoprovisioned node groups, once their size drops to 0.
|
||||
func (asg *Asg) Delete() error {
|
||||
|
|
|
|||
|
|
@ -119,6 +119,10 @@ type NodeGroup interface {
|
|||
// This will be executed only for autoprovisioned node groups, once their size drops to 0.
|
||||
// Implementation optional.
|
||||
Delete() error
|
||||
|
||||
// Autoprovisioned returns true if the node group is autoprovisioned. An autoprovisioned group
|
||||
// was created by CA and can be deleted when scaled to 0.
|
||||
Autoprovisioned() bool
|
||||
}
|
||||
|
||||
// PricingModel contains information about the node price and how it changes in time.
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ import (
|
|||
"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"
|
||||
)
|
||||
|
||||
const (
|
||||
maxAutoprovisionedSize = 1000
|
||||
minAutoprovisionedSize = 0
|
||||
)
|
||||
|
||||
// GceCloudProvider implements CloudProvider interface.
|
||||
type GceCloudProvider struct {
|
||||
gceManager *GceManager
|
||||
|
|
@ -131,6 +136,7 @@ type Mig struct {
|
|||
|
||||
minSize int
|
||||
maxSize int
|
||||
autoprovisioned bool
|
||||
}
|
||||
|
||||
// MaxSize returns maximum size of the node group.
|
||||
|
|
@ -266,6 +272,11 @@ func (mig *Mig) Delete() error {
|
|||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
// Autoprovisioned returns true if the node group is autoprovisioned.
|
||||
func (mig *Mig) Autoprovisioned() bool {
|
||||
return mig.autoprovisioned
|
||||
}
|
||||
|
||||
// TemplateNodeInfo returns a node template for this node group.
|
||||
func (mig *Mig) TemplateNodeInfo() (*schedulercache.NodeInfo, error) {
|
||||
template, err := mig.gceManager.getMigTemplate(mig)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ import (
|
|||
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
|
||||
"cloud.google.com/go/compute/metadata"
|
||||
provider_gce "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
|
||||
)
|
||||
|
||||
|
|
@ -59,6 +61,8 @@ type GceManager struct {
|
|||
|
||||
service *gce.Service
|
||||
cacheMutex sync.Mutex
|
||||
zone string
|
||||
projectId string
|
||||
}
|
||||
|
||||
// CreateGceManager constructs gceManager object.
|
||||
|
|
@ -80,6 +84,11 @@ func CreateGceManager(configReader io.Reader) (*GceManager, error) {
|
|||
} else {
|
||||
glog.Infof("Using default TokenSource %#v", tokenSource)
|
||||
}
|
||||
projectId, zone, err := getProjectAndZone()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
glog.V(1).Infof("GCE projectId=%s zone=%s", projectId, zone)
|
||||
|
||||
// Create Google Compute Engine service.
|
||||
client := oauth2.NewClient(oauth2.NoContext, tokenSource)
|
||||
|
|
@ -91,6 +100,8 @@ func CreateGceManager(configReader io.Reader) (*GceManager, error) {
|
|||
migs: make([]*migInformation, 0),
|
||||
service: gceService,
|
||||
migCache: make(map[GceRef]*Mig),
|
||||
zone: zone,
|
||||
projectId: projectId,
|
||||
}
|
||||
go wait.Forever(func() {
|
||||
manager.cacheMutex.Lock()
|
||||
|
|
@ -286,6 +297,17 @@ func (m *GceManager) getMigTemplate(mig *Mig) (*gce.InstanceTemplate, error) {
|
|||
return instanceTemplate, nil
|
||||
}
|
||||
|
||||
func (m *GceManager) getCpuAndMemoryForMachineType(machineType string) (cpu int64, mem int64, err error) {
|
||||
if strings.HasPrefix(machineType, "custom-") {
|
||||
return parseCustomMachineType(machineType)
|
||||
}
|
||||
machine, geterr := m.service.MachineTypes.Get(m.projectId, m.zone, machineType).Do()
|
||||
if geterr != nil {
|
||||
return 0, 0, geterr
|
||||
}
|
||||
return machine.GuestCpus, machine.MemoryMb * 1024 * 1024, nil
|
||||
}
|
||||
|
||||
func (m *GceManager) buildNodeFromTemplate(mig *Mig, template *gce.InstanceTemplate) (*apiv1.Node, error) {
|
||||
|
||||
if template.Properties == nil {
|
||||
|
|
@ -304,25 +326,16 @@ func (m *GceManager) buildNodeFromTemplate(mig *Mig, template *gce.InstanceTempl
|
|||
Capacity: apiv1.ResourceList{},
|
||||
}
|
||||
// TODO: get a real value.
|
||||
// TODO: handle GPU
|
||||
|
||||
node.Status.Capacity[apiv1.ResourcePods] = *resource.NewQuantity(110, resource.DecimalSI)
|
||||
|
||||
// TODO: handle custom !!!!
|
||||
// TODO: handle GPU
|
||||
if strings.HasPrefix(template.Properties.MachineType, "custom-") {
|
||||
cpu, mem, err := parseCustomMachineType(template.Properties.MachineType)
|
||||
cpu, mem, err := m.getCpuAndMemoryForMachineType(template.Properties.MachineType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node.Status.Capacity[apiv1.ResourceCPU] = *resource.NewQuantity(cpu, resource.DecimalSI)
|
||||
node.Status.Capacity[apiv1.ResourceMemory] = *resource.NewQuantity(mem, resource.DecimalSI)
|
||||
} else {
|
||||
machineType, err := m.service.MachineTypes.Get(mig.Project, mig.Zone, template.Properties.MachineType).Do()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node.Status.Capacity[apiv1.ResourceCPU] = *resource.NewQuantity(machineType.GuestCpus, resource.DecimalSI)
|
||||
node.Status.Capacity[apiv1.ResourceMemory] = *resource.NewQuantity(machineType.MemoryMb*1024*1024, resource.DecimalSI)
|
||||
}
|
||||
|
||||
// TODO: use proper allocatable!!
|
||||
node.Status.Allocatable = node.Status.Capacity
|
||||
|
|
@ -450,3 +463,21 @@ func buildTaints(kubeEnvTaints map[string]string) ([]apiv1.Taint, error) {
|
|||
}
|
||||
return taints, nil
|
||||
}
|
||||
|
||||
// Code borrowed from gce cloud provider. Reuse the original as soon as it becomes public.
|
||||
func getProjectAndZone() (string, string, error) {
|
||||
result, err := metadata.Get("instance/zone")
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
parts := strings.Split(result, "/")
|
||||
if len(parts) != 4 {
|
||||
return "", "", fmt.Errorf("unexpected response: %s", result)
|
||||
}
|
||||
zone := parts[3]
|
||||
projectID, err := metadata.ProjectID()
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return projectID, zone, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,6 +239,11 @@ func (nodeGroup *NodeGroup) Delete() error {
|
|||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
// Autoprovisioned returns true if the node group is autoprovisioned.
|
||||
func (nodeGroup *NodeGroup) Autoprovisioned() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func buildNodeGroup(value string, kubemarkController *kubemark.KubemarkController) (*NodeGroup, error) {
|
||||
spec, err := dynamic.SpecFromString(value, true)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -25,19 +25,23 @@ import (
|
|||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/autoscaler/cluster-autoscaler/cloudprovider"
|
||||
"k8s.io/autoscaler/cluster-autoscaler/utils/errors"
|
||||
"k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache"
|
||||
)
|
||||
|
||||
const (
|
||||
// ProviderName is the cloud provider name for kubemark
|
||||
ProviderName = "kubemark"
|
||||
)
|
||||
|
||||
type KubemarkCloudProvider struct{}
|
||||
|
||||
func BuildKubemarkCloudProvider(kubemarkController *kubemark.KubemarkController, specs []string) (*KubemarkCloudProvider, error) {
|
||||
func BuildKubemarkCloudProvider(kubemarkController interface{}, specs []string) (*KubemarkCloudProvider, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (kubemark *KubemarkCloudProvider) Name() string { return "" }
|
||||
|
||||
func (kubemark *KubemarkCloudProvider) NodeGroups() []cloudprovider.NodeGroup {
|
||||
return []cloudProvider.NodeGroup{}
|
||||
return []cloudprovider.NodeGroup{}
|
||||
}
|
||||
|
||||
func (kubemark *KubemarkCloudProvider) Pricing() (cloudprovider.PricingModel, errors.AutoscalerError) {
|
||||
|
|
@ -55,21 +59,3 @@ func (kubemark *KubemarkCloudProvider) GetAvilableMachineTypes() ([]string, erro
|
|||
func (kubemark *KubemarkCloudProvider) NewNodeGroup(name string, machineType string, labels map[string]string, extraResources map[string]resource.Quantity) (cloudprovider.NodeGroup, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
type FakeNodeGroup struct{}
|
||||
|
||||
func (f *FakeNodeGroup) Id() string { return "" }
|
||||
func (f *FakeNodeGroup) MinSize() int { return 0 }
|
||||
func (f *FakeNodeGroup) MaxSize() int { return 0 }
|
||||
func (f *FakeNodeGroup) Debug() string { return "" }
|
||||
func (f *FakeNodeGroup) Nodes() ([]string, error) { return []string{}, cloudprovider.ErrNotImplemented }
|
||||
func (f *FakeNodeGroup) DeleteNodes(nodes []*apiv1.Node) error { return cloudprovider.ErrNotImplemented }
|
||||
func (f *FakeNodeGroup) IncreaseSize(delta int) error { return cloudprovider.ErrNotImplemented }
|
||||
func (f *FakeNodeGroup) TargetSize() (int, error) { return 0, cloudprovider.ErrNotImplemented }
|
||||
func (f *FakeNodeGroup) DecreaseTargetSize(delta int) error { return cloudprovider.ErrNotImplemented }
|
||||
func (f *FakeNodeGroup) TemplateNodeInfo() (*schedulercache.NodeInfo, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
func (f *FakeNodeGroup) Exist() (bool, error) { return true, nil }
|
||||
func (f *FakeNodeGroup) Create() error { return cloudprovider.ErrNotImplemented }
|
||||
func (f *FakeNodeGroup) Delete() error { return cloudprovider.ErrNotImplemented }
|
||||
|
|
|
|||
|
|
@ -248,6 +248,11 @@ func (tng *TestNodeGroup) Nodes() ([]string, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
// Autoprovisioned returns true if the node group is autoprovisioned.
|
||||
func (tng *TestNodeGroup) Autoprovisioned() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// TemplateNodeInfo returns a node template for this node group.
|
||||
func (tng *TestNodeGroup) TemplateNodeInfo() (*schedulercache.NodeInfo, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ func (f *FakeNodeGroup) TemplateNodeInfo() (*schedulercache.NodeInfo, error) {
|
|||
func (f *FakeNodeGroup) Exist() (bool, error) { return true, nil }
|
||||
func (f *FakeNodeGroup) Create() error { return cloudprovider.ErrAlreadyExist }
|
||||
func (f *FakeNodeGroup) Delete() error { return cloudprovider.ErrNotImplemented }
|
||||
func (f *FakeNodeGroup) Autoprovisioned() bool { return false }
|
||||
|
||||
func makeNodeInfo(cpu int64, memory int64, pods int64) *schedulercache.NodeInfo {
|
||||
node := &apiv1.Node{
|
||||
|
|
|
|||
Loading…
Reference in New Issue