Add DynamicProvisioningScheduling support for EBS
Signed-off-by: Deep Debroy <ddebroy@docker.com>
This commit is contained in:
@@ -79,6 +79,16 @@ const (
|
||||
VolumeDynamicallyCreatedByKey = "kubernetes.io/createdby"
|
||||
)
|
||||
|
||||
// VolumeZoneConfig contains config information about zonal volume.
|
||||
type VolumeZoneConfig struct {
|
||||
ZonePresent bool
|
||||
ZonesPresent bool
|
||||
ReplicaZoneFromNodePresent bool
|
||||
Zone string
|
||||
Zones string
|
||||
ReplicaZoneFromNode string
|
||||
}
|
||||
|
||||
// IsReady checks for the existence of a regular file
|
||||
// called 'ready' in the given directory and returns
|
||||
// true if that file exists.
|
||||
@@ -308,6 +318,77 @@ func LoadPodFromFile(filePath string) (*v1.Pod, error) {
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
// SelectZone selects a zone for a volume based on several factors:
|
||||
// node.zone, allowedTopologies, zone/zones parameters from storageclass
|
||||
// and zones with active nodes from the cluster
|
||||
func SelectZoneForVolume(zoneParameterPresent, zonesParameterPresent bool, zoneParameter string, zonesParameter, zonesWithNodes sets.String, node *v1.Node, allowedTopologies []v1.TopologySelectorTerm, pvcName string) (string, error) {
|
||||
if zoneParameterPresent && zonesParameterPresent {
|
||||
return "", fmt.Errorf("both zone and zones StorageClass parameters must not be used at the same time")
|
||||
}
|
||||
|
||||
// pick zone from node if present
|
||||
if node != nil {
|
||||
// DynamicProvisioningScheduling implicit since node is not nil
|
||||
if zoneParameterPresent || zonesParameterPresent {
|
||||
return "", fmt.Errorf("zone[s] cannot be specified in StorageClass if VolumeBindingMode is set to WaitForFirstConsumer. Please specify allowedTopologies in StorageClass for constraining zones.")
|
||||
}
|
||||
|
||||
// pick node's zone and ignore any allowedTopologies (since scheduler is assumed to have accounted for it already)
|
||||
z, ok := node.ObjectMeta.Labels[kubeletapis.LabelZoneFailureDomain]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%s Label for node missing", kubeletapis.LabelZoneFailureDomain)
|
||||
}
|
||||
return z, nil
|
||||
}
|
||||
|
||||
// pick zone from allowedZones if specified
|
||||
allowedZones, err := ZonesFromAllowedTopologies(allowedTopologies)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if (len(allowedTopologies) > 0) && (allowedZones.Len() == 0) {
|
||||
return "", fmt.Errorf("no matchLabelExpressions with %s key found in allowedTopologies. Please specify matchLabelExpressions with %s key", kubeletapis.LabelZoneFailureDomain, kubeletapis.LabelZoneFailureDomain)
|
||||
}
|
||||
|
||||
if allowedZones.Len() > 0 {
|
||||
// DynamicProvisioningScheduling implicit since allowedZones present
|
||||
if zoneParameterPresent || zonesParameterPresent {
|
||||
return "", fmt.Errorf("zone[s] cannot be specified in StorageClass if allowedTopologies specified")
|
||||
}
|
||||
return ChooseZoneForVolume(*allowedZones, pvcName), nil
|
||||
}
|
||||
|
||||
// pick zone from parameters if present
|
||||
if zoneParameterPresent {
|
||||
return zoneParameter, nil
|
||||
}
|
||||
|
||||
if zonesParameterPresent {
|
||||
return ChooseZoneForVolume(zonesParameter, pvcName), nil
|
||||
}
|
||||
|
||||
// pick zone from zones with nodes
|
||||
return ChooseZoneForVolume(zonesWithNodes, pvcName), nil
|
||||
}
|
||||
|
||||
// ZonesFromAllowedTopologies returns a list of zones specified in allowedTopologies
|
||||
func ZonesFromAllowedTopologies(allowedTopologies []v1.TopologySelectorTerm) (*sets.String, error) {
|
||||
zones := make(sets.String)
|
||||
for _, term := range allowedTopologies {
|
||||
for _, exp := range term.MatchLabelExpressions {
|
||||
if exp.Key == kubeletapis.LabelZoneFailureDomain {
|
||||
for _, value := range exp.Values {
|
||||
zones.Insert(value)
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("unsupported key found in matchLabelExpressions: %s", exp.Key)
|
||||
}
|
||||
}
|
||||
}
|
||||
return &zones, nil
|
||||
}
|
||||
|
||||
func ZonesSetToLabelValue(strSet sets.String) string {
|
||||
return strings.Join(strSet.UnsortedList(), kubeletapis.LabelMultiZoneDelimiter)
|
||||
}
|
||||
|
Reference in New Issue
Block a user