1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 15:47:14 +01:00

AWS: Add the ability to configure throughput on GP3 volumes

GP3 volumes have the ability to configure throughput from 125 MiB/s to
2000 MiB/s. This allows the ability to set this at install time in the
install-config.

https://issues.redhat.com/browse/CORS-4212
This commit is contained in:
John Hixson
2025-09-16 21:57:14 -07:00
parent 567aa4add2
commit fdde8b0ece
7 changed files with 77 additions and 9 deletions

View File

@@ -221,6 +221,13 @@ spec:
(GiB).
minimum: 0
type: integer
throughput:
description: |-
Throughput to provision in MiB/s supported for the volume type. This
is currently only applicable to volumes of type gp3.
format: int64
minimum: 0
type: integer
type:
description: Type defines the type of the volume.
type: string
@@ -1739,6 +1746,13 @@ spec:
gibibytes (GiB).
minimum: 0
type: integer
throughput:
description: |-
Throughput to provision in MiB/s supported for the volume type. This
is currently only applicable to volumes of type gp3.
format: int64
minimum: 0
type: integer
type:
description: Type defines the type of the volume.
type: string
@@ -3197,6 +3211,13 @@ spec:
(GiB).
minimum: 0
type: integer
throughput:
description: |-
Throughput to provision in MiB/s supported for the volume type. This
is currently only applicable to volumes of type gp3.
format: int64
minimum: 0
type: integer
type:
description: Type defines the type of the volume.
type: string
@@ -4848,6 +4869,13 @@ spec:
(GiB).
minimum: 0
type: integer
throughput:
description: |-
Throughput to provision in MiB/s supported for the volume type. This
is currently only applicable to volumes of type gp3.
format: int64
minimum: 0
type: integer
type:
description: Type defines the type of the volume.
type: string

View File

