diff --git a/internal/services/providers/eks/eks.go b/internal/services/providers/eks/eks.go index 0ede83ba..370bdbd5 100644 --- a/internal/services/providers/eks/eks.go +++ b/internal/services/providers/eks/eks.go @@ -174,6 +174,10 @@ func determineLifecycle(n *v1.Node) nodeLifecycle { return NodeLifecycleSpot } + if val, ok := n.Labels[labels.WorkerSpot]; ok && val == "true" { + return NodeLifecycleSpot + } + if val, ok := n.Labels[labels.KarpenterCapacityType]; ok { if val == labels.ValueKarpenterCapacityTypeSpot { return NodeLifecycleSpot diff --git a/internal/services/providers/eks/eks_test.go b/internal/services/providers/eks/eks_test.go index 96fd3c1e..87e81ebd 100644 --- a/internal/services/providers/eks/eks_test.go +++ b/internal/services/providers/eks/eks_test.go @@ -83,6 +83,27 @@ func TestProvider_IsSpot(t *testing.T) { r.Equal([]*v1.Node{node}, got) }) + t.Run("spot instance worker label", func(t *testing.T) { + r := require.New(t) + awsClient := mock_client.NewMockClient(gomock.NewController(t)) + + p := &Provider{ + log: logrus.New(), + awsClient: awsClient, + apiNodeLifecycleDiscoveryEnabled: true, + spotCache: map[string]bool{}, + } + + node := &v1.Node{ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{ + labels.WorkerSpot: "true", + }}} + + got, err := p.FilterSpot(context.Background(), []*v1.Node{node}) + + r.NoError(err) + r.Equal([]*v1.Node{node}, got) + }) + t.Run("spot instance CAST AI label", func(t *testing.T) { r := require.New(t) awsClient := mock_client.NewMockClient(gomock.NewController(t)) diff --git a/pkg/labels/labels.go b/pkg/labels/labels.go index 0075f4ba..46ebef60 100644 --- a/pkg/labels/labels.go +++ b/pkg/labels/labels.go @@ -6,6 +6,7 @@ const ( CastaiFakeSpot = "scheduling.cast.ai/fake-spot" KopsSpot = "spot" KarpenterCapacityType = "karpenter.sh/capacity-type" + WorkerSpot = "node-role.kubernetes.io/spot-worker" ValueKarpenterCapacityTypeSpot = "spot" ValueKarpenterCapacityTypeOnDemand = "on-demand"