Skip to content

Commit

Permalink
Admin Can Specify in Which AWS Availability Zone(s) a PV Shall Be Cre…
Browse files Browse the repository at this point in the history
…ated

An admin wants to specify in which AWS availability zone(s) users may create persistent volumes using dynamic provisioning.

That's why the admin can now configure in StorageClass object a comma separated list of zones. Dynamically created PVs for PVCs that use the StorageClass are created in one of the configured zones.
  • Loading branch information
pospispa committed May 24, 2017
1 parent d73c0d6 commit 9eb912e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 9 deletions.
5 changes: 3 additions & 2 deletions examples/persistent-volume-provisioning/README.md
Expand Up @@ -25,12 +25,13 @@ metadata:
provisioner: kubernetes.io/aws-ebs
parameters:
type: io1
zone: us-east-1d
zones: us-east-1d, us-east-1c
iopsPerGB: "10"
```

* `type`: `io1`, `gp2`, `sc1`, `st1`. See AWS docs for details. Default: `gp2`.
* `zone`: AWS zone. If not specified, a random zone from those where Kubernetes cluster has a node is chosen.
* `zone`: AWS zone. If neither zone nor zones is specified, volumes are generally round-robin-ed across all active zones where Kubernetes cluster has a node. Note: zone and zones parameters must not be used at the same time.
* `zones`: a comma separated list of AWS zone(s). If neither zone nor zones is specified, volumes are generally round-robin-ed across all active zones where Kubernetes cluster has a node. Note: zone and zones parameters must not be used at the same time.
* `iopsPerGB`: only for `io1` volumes. I/O operations per second per GiB. AWS volume plugin multiplies this with size of requested volume to compute IOPS of the volume and caps it at 20 000 IOPS (maximum supported by AWS, see AWS docs).
* `encrypted`: denotes whether the EBS volume should be encrypted or not. Valid values are `true` or `false`.
* `kmsKeyId`: optional. The full Amazon Resource Name of the key to use when encrypting the volume. If none is supplied but `encrypted` is true, a key is generated by AWS. See AWS docs for valid ARN value.
Expand Down
30 changes: 23 additions & 7 deletions pkg/cloudprovider/providers/aws/aws.go
Expand Up @@ -287,11 +287,14 @@ const (

// VolumeOptions specifies capacity and tags for a volume.
type VolumeOptions struct {
CapacityGB int
Tags map[string]string
PVCName string
VolumeType string
AvailabilityZone string
CapacityGB int
Tags map[string]string
PVCName string
VolumeType string
ZonePresent bool
ZonesPresent bool
AvailabilityZone string
AvailabilityZones string
// IOPSPerGB x CapacityGB will give total IOPS of the volume to create.
// Calculated total IOPS will be capped at MaxTotalIOPS.
IOPSPerGB int
Expand Down Expand Up @@ -1675,10 +1678,23 @@ func (c *Cloud) CreateDisk(volumeOptions *VolumeOptions) (KubernetesVolumeID, er
return "", fmt.Errorf("error querying for all zones: %v", err)
}

createAZ := volumeOptions.AvailabilityZone
if createAZ == "" {
var createAZ string
if !volumeOptions.ZonePresent && !volumeOptions.ZonesPresent {
createAZ = volume.ChooseZoneForVolume(allZones, volumeOptions.PVCName)
}
if !volumeOptions.ZonePresent && volumeOptions.ZonesPresent {
if adminSetOfZones, err := volume.ZonesToSet(volumeOptions.AvailabilityZones); err != nil {
return "", err
} else {
createAZ = volume.ChooseZoneForVolume(adminSetOfZones, volumeOptions.PVCName)
}
}
if volumeOptions.ZonePresent && !volumeOptions.ZonesPresent {
if err := volume.ValidateZone(volumeOptions.AvailabilityZone); err != nil {
return "", err
}
createAZ = volumeOptions.AvailabilityZone
}

var createType string
var iops int64
Expand Down
10 changes: 10 additions & 0 deletions pkg/volume/aws_ebs/aws_util.go
Expand Up @@ -91,12 +91,18 @@ func (util *AWSDiskUtil) CreateVolume(c *awsElasticBlockStoreProvisioner) (aws.K
}
// Apply Parameters (case-insensitive). We leave validation of
// the values to the cloud provider.
volumeOptions.ZonePresent = false
volumeOptions.ZonesPresent = false
for k, v := range c.options.Parameters {
switch strings.ToLower(k) {
case "type":
volumeOptions.VolumeType = v
case "zone":
volumeOptions.ZonePresent = true
volumeOptions.AvailabilityZone = v
case "zones":
volumeOptions.ZonesPresent = true
volumeOptions.AvailabilityZones = v
case "iopspergb":
volumeOptions.IOPSPerGB, err = strconv.Atoi(v)
if err != nil {
Expand All @@ -114,6 +120,10 @@ func (util *AWSDiskUtil) CreateVolume(c *awsElasticBlockStoreProvisioner) (aws.K
}
}

if volumeOptions.ZonePresent && volumeOptions.ZonesPresent {
return "", 0, nil, fmt.Errorf("both zone and zones StorageClass parameters must not be used at the same time")
}

// TODO: implement PVC.Selector parsing
if c.options.PVC.Spec.Selector != nil {
return "", 0, nil, fmt.Errorf("claim.Spec.Selector is not supported for dynamic provisioning on AWS")
Expand Down

0 comments on commit 9eb912e

Please sign in to comment.