@@ -18,6 +18,8 @@ Beyond the [platform-agnostic `install-config.yaml` properties](../customization
* `rootVolume` (optional object): Defines the root volume for EC2 instances in the machine pool.
* `iops` (optional integer): The amount of provisioned [IOPS][volume-iops].
This is only valid for `type` `io1`.
* `throughput` (optional integer): The amount of throughput in MiB/s [Throughput Performance][volume-throughput].
This is only valid for `type` `gp3`.
* `size` (optional integer): Size of the root volume in gibibytes (GiB).
* `type` (optional string): The [type of volume][volume-type].
* `kmsKeyARN` (optional string): The [ARN of KMS key][kms-key] that should be used to encrypt the EBS volume.
@@ -119,4 +121,5 @@ sshKey: ssh-ed25519 AAAA...
[kms-key-default]: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_GetEbsDefaultKmsKeyId.html
[kms-key]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html
[volume-iops]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-io-characteristics.html
[volume-throughput]: https://docs.aws.amazon.com/ebs/latest/userguide/general-purpose.html#gp3-ebs-volume-type
[volume-type]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html

View File

@@ -107,6 +107,7 @@ func GenerateMachines(clusterID string, in *MachineInput) ([]*asset.RuntimeFile,
Size: int64(mpool.EC2RootVolume.Size),
Type: capa.VolumeType(mpool.EC2RootVolume.Type),
IOPS: int64(mpool.EC2RootVolume.IOPS),
Throughput: ptr.To(mpool.EC2RootVolume.Throughput),
Encrypted: ptr.To(true),
EncryptionKey: mpool.KMSKeyARN,
},

View File

@@ -115,7 +115,8 @@ func TestGenerateMachines(t *testing.T) {
},
SSHKeyName: ptr.To(""),
RootVolume: &capa.Volume{
Encrypted: ptr.To(true),
Encrypted: ptr.To(true),
Throughput: ptr.To(int64(0)),
},
UncompressedUserData: ptr.To(true),
Ignition: &capa.Ignition{
@@ -171,7 +172,8 @@ func TestGenerateMachines(t *testing.T) {
},
SSHKeyName: ptr.To(""),
RootVolume: &capa.Volume{
Encrypted: ptr.To(true),
Encrypted: ptr.To(true),
Throughput: ptr.To(int64(0)),
},
UncompressedUserData: ptr.To(true),
Ignition: &capa.Ignition{
@@ -227,8 +229,11 @@ func TestGenerateMachines(t *testing.T) {
fmt.Sprintf("%s-subnet-public-%s", stubClusterID, machineZone),
}}},
},
SSHKeyName: ptr.To(""),
RootVolume: &capa.Volume{Encrypted: ptr.To(true)},
SSHKeyName: ptr.To(""),
RootVolume: &capa.Volume{
Encrypted: ptr.To(true),
Throughput: ptr.To(int64(0)),
},
UncompressedUserData: ptr.To(true),
Ignition: &capa.Ignition{
StorageType: capa.IgnitionStorageTypeOptionUnencryptedUserData,

View File

@@ -239,11 +239,12 @@ func provider(in *machineProviderInput) (*machineapi.AWSMachineProviderConfig, e
BlockDevices: []machineapi.BlockDeviceMappingSpec{
{
EBS: &machineapi.EBSBlockDeviceSpec{
VolumeType: pointer.String(in.root.Type),
VolumeSize: pointer.Int64(int64(in.root.Size)),
Iops: pointer.Int64(int64(in.root.IOPS)),
Encrypted: pointer.Bool(true),
KMSKey: machineapi.AWSResourceReference{ARN: pointer.String(in.root.KMSKeyARN)},
VolumeType: pointer.String(in.root.Type),
VolumeSize: pointer.Int64(int64(in.root.Size)),
Iops: pointer.Int64(int64(in.root.IOPS)),
ThroughputMib: pointer.Int32(int32(in.root.Throughput)),
Encrypted: pointer.Bool(true),
KMSKey: machineapi.AWSResourceReference{ARN: pointer.String(in.root.KMSKeyARN)},
},
},
},

View File

@@ -71,6 +71,9 @@ func (a *MachinePool) Set(required *MachinePool) {
if required.EC2RootVolume.IOPS != 0 {
a.EC2RootVolume.IOPS = required.EC2RootVolume.IOPS
}
if required.EC2RootVolume.Throughput != 0 {
a.EC2RootVolume.Throughput = required.EC2RootVolume.Throughput
}
if required.EC2RootVolume.Size != 0 {
a.EC2RootVolume.Size = required.EC2RootVolume.Size
}
@@ -107,6 +110,13 @@ type EC2RootVolume struct {
// +optional
IOPS int `json:"iops"`
// Throughput to provision in MiB/s supported for the volume type. This
// is currently only applicable to volumes of type gp3.
//
// +kubebuilder:validation:Minimum=0
// +optional
Throughput int64 `json:"throughput"`
// Size defines the size of the volume in gibibytes (GiB).
//
// +kubebuilder:validation:Minimum=0

View File

@@ -46,6 +46,7 @@ func ValidateMachinePool(platform *aws.Platform, p *aws.MachinePool, fldPath *fi
if p.EC2RootVolume.Type != "" {
allErrs = append(allErrs, validateVolumeSize(p, fldPath)...)
allErrs = append(allErrs, validateIOPS(p, fldPath)...)
allErrs = append(allErrs, validateThroughput(p, fldPath)...)
}
if p.EC2Metadata.Authentication != "" && !validMetadataAuthValues.Has(p.EC2Metadata.Authentication) {
@@ -108,6 +109,25 @@ func validateIOPS(p *aws.MachinePool, fldPath *field.Path) field.ErrorList {
return allErrs
}
func validateThroughput(p *aws.MachinePool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
volumeType := strings.ToLower(p.EC2RootVolume.Type)
throughput := p.EC2RootVolume.Throughput
switch volumeType {
case "gp3":
if throughput != 0 && (throughput < 125 || throughput > 2000) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("throughput"), throughput, "throughput must be between 125 MiB/s and 2000 MiB/s"))
}
default:
if throughput != 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Child("throughput"), throughput, fmt.Sprintf("throughput not supported for type %s", volumeType)))
}
}
return allErrs
}
// ValidateAMIID check the AMI ID is set for a machine pool.
func ValidateAMIID(platform *aws.Platform, p *aws.MachinePool, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}