Skip to content

Commit

Permalink
Merge pull request #3102 from yoz2326/aws_ebs_iops
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue

AWS: root volume provisioned IOPS support

It is possible to set `rootVolumeType: gp2` so an instance group will use `gp2` as disk type (https://github.com/kubernetes/kops/blob/master/docs/instance_groups.md)

If the option is set to `rootVolumeType: io1` then the below error is thrown when building the cluster:

`W0731 13:44:44.298875    8784 executor.go:109] error running task "LaunchConfiguration/master-eu-west-1a.masters.cluster.name" (9m48s remaining to succeed): error creating AutoscalingLaunchConfiguration: ValidationError: Iops is required for a provisioned IOPS volume.
    status code: 400, request id: 072e23b2-75ee-11e7-968a-191d6f6e9343`

This PR tries to address this so if anyone needs, it can use `io1` as disk type for the root volume.
In order to define the number of Iops set `rootVolumeIops: <number>` (minimum is 100)

If `rootVolumeType: io1` is set and `rootVolumeIops` is not defined, then `rootVolumeIops` defaults to 100.

I am not quite familiar with the Kops codebase and this is my first encounter with Go, so some changes might not be suitable (I also do not have a software developer background so bear with me :) ). Please review and add feed-back.  

I've included a small change to the Makefile as I compiled Kops on a Mac and didn't had $GOPATH set after installing Go. I thought that pulling this via `go env` would be more flexible, but I am not 100% sure as I don't do much development in this area and not sure about possible use cases.
  • Loading branch information
