Skip to content

Commit

Permalink
PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathan-innis committed Sep 30, 2024
1 parent 027ed24 commit d1a7038
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 43 deletions.
32 changes: 14 additions & 18 deletions pkg/providers/instancetype/instancetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log"
karpv1 "sigs.k8s.io/karpenter/pkg/apis/v1"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
"github.com/samber/lo"
Expand Down Expand Up @@ -99,7 +98,7 @@ func (p *DefaultProvider) List(ctx context.Context, nodeClass *v1.EC2NodeClass)
}

subnetZones := sets.New(lo.Map(nodeClass.Status.Subnets, func(s v1.Subnet, _ int) string {
return aws.StringValue(&s.Zone)
return lo.FromPtr(&s.Zone)
})...)

// Compute fully initialized instance types hash key
Expand Down Expand Up @@ -131,16 +130,16 @@ func (p *DefaultProvider) List(ctx context.Context, nodeClass *v1.EC2NodeClass)
subnetZoneToID := lo.SliceToMap(nodeClass.Status.Subnets, func(s v1.Subnet) (string, string) {
return s.Zone, s.ZoneID
})
result := lo.FilterMap(p.instanceTypesInfo, func(i *ec2.InstanceTypeInfo, _ int) (*cloudprovider.InstanceType, bool) {
result := lo.Map(p.instanceTypesInfo, func(i *ec2.InstanceTypeInfo, _ int) *cloudprovider.InstanceType {
instanceTypeVCPU.With(prometheus.Labels{
instanceTypeLabel: *i.InstanceType,
}).Set(float64(aws.Int64Value(i.VCpuInfo.DefaultVCpus)))
}).Set(float64(lo.FromPtr(i.VCpuInfo.DefaultVCpus)))
instanceTypeMemory.With(prometheus.Labels{
instanceTypeLabel: *i.InstanceType,
}).Set(float64(aws.Int64Value(i.MemoryInfo.SizeInMiB) * 1024 * 1024))
}).Set(float64(lo.FromPtr(i.MemoryInfo.SizeInMiB) * 1024 * 1024))

