fix: create instance disk size error and adjust user define disk device name (#2179)

* feat:  add describe image api and get root device name from ami.

fix create root volume size not working.
user define root/data in Disk.Name rather than Disk.Type , user should not care about deviceName like /dev/xvda or /dev/sdb , they should be generated in the code
add some basic schema validation option: for example, supported 10 disk per machine check, volumeType enums check. disk Type enums check... etc

Signed-off-by: ybyang <ybyang7@iflytek.com>
This commit is contained in:
ybyang
2022-12-03 21:04:32 +08:00
committed by GitHub
parent 0aedab57a9
commit 70b4aaa70c
8 changed files with 159 additions and 58 deletions
+1 -1
View File
@@ -93,7 +93,7 @@ ifndef ignore-not-found
endif
.PHONY: install
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
install: manifests ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl apply -f -
.PHONY: uninstall
+22 -8
View File
@@ -128,14 +128,28 @@ metadata:
name: infra-apply-test
spec:
hosts:
- roles: [master] # required
count: 3 # Required
flavor: "t2.micro"
image: "ami-05248307900d52e3a"
- roles: [ node ] # required
count: 3 # Required
flavor: "t2.micro"
image: "ami-05248307900d52e3a"
- roles: [ master ]
count: 1
flavor: t2.medium
image: "ami-0d66b970b9f16f1f5"
disks:
- capacity: 23
volumeType: standard
type: "root"
- capacity: 21
volumeType: gp3
type: "data"
- roles: [ node ]
count: 1
flavor: t2.medium
image: "ami-0d66b970b9f16f1f5"
disks:
- capacity: 11
volumeType: gp3
type: "root"
- capacity: 13
volumeType: gp3
type: "data"
```
```shell
+21 -5
View File
@@ -87,8 +87,12 @@ type Metadata struct {
}
type Hosts struct {
// +kubebuilder:validation:Required
Roles []string `json:"roles,omitempty"`
Count int `json:"count,omitempty"`
// +kubebuilder:validation:Required
// +kubebuilder:validation:Minimum:=0
Count int `json:"count,omitempty"`
// key values resources.
// cpu: 2
// memory: 4
@@ -97,9 +101,15 @@ type Hosts struct {
// ecs.t5-lc1m2.large
Flavor string `json:"flavor,omitempty"`
// ENUM: amd64/arm64 (NOTE: the default value is amd64)
// +kubebuilder:default:=amd64
// +kubebuilder:validation:Enum=amd64;arm64
Arch string `json:"arch,omitempty"`
// ENUM: ubuntu:20.04, centos:7.2 and so on.
Image string `json:"image,omitempty"`
Image string `json:"image,omitempty"`
// max support 10 disks .
// +kubebuilder:validation:MaxItems:=10
// +kubebuilder:validation:Optional
Disks []Disk `json:"disks,omitempty"`
Metadata []Metadata `json:"metadata,omitempty"`
// Find the mapping between expected hosts and actual hosts
@@ -122,9 +132,14 @@ func (hosts IndexHosts) Swap(i, j int) {
type Disk struct {
Capacity int `json:"capacity,omitempty"`
// ENUM: system/data
// ENUM: standard/io1/io2/gp2/gp3/sc1/st1
// +kubebuilder:validation:Enum=standard;io1;io2;gp2;gp3;sc1;st1
VolumeType string `json:"volumeType,omitempty"`
// +kubebuilder:validation:Optional
// +kubebuilder:validation:Enum=root;data
// +kubebuilder:default:=data
// Disk Type , default is data disk. allowed value is `root|data`
Type string `json:"type,omitempty"`
// Device name
Name string `json:"name,omitempty"`
}
@@ -151,7 +166,8 @@ type InfraSpec struct {
RegionIDs []string `json:"regionIDs,omitempty"`
ZoneIDs []string `json:"zoneIDs,omitempty"`
SSH v1bata1.SSH `json:"ssh,omitempty"`
Hosts []Hosts `json:"hosts,omitempty"`
// +kubebuilder:validation:Required
Hosts []Hosts `json:"hosts,omitempty"`
// Availability Zone
AvailabilityZone string `json:"availabilityZone,omitempty"`
}
+2
View File
@@ -15,3 +15,5 @@ const (
TrySleepTime = time.Second
TRUELable = "true"
)
var DefaultRootVolumeSize = int32(40)
@@ -42,23 +42,45 @@ spec:
items:
properties:
arch:
default: amd64
description: 'ENUM: amd64/arm64 (NOTE: the default value is
amd64)'
enum:
- amd64
- arm64
type: string
count:
minimum: 0
type: integer
disks:
description: max support 10 disks .
items:
properties:
capacity:
type: integer
name:
description: Device name
type: string
type:
description: 'ENUM: system/data'
default: data
description: Disk Type , default is data disk. allowed
value is `root|data`
enum:
- root
- data
type: string
volumeType:
description: 'ENUM: standard/io1/io2/gp2/gp3/sc1/st1'
enum:
- standard
- io1
- io2
- gp2
- gp3
- sc1
- st1
type: string
type: object
maxItems: 10
type: array
flavor:
description: ecs.t5-lc1m2.large
@@ -18,11 +18,25 @@ metadata:
name: infra-apply-test
spec:
hosts:
- roles: [master] # required
count: 1 # Required
flavor: "t2.large"
image: "ami-0d66b970b9f16f1f5"
- roles: [ node ] # required
count: 1 # Required
flavor: "t2.medium"
image: "ami-0d66b970b9f16f1f5"
- roles: [ master ]
count: 1
flavor: t2.medium
image: "ami-0d66b970b9f16f1f5"
disks:
- capacity: 23
volumeType: standard
type: "root"
- capacity: 21
volumeType: gp3
type: "data"
- roles: [ node ]
count: 1
flavor: t2.medium
image: "ami-0d66b970b9f16f1f5"
disks:
- capacity: 11
volumeType: gp3
type: "root"
- capacity: 13
volumeType: gp3
type: "data"
+23 -23
View File
@@ -22,29 +22,29 @@ kind: Infra
metadata:
name: aws-infra-demo
spec:
regionIds: [cn-north-1]
ssh:
passwd: xxx
pk: /root/.ssh/id_rsa
port: 22
user: root
hosts:
- roles: [master, aaa, bbb] # required
count: 3 # Required
# key values resources.
resources:
cpu: 2
memory: 4
# other resources like GPU
# ENUM: amd64/arm64 (NOTE: the default value is amd64)
flavor: ecs.t5-lc1m2.large
arch: amd64
# ENUM: ubuntu:20.04, centos:7.2 and so on.
image: utuntu:20.04
disks:
- capacity: 50
# ENUM: system/data
type: system
hosts:
- roles: [ master ]
count: 1
flavor: t2.medium
image: "ami-0d66b970b9f16f1f5"
disks:
- capacity: 23
volumeType: standard
type: "root"
- capacity: 21
volumeType: gp3
type: "data"
- roles: [ node ]
count: 1
flavor: t2.medium
image: "ami-0d66b970b9f16f1f5"
disks:
- capacity: 11
volumeType: gp3
type: "root"
- capacity: 13
volumeType: gp3
type: "data"
```
kubectl apply -f infra.yaml
@@ -21,6 +21,7 @@ import (
"encoding/base64"
"fmt"
"strconv"
"strings"
"sync"
"time"
@@ -38,8 +39,6 @@ import (
var mutex sync.Mutex
var rootVolumeSize = int32(40)
var userData = `#!/bin/bash
sudo cp /home/ec2-user/.ssh/authorized_keys /root/.ssh/authorized_keys
sudo sed -i 's/#PermitRootLogin no/PermitRootLogin yes/g' /etc/ssh/sshd_config
@@ -115,6 +114,26 @@ func rolesToTags(roles []string) (tags []types.Tag) {
return tags
}
func checkHasSystemDisk(hosts *v1.Hosts) bool {
var hasSystemDisk = false
for _, v := range hosts.Disks {
if strings.EqualFold(v.Type, common.RootVolumeLabel) {
hasSystemDisk = true
}
}
return hasSystemDisk
}
// generateDataDiskDeviceName according https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/device_naming.html#available-ec2-device-names
func generateDataDiskDeviceName(index int) (string, error) {
var deviceSuffix = "bcdefghijklmnop"
if index > len(deviceSuffix)-1 || index < 0 {
return "", fmt.Errorf("device index is wrong that aws can't support, please check")
}
var deviceName = fmt.Sprintf("/dev/sd%s", string(deviceSuffix[index]))
return deviceName, nil
}
// get tags
func (d Driver) GetTags(hosts *v1.Hosts, infra *v1.Infra) []types.Tag {
// Tag name and tag value
@@ -149,29 +168,43 @@ func (d Driver) GetTags(hosts *v1.Hosts, infra *v1.Infra) []types.Tag {
return tags
}
// set blockDeviceMappings from hosts
// GetBlockDeviceMappings generate blockDeviceMappings from hosts
func (d Driver) GetBlockDeviceMappings(hosts *v1.Hosts, rootDeviceName string) []types.BlockDeviceMapping {
var blockDeviceMappings []types.BlockDeviceMapping
// add system disk if not exists
if len(hosts.Disks) == 0 || hosts.Disks[0].Name != rootDeviceName {
hasSystem := checkHasSystemDisk(hosts)
// if not specify a system disk, we add a default
if !hasSystem {
blockDeviceMappings = append(blockDeviceMappings, types.BlockDeviceMapping{
DeviceName: &rootDeviceName,
Ebs: &types.EbsBlockDevice{
VolumeSize: &rootVolumeSize,
VolumeSize: &common.DefaultRootVolumeSize,
},
})
}
systemAdded := false
dataDiskIndex := 0
for _, v := range hosts.Disks {
var deviceName string
if strings.EqualFold(v.Type, common.RootVolumeLabel) && !systemAdded {
deviceName = rootDeviceName
systemAdded = true
} else {
// should limit dataDiskNumbers here in crd check to avoid index error.
deviceName, _ = generateDataDiskDeviceName(dataDiskIndex)
dataDiskIndex++
}
size := int32(v.Capacity)
blockDeviceMappings = append(blockDeviceMappings, types.BlockDeviceMapping{
DeviceName: &v.Name,
bdm := types.BlockDeviceMapping{
DeviceName: &deviceName,
Ebs: &types.EbsBlockDevice{
VolumeSize: &size,
VolumeType: types.VolumeType(v.Type),
VolumeType: types.VolumeType(v.VolumeType),
},
})
}
blockDeviceMappings = append(blockDeviceMappings, bdm)
}
return blockDeviceMappings
}