Skip to content

Commit c350073

Browse files
author
jwcesign
authored
Merge pull request #44 from daimaxiaxie/impl-launch-template-provider-ensure-all
implement LaunchTemplateProvider.EnsureAll
2 parents 4f3842b + e6bd8de commit c350073

File tree

19 files changed

+2749
-6727
lines changed

19 files changed

+2749
-6727
lines changed

config/components/crds/karpenter.k8s.alicloud_ecsnodeclasses.yaml

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,73 @@ spec:
278278
- message: '''name'' is mutually exclusive, cannot be set with a combination
279279
of other fields in securityGroupSelectorTerms'
280280
rule: '!self.all(x, has(x.name) && (has(x.tags) || has(x.id)))'
281+
systemDisk:
282+
description: SystemDisk to be applied to provisioned nodes.
283+
properties:
284+
autoSnapshotPolicyId:
285+
description: The ID of the automatic snapshot policy to apply
286+
to the system disk.
287+
type: string
288+
burstingEnabled:
289+
description: Specifies whether to enable the performance burst
290+
feature for the system disk
291+
type: boolean
292+
category:
293+
description: |-
294+
The category of the system disk (for example, cloud or cloud_ssd).
295+
Only one of the following: "cloud", "cloud_efficiency", "cloud_ssd", "cloud_essd", "cloud_auto", and "cloud_essd_entry"
296+
enum:
297+
- cloud
298+
- cloud_efficiency
299+
- cloud_ssd
300+
- cloud_essd
301+
- cloud_auto
302+
- cloud_essd_entry
303+
type: string
304+
diskName:
305+
description: |-
306+
The name of the system disk.
307+
The name must be 2 to 128 characters in length.
308+
The name must start with a letter and cannot start with http:// or https://.
309+
The name can contain letters, digits, colons (:), underscores (_), and hyphens (-).
310+
pattern: ^[A-Za-z][A-Za-z0-9:_-]*$
311+
type: string
312+
x-kubernetes-validations:
313+
- message: format invalid
314+
rule: '!self.startsWith(''http'') && self.size() >= 2 && self.size()
315+
<= 128'
316+
performanceLevel:
317+
description: |-
318+
The performance level of the ESSD to use as the system disk. Default value: PL0.
319+
Valid values:
320+
* PL0: A single ESSD can deliver up to 10,000 random read/write IOPS.
321+
* PL1: A single ESSD can deliver up to 50,000 random read/write IOPS.
322+
* PL2: A single ESSD can deliver up to 100,000 random read/write IOPS.
323+
* PL3: A single ESSD can deliver up to 1,000,000 random read/write IOPS.
324+
enum:
325+
- PL0
326+
- PL1
327+
- PL2
328+
- PL3
329+
type: string
330+
size:
331+
description: |-
332+
The size of the system disk. Unit: GiB.
333+
Valid values:
334+
* If you set Category to cloud: 20 to 500.
335+
* If you set Category to other disk categories: 20 to 2048.
336+
format: int32
337+
type: integer
338+
x-kubernetes-validations:
339+
- message: size invalid
340+
rule: self >= 20
341+
type: object
342+
userData:
343+
description: |-
344+
UserData to be applied to the provisioned nodes.
345+
It must be in the appropriate format based on the AMIFamily in use. Karpenter will merge certain fields into
346+
this UserData to ensure nodes are being provisioned with the correct configuration.
347+
type: string
281348
vSwitchSelectorTerms:
282349
description: VSwitchSelectorTerms is a list of or vSwitch selector
283350
terms. The terms are ORed.
@@ -376,6 +443,57 @@ spec:
376443
- type
377444
type: object
378445
type: array
446+
images:
447+
description: |-
448+
Image contains the current image that are available to the
449+
cluster under the Image selectors.
450+
items:
451+
description: Image contains resolved image selector values utilized
452+
for node launch
453+
properties:
454+
id:
455+
description: ID of the Image
456+
type: string
457+
name:
458+
description: Name of the Image
459+
type: string
460+
requirements:
461+
description: Requirements of the Image to be utilized on an
462+
instance type
463+
items:
464+
description: |-
465+
A node selector requirement is a selector that contains values, a key, and an operator
466+
that relates the key and values.
467+
properties:
468+
key:
469+
description: The label key that the selector applies to.
470+
type: string
471+
operator:
472+
description: |-
473+
Represents a key's relationship to a set of values.
474+
Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
475+
type: string
476+
values:
477+
description: |-
478+
An array of string values. If the operator is In or NotIn,
479+
the values array must be non-empty. If the operator is Exists or DoesNotExist,
480+
the values array must be empty. If the operator is Gt or Lt, the values
481+
array must have a single element, which will be interpreted as an integer.
482+
This array is replaced during a strategic merge patch.
483+
items:
484+
type: string
485+
type: array
486+
x-kubernetes-list-type: atomic
487+
required:
488+
- key
489+
- operator
490+
type: object
491+
type: array
492+
required:
493+
- id
494+
- requirements
495+
type: object
496+
type: array
379497
securityGroups:
380498
description: |-
381499
SecurityGroups contains the current Security Groups values that are available to the

go.mod

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.23
44

55
require (
66
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.10
7-
github.com/alibabacloud-go/ecs-20140526/v4 v4.26.1
7+
github.com/alibabacloud-go/ecs-20140526/v4 v4.26.4
88
github.com/alibabacloud-go/tea v1.2.2
99
github.com/alibabacloud-go/tea-utils/v2 v2.0.6
1010
github.com/alibabacloud-go/vpc-20160428/v6 v6.10.4
@@ -28,13 +28,7 @@ require (
2828
require (
2929
contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect
3030
contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect
31-
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 // indirect
3231
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
33-
github.com/alibabacloud-go/darabonba-array v0.1.0 // indirect
34-
github.com/alibabacloud-go/darabonba-encode-util v0.0.2 // indirect
35-
github.com/alibabacloud-go/darabonba-map v0.0.2 // indirect
36-
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 // indirect
37-
github.com/alibabacloud-go/darabonba-string v1.0.2 // indirect
3832
github.com/alibabacloud-go/debug v1.0.1 // indirect
3933
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
4034
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6p
6565
github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
6666
github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA6GSbPg=
6767
github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc=
68-
github.com/alibabacloud-go/ecs-20140526/v4 v4.26.1 h1:H7iwq9BkcEBSc5cILRI0mz/G5liUCYzQdAtnpqYhaZ0=
69-
github.com/alibabacloud-go/ecs-20140526/v4 v4.26.1/go.mod h1:+OL8LuKrMnvZHxGETlNFY7NyYC4iba6zeVJo2OzX+zI=
68+
github.com/alibabacloud-go/ecs-20140526/v4 v4.26.4 h1:6SGPir8HT9YolNjTiDc1RBsU2BhQ3sBLy+kecxqDV7M=
69+
github.com/alibabacloud-go/ecs-20140526/v4 v4.26.4/go.mod h1:RAjofcYEeLI1zDF/bhyyHI/fRCMnPh7ZI/Swy2mEiXA=
7070
github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q=
7171
github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE=
7272
github.com/alibabacloud-go/openapi-util v0.1.0 h1:0z75cIULkDrdEhkLWgi9tnLe+KhAFE/r5Pb3312/eAY=

pkg/apis/v1alpha1/ecsnodeclass.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ type ECSNodeClassSpec struct {
5353
// +kubebuilder:validation:MaxItems:=30
5454
// +required
5555
ImageSelectorTerms []ImageSelectorTerm `json:"imageSelectorTerms" hash:"ignore"`
56+
// UserData to be applied to the provisioned nodes.
57+
// It must be in the appropriate format based on the ImageFamily in use. Karpenter will merge certain fields into
58+
// this UserData to ensure nodes are being provisioned with the correct configuration.
59+
// +optional
60+
UserData *string `json:"userData,omitempty"`
5661
// KubeletConfiguration defines args to be used when configuring kubelet on provisioned nodes.
5762
// They are a subset of the upstream types, recognizing not all options may be supported.
5863
// Wherever possible, the types and names should reflect the upstream kubelet types.
@@ -61,6 +66,9 @@ type ECSNodeClassSpec struct {
6166
// +kubebuilder:validation:XValidation:message="evictionSoftGracePeriod OwnerKey does not have a matching evictionSoft",rule="has(self.evictionSoftGracePeriod) ? self.evictionSoftGracePeriod.all(e, (e in self.evictionSoft)):true"
6267
// +optional
6368
KubeletConfiguration *KubeletConfiguration `json:"kubeletConfiguration,omitempty"`
69+
// SystemDisk to be applied to provisioned nodes.
70+
// +optional
71+
SystemDisk *SystemDisk `json:"systemDisk,omitempty"`
6472
}
6573

6674
// VSwitchSelectorTerm defines selection logic for a vSwitch used by Karpenter to launch nodes.
@@ -196,6 +204,43 @@ type KubeletConfiguration struct {
196204
CPUCFSQuota *bool `json:"cpuCFSQuota,omitempty"`
197205
}
198206

207+
type SystemDisk struct {
208+
// The category of the system disk (for example, cloud or cloud_ssd).
209+
// Only one of the following: "cloud", "cloud_efficiency", "cloud_ssd", "cloud_essd", "cloud_auto", and "cloud_essd_entry"
210+
// +kubebuilder:validation:Enum:={cloud,cloud_efficiency,cloud_ssd,cloud_essd,cloud_auto,cloud_essd_entry}
211+
// +optional
212+
Category *string `json:"category,omitempty"`
213+
// The size of the system disk. Unit: GiB.
214+
// Valid values:
215+
// * If you set Category to cloud: 20 to 500.
216+
// * If you set Category to other disk categories: 20 to 2048.
217+
//
218+
// +kubebuilder:validation:XValidation:message="size invalid",rule="self >= 20"
219+
// +optional
220+
Size *int32 `json:"size,omitempty"`
221+
// The name of the system disk.
222+
// The name must be 2 to 128 characters in length.
223+
// The name must start with a letter and cannot start with http:// or https://.
224+
// The name can contain letters, digits, colons (:), underscores (_), and hyphens (-).
225+
// +kubebuilder:validation:XValidation:message="format invalid",rule="!self.startsWith('http') && self.size() >= 2 && self.size() <= 128"
226+
// +kubebuilder:validation:Pattern="^[A-Za-z][A-Za-z0-9:_-]*$"
227+
// +optional
228+
DiskName *string `json:"diskName,omitempty"`
229+
// The performance level of the ESSD to use as the system disk. Default value: PL0.
230+
// Valid values:
231+
// * PL0: A single ESSD can deliver up to 10,000 random read/write IOPS.
232+
// * PL1: A single ESSD can deliver up to 50,000 random read/write IOPS.
233+
// * PL2: A single ESSD can deliver up to 100,000 random read/write IOPS.
234+
// * PL3: A single ESSD can deliver up to 1,000,000 random read/write IOPS.
235+
// +kubebuilder:validation:Enum:={PL0,PL1,PL2,PL3}
236+
PerformanceLevel *string `json:"performanceLevel,omitempty"`
237+
// The ID of the automatic snapshot policy to apply to the system disk.
238+
AutoSnapshotPolicyID *string `json:"autoSnapshotPolicyId,omitempty"`
239+
// Specifies whether to enable the performance burst feature for the system disk
240+
BurstingEnabled *bool `json:"burstingEnabled,omitempty"`
241+
// TODO: add ProvisionedIops or Iops
242+
}
243+
199244
// ECSNodeClass is the Schema for the ECSNodeClass API
200245
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
201246
// +kubebuilder:resource:path=ecsnodeclasses,scope=Cluster,categories=karpenter,shortName={ecsnc,ecsncs}

pkg/apis/v1alpha1/ecsnodeclass_status.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package v1alpha1
1818

1919
import (
2020
"github.com/awslabs/operatorpkg/status"
21+
corev1 "k8s.io/api/core/v1"
2122
)
2223

2324
const (
@@ -46,6 +47,19 @@ type SecurityGroup struct {
4647
Name string `json:"name,omitempty"`
4748
}
4849

50+
// Image contains resolved image selector values utilized for node launch
51+
type Image struct {
52+
// ID of the Image
53+
// +required
54+
ID string `json:"id"`
55+
// Name of the Image
56+
// +optional
57+
Name string `json:"name,omitempty"`
58+
// Requirements of the Image to be utilized on an instance type
59+
// +required
60+
Requirements []corev1.NodeSelectorRequirement `json:"requirements"`
61+
}
62+
4963
// ECSNodeClassStatus contains the resolved state of the ECSNodeClass
5064
type ECSNodeClassStatus struct {
5165
// VSwitches contains the current VSwitch values that are available to the
@@ -56,6 +70,10 @@ type ECSNodeClassStatus struct {
5670
// cluster under the SecurityGroups selectors.
5771
// +optional
5872
SecurityGroups []SecurityGroup `json:"securityGroups,omitempty"`
73+
// Image contains the current image that are available to the
74+
// cluster under the Image selectors.
75+
// +optional
76+
Images []Image `json:"images,omitempty"`
5977
// Conditions contains signals for health and readiness
6078
// +optional
6179
Conditions []status.Condition `json:"conditions,omitempty"`

pkg/providers/imagefamily/aliyun3.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,35 @@ limitations under the License.
1616

1717
package imagefamily
1818

19-
import "context"
19+
import (
20+
"context"
21+
22+
corev1 "k8s.io/api/core/v1"
23+
"sigs.k8s.io/karpenter/pkg/cloudprovider"
24+
25+
"github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/apis/v1alpha1"
26+
)
2027

2128
type Aliyun3 struct {
29+
*Options
30+
}
31+
32+
func (a Aliyun3) UserData(kubeletConfig *v1alpha1.KubeletConfiguration, taints []corev1.Taint, labels map[string]string, instanceTypes []*cloudprovider.InstanceType, customUserData *string) string {
33+
// in-cluster user data
34+
// curl http://aliacs-k8s-{region}.oss-{region}-internal.aliyuncs.com/public/pkg/run/attach/{clusterversion}/attach_node.sh | bash -s -- --token **** --endpoint 1.x.x.x --cluster-dns 1.x.x.x --cluster-id ...
35+
//
36+
// token: secret/bootstrap-token
37+
38+
//TODO implement me
39+
panic("implement me")
2240
}
2341

2442
func (a Aliyun3) DescribeImageQuery(ctx context.Context, k8sVersion string, imageVersion string) ([]DescribeImageQuery, error) {
2543
//TODO implement me
2644
panic("implement me")
2745
}
46+
47+
func (a Aliyun3) DefaultSystemDisk() *v1alpha1.SystemDisk {
48+
//TODO implement me
49+
panic("implement me")
50+
}

pkg/providers/imagefamily/custom.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,28 @@ package imagefamily
1818

1919
import (
2020
"context"
21+
"encoding/base64"
2122

23+
"github.com/alibabacloud-go/tea/tea"
2224
corev1 "k8s.io/api/core/v1"
2325
"sigs.k8s.io/karpenter/pkg/cloudprovider"
2426

2527
"github.com/cloudpilot-ai/karpenter-provider-alicloud/pkg/apis/v1alpha1"
2628
)
2729

2830
type Custom struct {
31+
*Options
2932
}
3033

3134
// UserData returns the default userdata script for the Image Family
32-
func (c Custom) UserData(_ *v1alpha1.KubeletConfiguration, _ []corev1.Taint, _ map[string]string, _ *string, _ []*cloudprovider.InstanceType, customUserData *string) {
33-
//TODO implement me
34-
panic("implement me")
35+
func (c Custom) UserData(kubeletConfig *v1alpha1.KubeletConfiguration, taints []corev1.Taint, labels map[string]string, instanceTypes []*cloudprovider.InstanceType, customUserData *string) string {
36+
return base64.StdEncoding.EncodeToString([]byte(tea.StringValue(customUserData)))
3537
}
3638

3739
func (c Custom) DescribeImageQuery(_ context.Context, _ string, _ string) ([]DescribeImageQuery, error) {
3840
return []DescribeImageQuery{}, nil
3941
}
42+
43+
func (c Custom) DefaultSystemDisk() *v1alpha1.SystemDisk {
44+
return nil
45+
}

pkg/providers/imagefamily/image.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (p *DefaultProvider) DescribeImageQueries(ctx context.Context, nodeClass *v
9090
if err != nil {
9191
return nil, fmt.Errorf("getting kubernetes version, %w", err)
9292
}
93-
imageFamily := GetImageFamily(v1alpha1.ImageFamilyFromAlias(term.Alias))
93+
imageFamily := GetImageFamily(v1alpha1.ImageFamilyFromAlias(term.Alias), nil)
9494
query, err := imageFamily.DescribeImageQuery(ctx, kubernetesVersion, v1alpha1.ImageVersionFromAlias(term.Alias))
9595
if err != nil {
9696
return nil, err
@@ -204,15 +204,3 @@ func (p *DefaultProvider) describeImages(request *ecs.DescribeImagesRequest, pro
204204
}
205205
return nil
206206
}
207-
208-
// TODO: move it to resolver.go
209-
func GetImageFamily(imageFamily string) ImageFamily {
210-
switch imageFamily {
211-
case v1alpha1.ImageFamilyCustom:
212-
return &Custom{}
213-
case v1alpha1.ImageFamilyAliyun3:
214-
return &Aliyun3{}
215-
default:
216-
return &Aliyun3{}
217-
}
218-
}

0 commit comments

Comments
 (0)