zoneData := lo.Map(allZones.UnsortedList(), func(zoneName string, _ int) ZoneData {
if !p.instanceTypesOfferings[aws.StringValue(i.InstanceType)].Has(zoneName) || !subnetZones.Has(zoneName) {
if !p.instanceTypesOfferings[lo.FromPtr(i.InstanceType)].Has(zoneName) || !subnetZones.Has(zoneName) {
return ZoneData{
Name: zoneName,
Available: false,
Expand All @@ -154,9 +153,6 @@ func (p *DefaultProvider) List(ctx context.Context, nodeClass *v1.EC2NodeClass)
})

it := p.instanceTypesResolver.Resolve(ctx, i, zoneData, nodeClass)
if it == nil {
return nil, false
}
for _, of := range it.Offerings {
instanceTypeOfferingAvailable.With(prometheus.Labels{
instanceTypeLabel: it.Name,
Expand All @@ -169,7 +165,7 @@ func (p *DefaultProvider) List(ctx context.Context, nodeClass *v1.EC2NodeClass)
zoneLabel: of.Requirements.Get(corev1.LabelTopologyZone).Any(),
}).Set(of.Price)
}
return it, true
return it
})
p.instanceTypesCache.SetDefault(key, result)
return result, nil
Expand All @@ -187,12 +183,12 @@ func (p *DefaultProvider) UpdateInstanceTypes(ctx context.Context) error {
if err := p.ec2api.DescribeInstanceTypesPagesWithContext(ctx, &ec2.DescribeInstanceTypesInput{
Filters: []*ec2.Filter{
{
Name: aws.String("supported-virtualization-type"),
Values: []*string{aws.String("hvm")},
Name: lo.ToPtr("supported-virtualization-type"),
Values: lo.ToSlicePtr([]string{"hvm"}),
},
{
Name: aws.String("processor-info.supported-architecture"),
Values: aws.StringSlice([]string{"x86_64", "arm64"}),
Name: lo.ToPtr("processor-info.supported-architecture"),
Values: lo.ToSlicePtr([]string{"x86_64", "arm64"}),
},
},
}, func(page *ec2.DescribeInstanceTypesOutput, lastPage bool) bool {
Expand Down Expand Up @@ -224,13 +220,13 @@ func (p *DefaultProvider) UpdateInstanceTypeOfferings(ctx context.Context) error

// Get offerings from EC2
instanceTypeOfferings := map[string]sets.Set[string]{}
if err := p.ec2api.DescribeInstanceTypeOfferingsPagesWithContext(ctx, &ec2.DescribeInstanceTypeOfferingsInput{LocationType: aws.String("availability-zone")},
if err := p.ec2api.DescribeInstanceTypeOfferingsPagesWithContext(ctx, &ec2.DescribeInstanceTypeOfferingsInput{LocationType: lo.ToPtr("availability-zone")},
func(output *ec2.DescribeInstanceTypeOfferingsOutput, lastPage bool) bool {
for _, offering := range output.InstanceTypeOfferings {
if _, ok := instanceTypeOfferings[aws.StringValue(offering.InstanceType)]; !ok {
instanceTypeOfferings[aws.StringValue(offering.InstanceType)] = sets.New[string]()
if _, ok := instanceTypeOfferings[lo.FromPtr(offering.InstanceType)]; !ok {
instanceTypeOfferings[lo.FromPtr(offering.InstanceType)] = sets.New[string]()
}
instanceTypeOfferings[aws.StringValue(offering.InstanceType)].Insert(aws.StringValue(offering.Location))
instanceTypeOfferings[lo.FromPtr(offering.InstanceType)].Insert(lo.FromPtr(offering.Location))
}
return true
}); err != nil {
Expand Down
49 changes: 24 additions & 25 deletions pkg/providers/instancetype/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ type ZoneData struct {
}

type Resolver interface {
// CacheKey tells the InstanceType cache if something changes about the InstanceTypes or Offerings without it being known externally.
// You do not need to use anything in the input data to generate the key here since that will automatically refresh the cache
// CacheKey tells the InstanceType cache if something changes about the InstanceTypes or Offerings based on the NodeClass.
CacheKey(nodeClass *v1.EC2NodeClass) string
// Resolve generates an InstanceType based on raw InstanceTypeInfo and NodeClass setting data
Resolve(ctx context.Context, info *ec2.InstanceTypeInfo, zoneData []ZoneData, nodeClass *v1.EC2NodeClass) *cloudprovider.InstanceType
Expand Down Expand Up @@ -109,29 +108,6 @@ func (d *DefaultResolver) Resolve(ctx context.Context, info *ec2.InstanceTypeInf
kc.SystemReserved, kc.EvictionHard, kc.EvictionSoft, nodeClass.AMIFamily(), d.createOfferings(ctx, info, zoneData))
}

func NewInstanceType(ctx context.Context, info *ec2.InstanceTypeInfo, region string,
blockDeviceMappings []*v1.BlockDeviceMapping, instanceStorePolicy *v1.InstanceStorePolicy, maxPods *int32, podsPerCore *int32,
kubeReserved map[string]string, systemReserved map[string]string, evictionHard map[string]string, evictionSoft map[string]string,
amiFamilyType string, offerings cloudprovider.Offerings) *cloudprovider.InstanceType {

amiFamily := amifamily.GetAMIFamily(amiFamilyType, &amifamily.Options{})
it := &cloudprovider.InstanceType{
Name: aws.StringValue(info.InstanceType),
Requirements: computeRequirements(info, offerings, region, amiFamily),
Offerings: offerings,
Capacity: computeCapacity(ctx, info, amiFamily, blockDeviceMappings, instanceStorePolicy, maxPods, podsPerCore),
Overhead: &cloudprovider.InstanceTypeOverhead{
KubeReserved: kubeReservedResources(cpu(info), pods(ctx, info, amiFamily, maxPods, podsPerCore), ENILimitedPods(ctx, info), amiFamily, kubeReserved),
SystemReserved: systemReservedResources(systemReserved),
EvictionThreshold: evictionThreshold(memory(ctx, info), ephemeralStorage(info, amiFamily, blockDeviceMappings, instanceStorePolicy), amiFamily, evictionHard, evictionSoft),
},
}
if it.Requirements.Compatible(scheduling.NewRequirements(scheduling.NewRequirement(corev1.LabelOSStable, corev1.NodeSelectorOpIn, string(corev1.Windows)))) == nil {
it.Capacity[v1.ResourcePrivateIPv4Address] = *privateIPv4Address(aws.StringValue(info.InstanceType))
}
return it
}

// createOfferings creates a set of mutually exclusive offerings for a given instance type. This provider maintains an
// invariant that each offering is mutually exclusive. Specifically, there is an offering for each permutation of zone
// and capacity type. ZoneID is also injected into the offering requirements, when available, but there is a 1-1
Expand Down Expand Up @@ -180,6 +156,29 @@ func (d *DefaultResolver) createOfferings(ctx context.Context, instanceType *ec2
return offerings
}

func NewInstanceType(ctx context.Context, info *ec2.InstanceTypeInfo, region string,
blockDeviceMappings []*v1.BlockDeviceMapping, instanceStorePolicy *v1.InstanceStorePolicy, maxPods *int32, podsPerCore *int32,
kubeReserved map[string]string, systemReserved map[string]string, evictionHard map[string]string, evictionSoft map[string]string,
amiFamilyType string, offerings cloudprovider.Offerings) *cloudprovider.InstanceType {

amiFamily := amifamily.GetAMIFamily(amiFamilyType, &amifamily.Options{})
it := &cloudprovider.InstanceType{
Name: aws.StringValue(info.InstanceType),
Requirements: computeRequirements(info, offerings, region, amiFamily),
Offerings: offerings,
Capacity: computeCapacity(ctx, info, amiFamily, blockDeviceMappings, instanceStorePolicy, maxPods, podsPerCore),
Overhead: &cloudprovider.InstanceTypeOverhead{
KubeReserved: kubeReservedResources(cpu(info), pods(ctx, info, amiFamily, maxPods, podsPerCore), ENILimitedPods(ctx, info), amiFamily, kubeReserved),
SystemReserved: systemReservedResources(systemReserved),
EvictionThreshold: evictionThreshold(memory(ctx, info), ephemeralStorage(info, amiFamily, blockDeviceMappings, instanceStorePolicy), amiFamily, evictionHard, evictionSoft),
},
}
if it.Requirements.Compatible(scheduling.NewRequirements(scheduling.NewRequirement(corev1.LabelOSStable, corev1.NodeSelectorOpIn, string(corev1.Windows)))) == nil {
it.Capacity[v1.ResourcePrivateIPv4Address] = *privateIPv4Address(aws.StringValue(info.InstanceType))
}
return it
}

//nolint:gocyclo
func computeRequirements(info *ec2.InstanceTypeInfo, offerings cloudprovider.Offerings, region string, amiFamily amifamily.AMIFamily) scheduling.Requirements {
requirements := scheduling.NewRequirements(
Expand Down

0 comments on commit d1a7038

Please sign in to comment.