Kubernetes Submit Queue authored Aug 1, 2017
2 parents 62be683 + 14526ae commit 576dca6
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ S3_BUCKET?=s3://must-override/
GCS_LOCATION?=gs://must-override
GCS_URL=$(GCS_LOCATION:gs://%=https://storage.googleapis.com/%)
LATEST_FILE?=latest-ci.txt
GOPATH_1ST=$(shell echo ${GOPATH} | cut -d : -f 1)
GOPATH_1ST=$(shell go env | grep GOPATH | cut -f 2 -d \")
UNIQUE:=$(shell date +%s)
GOVERSION=1.8.3

Expand Down
17 changes: 17 additions & 0 deletions docs/instance_groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ The default volume size for Masters is 64 GB, while the default volume size for
The procedure to resize the root volume works the same way:

* Edit the instance group, set `rootVolumeSize` and/or `rootVolumeType` to the desired values: `kops edit ig nodes`
* If `rootVolumeType` is set to `io1` then you can define the number of Iops by specifing `rootVolumeIops` (defaults to 100 if not defined)
* Preview changes: `kops update cluster <clustername>`
* Apply changes: `kops update cluster <clustername> --yes`
* Rolling update to update existing instances: `kops rolling-update cluster --yes`
Expand All @@ -87,6 +88,22 @@ spec:
rootVolumeType: gp2
```

For example, to set up a 200GB io1 root volume with 200 provisioned Iops, your InstanceGroup spec might look like:

```
metadata:
creationTimestamp: "2016-07-11T04:14:00Z"
name: nodes
spec:
machineType: t2.medium
maxSize: 2
minSize: 2
role: Node
rootVolumeSize: 200
rootVolumeType: io1
rootProvisionedIops: 200
```

## Creating a new instance group

Suppose you want to add a new group of nodes, perhaps with a different instance type. You do this using
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/instancegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type InstanceGroupSpec struct {
RootVolumeSize *int32 `json:"rootVolumeSize,omitempty"`
// RootVolumeType is the type of the EBS root volume to use (e.g. gp2)
RootVolumeType *string `json:"rootVolumeType,omitempty"`
// If volume type is io1, then we need to specify the number of Iops.
RootVolumeIops *int32 `json:"rootVolumeIops,omitempty"`
// RootVolumeOptimization enables EBS optimization for an instance
RootVolumeOptimization *bool `json:"rootVolumeOptimization,omitempty"`

Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/v1alpha1/instancegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ type InstanceGroupSpec struct {
RootVolumeSize *int32 `json:"rootVolumeSize,omitempty"`
// RootVolumeType is the type of the EBS root volume to use (e.g. gp2)
RootVolumeType *string `json:"rootVolumeType,omitempty"`
// If volume type is io1, then we need to specify the number of Iops.
RootVolumeIops *int32 `json:"rootVolumeIops,omitempty"`
// RootVolumeOptimization enables EBS optimization for an instance
RootVolumeOptimization *bool `json:"rootVolumeOptimization,omitempty"`

Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/v1alpha1/zz_generated.conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,7 @@ func autoConvert_v1alpha1_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *Instan
out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize
out.RootVolumeType = in.RootVolumeType
out.RootVolumeIops = in.RootVolumeIops
out.RootVolumeOptimization = in.RootVolumeOptimization
// WARNING: in.Zones requires manual conversion: does not exist in peer-type
out.MaxPrice = in.MaxPrice
Expand Down Expand Up @@ -1301,6 +1302,7 @@ func autoConvert_kops_InstanceGroupSpec_To_v1alpha1_InstanceGroupSpec(in *kops.I
out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize
out.RootVolumeType = in.RootVolumeType
out.RootVolumeIops = in.RootVolumeIops
out.RootVolumeOptimization = in.RootVolumeOptimization
// WARNING: in.Subnets requires manual conversion: does not exist in peer-type
out.MaxPrice = in.MaxPrice
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/v1alpha2/instancegroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ type InstanceGroupSpec struct {
RootVolumeSize *int32 `json:"rootVolumeSize,omitempty"`
// RootVolumeType is the type of the EBS root volume to use (e.g. gp2)
RootVolumeType *string `json:"rootVolumeType,omitempty"`
// If volume type is io1, then we need to specify the number of Iops.
RootVolumeIops *int32 `json:"rootVolumeIops,omitempty"`
// RootVolumeOptimization enables EBS optimization for an instance
RootVolumeOptimization *bool `json:"rootVolumeOptimization,omitempty"`

Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/kops/v1alpha2/zz_generated.conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,7 @@ func autoConvert_v1alpha2_InstanceGroupSpec_To_kops_InstanceGroupSpec(in *Instan
out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize
out.RootVolumeType = in.RootVolumeType
out.RootVolumeIops = in.RootVolumeIops
out.RootVolumeOptimization = in.RootVolumeOptimization
out.Subnets = in.Subnets
out.MaxPrice = in.MaxPrice
Expand Down Expand Up @@ -1404,6 +1405,7 @@ func autoConvert_kops_InstanceGroupSpec_To_v1alpha2_InstanceGroupSpec(in *kops.I
out.MachineType = in.MachineType
out.RootVolumeSize = in.RootVolumeSize
out.RootVolumeType = in.RootVolumeType
out.RootVolumeIops = in.RootVolumeIops
out.RootVolumeOptimization = in.RootVolumeOptimization
out.Subnets = in.Subnets
out.MaxPrice = in.MaxPrice
Expand Down
14 changes: 13 additions & 1 deletion pkg/model/awsmodel/autoscalinggroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
DefaultVolumeSizeMaster = 64
DefaultVolumeSizeBastion = 32
DefaultVolumeType = "gp2"
DefaultVolumeIops = 100
)

// AutoscalingGroupModelBuilder configures AutoscalingGroup objects
Expand Down Expand Up @@ -63,7 +64,14 @@ func (b *AutoscalingGroupModelBuilder) Build(c *fi.ModelBuilderContext) error {
}
}
volumeType := fi.StringValue(ig.Spec.RootVolumeType)
if volumeType == "" {
volumeIops := fi.Int32Value(ig.Spec.RootVolumeIops)

switch volumeType {
case "io1":
if volumeIops == 0 {
volumeIops = DefaultVolumeIops
}
default:
volumeType = DefaultVolumeType
}

Expand All @@ -83,6 +91,10 @@ func (b *AutoscalingGroupModelBuilder) Build(c *fi.ModelBuilderContext) error {
RootVolumeOptimization: ig.Spec.RootVolumeOptimization,
}

if volumeType == "io1" {
t.RootVolumeIops = i64(int64(volumeIops))
}

if ig.Spec.Tenancy != "" {
t.Tenancy = s(ig.Spec.Tenancy)
}
Expand Down
2 changes: 2 additions & 0 deletions upup/pkg/fi/cloudup/awstasks/block_device_mappings.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type BlockDeviceMapping struct {
EbsDeleteOnTermination *bool
EbsVolumeSize *int64
EbsVolumeType *string
EbsVolumeIops *int64
}

func BlockDeviceMappingFromEC2(i *ec2.BlockDeviceMapping) (string, *BlockDeviceMapping) {
Expand Down Expand Up @@ -76,6 +77,7 @@ func (i *BlockDeviceMapping) ToAutoscaling(deviceName string) *autoscaling.Block
o.Ebs.DeleteOnTermination = i.EbsDeleteOnTermination
o.Ebs.VolumeSize = i.EbsVolumeSize
o.Ebs.VolumeType = i.EbsVolumeType
o.Ebs.Iops = i.EbsVolumeIops
}

return o
Expand Down
4 changes: 4 additions & 0 deletions upup/pkg/fi/cloudup/awstasks/launchconfiguration.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ type LaunchConfiguration struct {
RootVolumeSize *int64
// RootVolumeType is the type of the EBS root volume to use (e.g. gp2)
RootVolumeType *string
// If volume type is io1, then we need to specify the number of Iops.
RootVolumeIops *int64
// RootVolumeOptimization enables EBS optimization for an instance
RootVolumeOptimization *bool

Expand Down Expand Up @@ -136,6 +138,7 @@ func (e *LaunchConfiguration) Find(c *fi.Context) (*LaunchConfiguration, error)
}
actual.RootVolumeSize = b.Ebs.VolumeSize
actual.RootVolumeType = b.Ebs.VolumeType
actual.RootVolumeIops = b.Ebs.Iops
}

userData, err := base64.StdEncoding.DecodeString(*lc.UserData)
Expand Down Expand Up @@ -201,6 +204,7 @@ func (e *LaunchConfiguration) buildRootDevice(cloud awsup.AWSCloud) (map[string]
EbsDeleteOnTermination: aws.Bool(true),
EbsVolumeSize: e.RootVolumeSize,
EbsVolumeType: e.RootVolumeType,
EbsVolumeIops: e.RootVolumeIops,
}

blockDeviceMappings[rootDeviceName] = rootDeviceMapping
Expand Down

0 comments on commit 576dca6

Please sign in to comment.