Skip to content

Commit

Permalink
RFC Implementation Supporting ODCR
Browse files Browse the repository at this point in the history
  • Loading branch information
tvonhacht-apple committed Jul 3, 2024
1 parent 7bc4aad commit b8512cf
Show file tree
Hide file tree
Showing 31 changed files with 1,574 additions and 182 deletions.
1 change: 1 addition & 0 deletions cmd/controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func main() {
op.AMIProvider,
op.LaunchTemplateProvider,
op.InstanceTypesProvider,
op.CapacityReservationProvider,
)...).
WithWebhooks(ctx, webhooks.NewWebhooks()...).
Start(ctx)
Expand Down
270 changes: 270 additions & 0 deletions pkg/apis/crds/karpenter.k8s.aws_ec2nodeclasses.yaml

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions pkg/apis/v1/ec2nodeclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ type EC2NodeClassSpec struct {
// +kubebuilder:validation:Enum:={AL2,AL2023,Bottlerocket,Ubuntu,Custom,Windows2019,Windows2022}
// +required
AMIFamily *string `json:"amiFamily"`
// CapacityReservationSelectorTerms is a list of or Capacity Reservation selector terms. The terms are ORed.
// +kubebuilder:validation:MaxItems:=30
// +optional
CapacityReservationSelectorTerms []CapacityReservationSelectorTerm `json:"capacityReservationSelectorTerms,omitempty" hash:"ignore"`
// UserData to be applied to the provisioned nodes.
// It must be in the appropriate format based on the AMIFamily in use. Karpenter will merge certain fields into
// this UserData to ensure nodes are being provisioned with the correct configuration.
Expand Down Expand Up @@ -175,6 +179,44 @@ type AMISelectorTerm struct {
Owner string `json:"owner,omitempty"`
}

// CapacityReservationSelectorTerm defines selection logic for a Capacity Reservation used by Karpenter to launch nodes.
// If multiple fields are used for selection, the requirements are ANDed.
type CapacityReservationSelectorTerm struct {
// The Availability Zone of the Capacity Reservation
// +optional
AvailabilityZone string `json:"availabilityZone,omitempty"`
// The platform of operating system for which the Capacity Reservation reserves capacity
// +optional
ID string `json:"id,omitempty"`
// The type of operating system for which the Capacity Reservation reserves capacity
// +optional
InstanceType string `json:"instanceType,omitempty"`
// Tags is a map of key/value tags used to select subnets
// Specifying '*' for a value selects all values for a given tag key.
// +kubebuilder:validation:XValidation:message="empty tag keys or values aren't supported",rule="self.all(k, k != '' && self[k] != '')"
// +kubebuilder:validation:MaxProperties:=20
// +optional
Tags map[string]string `json:"tags,omitempty"`
// Indicates the type of instance launches that the Capacity Reservation accepts. The options include:
// - open:
// The Capacity Reservation accepts all instances that have
// matching attributes (instance type, platform, and Availability
// Zone). Instances that have matching attributes launch into the
// Capacity Reservation automatically without specifying any
// additional parameters.
// - targeted:
// The Capacity Reservation only accepts instances that
// have matching attributes (instance type, platform, and
// Availability Zone), and explicitly target the Capacity
// Reservation. This ensures that only permitted instances can use
// the reserved capacity.
// +optional
Type string `json:"type,omitempty"`
// The ID of the Amazon Web Services account that owns the Capacity Reservation
// +optional
OwnerID string `json:"ownerId,omitempty"`
}

// MetadataOptions contains parameters for specifying the exposure of the
// Instance Metadata Service to provisioned EC2 nodes.
type MetadataOptions struct {
Expand Down
63 changes: 63 additions & 0 deletions pkg/apis/v1/ec2nodeclass_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,71 @@ type AMI struct {
Requirements []v1.NodeSelectorRequirement `json:"requirements"`
}

// CapacityReservation contains resolved Capacity Reservation selector values utilized for node launch
type CapacityReservation struct {
// ID of the Capacity Reservation
// +required
ID string `json:"id"`
// AvailabilityZone of the Capacity Reservation
// +required
AvailabilityZone string `json:"availabilityZone"`
// Available Instance Count of the Capacity Reservation
// +required
AvailableInstanceCount int `json:"availableInstanceCount"`
// The date and time at which the Capacity Reservation expires. When a Capacity
// Reservation expires, the reserved capacity is released and you can no longer
// launch instances into it. The Capacity Reservation's state changes to expired
// when it reaches its end date and time.
// +optional
EndDate *string `json:"endDate,omitempty"`
// Indicates the way in which the Capacity Reservation ends. A Capacity Reservation
// can have one of the following end types:
//
// * unlimited - The Capacity Reservation remains active until you explicitly
// cancel it.
//
// * limited - The Capacity Reservation expires automatically at a specified
// date and time.
// +required
EndDateType string `json:"endDateType"`
// Indicates the type of instance launches that the Capacity Reservation accepts. The options include:
// - open:
// The Capacity Reservation accepts all instances that have
// matching attributes (instance type, platform, and Availability
// Zone). Instances that have matching attributes launch into the
// Capacity Reservation automatically without specifying any
// additional parameters.
// - targeted:
// The Capacity Reservation only accepts instances that
// have matching attributes (instance type, platform, and
// Availability Zone), and explicitly target the Capacity
// Reservation. This ensures that only permitted instances can use
// the reserved capacity.
// +required
InstanceMatchCriteria string `json:"instanceMatchCriteria"`
// Instance Platform of the Capacity Reservation
// +required
InstancePlatform string `json:"instancePlatform"`
// Instance Type of the Capacity Reservation
// +required
InstanceType string `json:"instanceType"`
// Owner Id of the Capacity Reservation
// +required
OwnerID string `json:"ownerId"`
// The date and time at which the Capacity Reservation was started.
// +required
StartDate string `json:"startDate"`
// Total Instance Count of the Capacity Reservation
// +required
TotalInstanceCount int `json:"totalInstanceCount"`
}

// EC2NodeClassStatus contains the resolved state of the EC2NodeClass
type EC2NodeClassStatus struct {
// CapacityReservations contains the current Capacity Reservations values that are available to the
// cluster under the CapacityReservations selectors.
// +optional
CapacityReservations []CapacityReservation `json:"capacityReservations,omitempty"`
// Subnets contains the current Subnet values that are available to the
// cluster under the subnet selectors.
// +optional
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/v1/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
func init() {
v1beta1.RestrictedLabelDomains = v1beta1.RestrictedLabelDomains.Insert(RestrictedLabelDomains...)
v1beta1.WellKnownLabels = v1beta1.WellKnownLabels.Insert(
LabelCapactiyReservationID,
LabelInstanceHypervisor,
LabelInstanceEncryptionInTransitSupported,
LabelInstanceCategory,
Expand Down Expand Up @@ -119,6 +120,7 @@ var (
AnnotationEC2NodeClassHash = Group + "/ec2nodeclass-hash"
AnnotationEC2NodeClassHashVersion = Group + "/ec2nodeclass-hash-version"
AnnotationInstanceTagged = Group + "/tagged"
LabelCapactiyReservationID = Group + "/capacity-reservation-id"

TagNodeClaim = v1beta1.Group + "/nodeclaim"
TagManagedLaunchTemplate = Group + "/cluster"
Expand Down
56 changes: 56 additions & 0 deletions pkg/apis/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 42 additions & 0 deletions pkg/apis/v1beta1/ec2nodeclass.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ type EC2NodeClassSpec struct {
// +kubebuilder:validation:Enum:={AL2,AL2023,Bottlerocket,Ubuntu,Custom,Windows2019,Windows2022}
// +required
AMIFamily *string `json:"amiFamily"`
// CapacityReservationSelectorTerms is a list of or Capacity Reservation selector terms. The terms are ORed.
// +kubebuilder:validation:MaxItems:=30
// +optional
CapacityReservationSelectorTerms []CapacityReservationSelectorTerm `json:"capacityReservationSelectorTerms,omitempty" hash:"ignore"`
// UserData to be applied to the provisioned nodes.
// It must be in the appropriate format based on the AMIFamily in use. Karpenter will merge certain fields into
// this UserData to ensure nodes are being provisioned with the correct configuration.
Expand Down Expand Up @@ -175,6 +179,44 @@ type AMISelectorTerm struct {
Owner string `json:"owner,omitempty"`
}

// CapacityReservationSelectorTerm defines selection logic for a Capacity Reservation used by Karpenter to launch nodes.
// If multiple fields are used for selection, the requirements are ANDed.
type CapacityReservationSelectorTerm struct {
// The Availability Zone of the Capacity Reservation
// +optional
AvailabilityZone string `json:"availabilityZone,omitempty"`
// The platform of operating system for which the Capacity Reservation reserves capacity
// +optional
ID string `json:"id,omitempty"`
// The type of operating system for which the Capacity Reservation reserves capacity
// +optional
InstanceType string `json:"instanceType,omitempty"`
// Tags is a map of key/value tags used to select subnets
// Specifying '*' for a value selects all values for a given tag key.
// +kubebuilder:validation:XValidation:message="empty tag keys or values aren't supported",rule="self.all(k, k != '' && self[k] != '')"
// +kubebuilder:validation:MaxProperties:=20
// +optional
Tags map[string]string `json:"tags,omitempty"`
// Indicates the type of instance launches that the Capacity Reservation accepts. The options include:
// - open:
// The Capacity Reservation accepts all instances that have
// matching attributes (instance type, platform, and Availability
// Zone). Instances that have matching attributes launch into the
// Capacity Reservation automatically without specifying any
// additional parameters.
// - targeted:
// The Capacity Reservation only accepts instances that
// have matching attributes (instance type, platform, and
// Availability Zone), and explicitly target the Capacity
// Reservation. This ensures that only permitted instances can use
// the reserved capacity.
// +optional
Type string `json:"type,omitempty"`
// The ID of the Amazon Web Services account that owns the Capacity Reservation
// +optional
OwnerID string `json:"ownerId,omitempty"`
}

// MetadataOptions contains parameters for specifying the exposure of the
// Instance Metadata Service to provisioned EC2 nodes.
type MetadataOptions struct {
Expand Down
63 changes: 63 additions & 0 deletions pkg/apis/v1beta1/ec2nodeclass_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,65 @@ type SecurityGroup struct {
Name string `json:"name,omitempty"`
}

// CapacityReservation contains resolved Capacity Reservation selector values utilized for node launch
type CapacityReservation struct {
// ID of the Capacity Reservation
// +required
ID string `json:"id"`
// AvailabilityZone of the Capacity Reservation
// +required
AvailabilityZone string `json:"availabilityZone"`
// Available Instance Count of the Capacity Reservation
// +required
AvailableInstanceCount int `json:"availableInstanceCount"`
// The date and time at which the Capacity Reservation expires. When a Capacity
// Reservation expires, the reserved capacity is released and you can no longer
// launch instances into it. The Capacity Reservation's state changes to expired
// when it reaches its end date and time.
// +optional
EndDate *string `json:"endDate,omitempty"`
// Indicates the way in which the Capacity Reservation ends. A Capacity Reservation
// can have one of the following end types:
//
// * unlimited - The Capacity Reservation remains active until you explicitly
// cancel it.
//
// * limited - The Capacity Reservation expires automatically at a specified
// date and time.
// +required
EndDateType string `json:"endDateType"`
// Indicates the type of instance launches that the Capacity Reservation accepts. The options include:
// - open:
// The Capacity Reservation accepts all instances that have
// matching attributes (instance type, platform, and Availability
// Zone). Instances that have matching attributes launch into the
// Capacity Reservation automatically without specifying any
// additional parameters.
// - targeted:
// The Capacity Reservation only accepts instances that
// have matching attributes (instance type, platform, and
// Availability Zone), and explicitly target the Capacity
// Reservation. This ensures that only permitted instances can use
// the reserved capacity.
// +required
InstanceMatchCriteria string `json:"instanceMatchCriteria"`
// Instance Platform of the Capacity Reservation
// +required
InstancePlatform string `json:"instancePlatform"`
// Instance Type of the Capacity Reservation
// +required
InstanceType string `json:"instanceType"`
// Owner Id of the Capacity Reservation
// +required
OwnerID string `json:"ownerId"`
// The date and time at which the Capacity Reservation was started.
// +required
StartDate string `json:"startDate"`
// Total Instance Count of the Capacity Reservation
// +required
TotalInstanceCount int `json:"totalInstanceCount"`
}

// AMI contains resolved AMI selector values utilized for node launch
type AMI struct {
// ID of the AMI
Expand All @@ -57,6 +116,10 @@ type AMI struct {

// EC2NodeClassStatus contains the resolved state of the EC2NodeClass
type EC2NodeClassStatus struct {
// CapacityReservations contains the current Capacity Reservations values that are available to the
// cluster under the CapacityReservations selectors.
// +optional
CapacityReservations []CapacityReservation `json:"capacityReservations,omitempty"`
// Subnets contains the current Subnet values that are available to the
// cluster under the subnet selectors.
// +optional
Expand Down
Loading

0 comments on commit b8512cf

Please sign in to comment.