diff --git a/charts/aws-ebs-csi-driver/values.yaml b/charts/aws-ebs-csi-driver/values.yaml index e123481baa..7da7e54eab 100644 --- a/charts/aws-ebs-csi-driver/values.yaml +++ b/charts/aws-ebs-csi-driver/values.yaml @@ -110,7 +110,16 @@ fullnameOverride: controller: # If arbitrary args like "--aws-sdk-debug-log=true" need to be passed, use this value additionalArgs: [] - affinity: {} + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + - key: eks.amazonaws.com/compute-type + operator: NotIn + values: + - fargate # The default filesystem type of the volume to provision when fstype is unspecified in the StorageClass. # If the default is not set and fstype is unset in the StorageClass, then no fstype will be set defaultFsType: ext4 diff --git a/deploy/kubernetes/base/controller.yaml b/deploy/kubernetes/base/controller.yaml index 397c8e696f..c35dc32119 100644 --- a/deploy/kubernetes/base/controller.yaml +++ b/deploy/kubernetes/base/controller.yaml @@ -23,6 +23,16 @@ spec: kubernetes.io/os: linux serviceAccountName: ebs-csi-controller-sa priorityClassName: system-cluster-critical + affinity: + nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: eks.amazonaws.com/compute-type + operator: NotIn + values: + - fargate + weight: 1 tolerations: - key: CriticalAddonsOnly operator: Exists diff --git a/pkg/cloud/metadata_k8s.go b/pkg/cloud/metadata_k8s.go index 92e3f4ff14..9b307a7fec 100644 --- a/pkg/cloud/metadata_k8s.go +++ b/pkg/cloud/metadata_k8s.go @@ -45,31 +45,33 @@ func KubernetesAPIInstanceInfo(clientset kubernetes.Interface) (*Metadata, error return nil, fmt.Errorf("node providerID empty, cannot parse") } - awsRegionRegex := "(snow)|(([a-z]{2}(-gov)?)-(central|(north|south)?(east|west)?)-[0-9])" - awsAvailabilityZoneRegex := "(snow)|(([a-z]{2}(-gov)?)-(central|(north|south)?(east|west)?)-[0-9][a-z])" awsInstanceIDRegex := "s\\.i-[a-z0-9]+|i-[a-z0-9]+$" - re := regexp.MustCompile(awsRegionRegex) - region := re.FindString(providerID) - if region == "" { - return nil, fmt.Errorf("did not find aws region in node providerID string") - } - - re = regexp.MustCompile(awsAvailabilityZoneRegex) - availabilityZone := re.FindString(providerID) - if availabilityZone == "" { - return nil, fmt.Errorf("did not find aws availability zone in node providerID string") - } - - re = regexp.MustCompile(awsInstanceIDRegex) + re := regexp.MustCompile(awsInstanceIDRegex) instanceID := re.FindString(providerID) if instanceID == "" { return nil, fmt.Errorf("did not find aws instance ID in node providerID string") } var instanceType string - if it, ok := node.GetLabels()[corev1.LabelInstanceTypeStable]; ok { - instanceType = it + if val, ok := node.GetLabels()[corev1.LabelInstanceTypeStable]; ok { + instanceType = val + } else { + return nil, fmt.Errorf("could not retrieve instance type from topology label") + } + + var region string + if val, ok := node.GetLabels()[corev1.LabelTopologyRegion]; ok { + region = val + } else { + return nil, fmt.Errorf("could not retrieve region from topology label") + } + + var availabilityZone string + if val, ok := node.GetLabels()[corev1.LabelTopologyZone]; ok { + availabilityZone = val + } else { + return nil, fmt.Errorf("could not retrieve AZ from topology label") } instanceInfo := Metadata{ diff --git a/pkg/cloud/metadata_test.go b/pkg/cloud/metadata_test.go index 81a949a7d6..fc90e1f270 100644 --- a/pkg/cloud/metadata_test.go +++ b/pkg/cloud/metadata_test.go @@ -130,6 +130,8 @@ func TestNewMetadataService(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ "node.kubernetes.io/instance-type": stdInstanceType, + "topology.kubernetes.io/region": stdRegion, + "topology.kubernetes.io/zone": stdAvailabilityZone, }, Name: nodeName, }, @@ -179,38 +181,46 @@ func TestNewMetadataService(t *testing.T) { nodeNameEnvVar: nodeName, }, { - name: "failure: metadata not available, invalid region", + name: "failure: metadata not available, could not retrieve region", ec2metadataAvailable: false, - expectedErr: fmt.Errorf("did not find aws region in node providerID string"), + expectedErr: fmt.Errorf("could not retrieve region from topology label"), node: v1.Node{ TypeMeta: metav1.TypeMeta{ Kind: "Node", APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "node.kubernetes.io/instance-type": stdInstanceType, + "topology.kubernetes.io/zone": stdAvailabilityZone, + }, Name: nodeName, }, Spec: v1.NodeSpec{ - ProviderID: "aws:///us-est-2b/i-abcdefgh123456789", // invalid region + ProviderID: "aws:///" + stdAvailabilityZone + "/" + stdInstanceID, }, Status: v1.NodeStatus{}, }, nodeNameEnvVar: nodeName, }, { - name: "failure: metadata not available, invalid az", + name: "failure: metadata not available, could not retrieve AZ", ec2metadataAvailable: false, - expectedErr: fmt.Errorf("did not find aws availability zone in node providerID string"), + expectedErr: fmt.Errorf("could not retrieve AZ from topology label"), node: v1.Node{ TypeMeta: metav1.TypeMeta{ Kind: "Node", APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "node.kubernetes.io/instance-type": stdInstanceType, + "topology.kubernetes.io/region": stdRegion, + }, Name: nodeName, }, Spec: v1.NodeSpec{ - ProviderID: "aws:///us-west-21/i-abcdefgh123456789", // invalid AZ + ProviderID: "aws:///" + stdAvailabilityZone + "/" + stdInstanceID, }, Status: v1.NodeStatus{}, }, @@ -226,6 +236,11 @@ func TestNewMetadataService(t *testing.T) { APIVersion: "v1", }, ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "node.kubernetes.io/instance-type": stdInstanceType, + "topology.kubernetes.io/region": stdRegion, + "topology.kubernetes.io/zone": stdAvailabilityZone, + }, Name: nodeName, }, Spec: v1.NodeSpec{