@@ -17,6 +17,7 @@ limitations under the License.
17
17
package scheduling_test
18
18
19
19
import (
20
+ "fmt"
20
21
"time"
21
22
22
23
. "github.com/onsi/gomega"
@@ -1120,7 +1121,7 @@ var _ = Describe("Topology", func() {
1120
1121
Skip ("NodeTaintsPolicy ony enabled by default for K8s >= 1.26.x" )
1121
1122
}
1122
1123
1123
- const spreadLabel = "karpenter.sh/ fake-label"
1124
+ const spreadLabel = "fake-label"
1124
1125
nodePool .Spec .Template .Labels = map [string ]string {
1125
1126
spreadLabel : "baz" ,
1126
1127
}
@@ -1194,7 +1195,7 @@ var _ = Describe("Topology", func() {
1194
1195
if env .Version .Minor () < 26 {
1195
1196
Skip ("NodeTaintsPolicy ony enabled by default for K8s >= 1.26.x" )
1196
1197
}
1197
- const spreadLabel = "karpenter.sh/ fake-label"
1198
+ const spreadLabel = "fake-label"
1198
1199
nodePool .Spec .Template .Labels = map [string ]string {
1199
1200
spreadLabel : "baz" ,
1200
1201
}
@@ -1263,23 +1264,83 @@ var _ = Describe("Topology", func() {
1263
1264
// and should schedule all of the pods on the same node
1264
1265
ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (5 ))
1265
1266
})
1266
- FIt ("should balance pods across a label when discovered from the provisioner (NodeTaintsPolicy=honor)" , func () {
1267
+ It ("should balance pods across a label when discovered from the provisioner (NodeTaintsPolicy=ignore)" , func () {
1268
+ const spreadLabel = "fake-label"
1269
+ const taintKey = "taint-key"
1270
+ nodePool .Spec .Template .Spec .Requirements = append (nodePool .Spec .Template .Spec .Requirements , v1.NodeSelectorRequirement {
1271
+ Key : spreadLabel ,
1272
+ Operator : v1 .NodeSelectorOpIn ,
1273
+ Values : []string {"foo" },
1274
+ })
1275
+ taintedNodePool := test .NodePool (v1beta1.NodePool {
1276
+ Spec : v1beta1.NodePoolSpec {
1277
+ Template : v1beta1.NodeClaimTemplate {
1278
+ Spec : v1beta1.NodeClaimSpec {
1279
+ Taints : []v1.Taint {
1280
+ {
1281
+ Key : taintKey ,
1282
+ Value : "taint-value" ,
1283
+ Effect : v1 .TaintEffectNoSchedule ,
1284
+ },
1285
+ },
1286
+ Requirements : []v1.NodeSelectorRequirement {
1287
+ {
1288
+ Key : v1beta1 .CapacityTypeLabelKey ,
1289
+ Operator : v1 .NodeSelectorOpExists ,
1290
+ },
1291
+ {
1292
+ Key : spreadLabel ,
1293
+ Operator : v1 .NodeSelectorOpIn ,
1294
+ Values : []string {"bar" },
1295
+ },
1296
+ },
1297
+ },
1298
+ },
1299
+ },
1300
+ })
1301
+
1302
+ honor := v1 .NodeInclusionPolicyIgnore
1303
+ topology := []v1.TopologySpreadConstraint {{
1304
+ TopologyKey : spreadLabel ,
1305
+ WhenUnsatisfiable : v1 .DoNotSchedule ,
1306
+ LabelSelector : & metav1.LabelSelector {MatchLabels : labels },
1307
+ MaxSkew : 1 ,
1308
+ NodeTaintsPolicy : & honor ,
1309
+ }}
1310
+
1311
+ pods := test .UnschedulablePods (test.PodOptions {
1312
+ ObjectMeta : metav1.ObjectMeta {
1313
+ Labels : labels ,
1314
+ },
1315
+ TopologySpreadConstraints : topology ,
1316
+ }, 2 )
1317
+
1318
+ ExpectApplied (ctx , env .Client , nodePool , taintedNodePool )
1319
+ ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pods ... )
1320
+
1321
+ // should fail to schedule both pods, one pod is scheduled to domain "foo" but the other can't be scheduled to domain "bar"
1322
+ ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (1 ))
1323
+ })
1324
+ It ("should balance pods across a label when discovered from the provisioner (NodeTaintsPolicy=honor)" , func () {
1267
1325
if env .Version .Minor () < 26 {
1268
1326
Skip ("NodeTaintsPolicy ony enabled by default for K8s >= 1.26.x" )
1269
1327
}
1270
- const spreadLabel = "karpenter.sh/fake-label"
1271
- nodePool .Spec .Template .Labels = map [string ]string {
1272
- spreadLabel : "baz" ,
1273
- }
1274
1328
1275
- nodePoolTainted := test .NodePool (v1beta1.NodePool {
1329
+ const spreadLabel = "fake-label"
1330
+ const taintKey = "taint-key"
1331
+ nodePool .Spec .Template .Spec .Requirements = append (nodePool .Spec .Template .Spec .Requirements , v1.NodeSelectorRequirement {
1332
+ Key : spreadLabel ,
1333
+ Operator : v1 .NodeSelectorOpIn ,
1334
+ Values : []string {"foo" },
1335
+ })
1336
+ taintedNodePool := test .NodePool (v1beta1.NodePool {
1276
1337
Spec : v1beta1.NodePoolSpec {
1277
1338
Template : v1beta1.NodeClaimTemplate {
1278
1339
Spec : v1beta1.NodeClaimSpec {
1279
1340
Taints : []v1.Taint {
1280
1341
{
1281
- Key : "taintname" ,
1282
- Value : "taintvalue " ,
1342
+ Key : taintKey ,
1343
+ Value : "taint-value " ,
1283
1344
Effect : v1 .TaintEffectNoSchedule ,
1284
1345
},
1285
1346
},
@@ -1291,17 +1352,14 @@ var _ = Describe("Topology", func() {
1291
1352
{
1292
1353
Key : spreadLabel ,
1293
1354
Operator : v1 .NodeSelectorOpIn ,
1294
- Values : []string {"foo" , " bar" },
1355
+ Values : []string {"bar" },
1295
1356
},
1296
1357
},
1297
1358
},
1298
1359
},
1299
1360
},
1300
1361
})
1301
1362
1302
- ExpectApplied (ctx , env .Client , nodePool , nodePoolTainted )
1303
-
1304
- ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov )
1305
1363
honor := v1 .NodeInclusionPolicyHonor
1306
1364
topology := []v1.TopologySpreadConstraint {{
1307
1365
TopologyKey : spreadLabel ,
@@ -1311,20 +1369,80 @@ var _ = Describe("Topology", func() {
1311
1369
NodeTaintsPolicy : & honor ,
1312
1370
}}
1313
1371
1314
- ExpectApplied (ctx , env .Client , nodePool )
1315
- ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov ,
1316
- test .UnschedulablePods (test.PodOptions {
1317
- ObjectMeta : metav1.ObjectMeta {Labels : labels },
1318
- ResourceRequirements : v1.ResourceRequirements {
1319
- Requests : v1.ResourceList {
1320
- v1 .ResourceCPU : resource .MustParse ("1" ),
1372
+ pods := test .UnschedulablePods (test.PodOptions {
1373
+ ObjectMeta : metav1.ObjectMeta {
1374
+ Labels : labels ,
1375
+ },
1376
+ TopologySpreadConstraints : topology ,
1377
+ }, 2 )
1378
+
1379
+ ExpectApplied (ctx , env .Client , nodePool , taintedNodePool )
1380
+ ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pods ... )
1381
+
1382
+ // should schedule all pods to domain "foo", ignoring bar since pods don't tolerate
1383
+ ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (2 ))
1384
+ })
1385
+ It ("should balance pods across a label when mutually exclusive NodePools (by taints) share domains (NodeTaintsPolicy=honor)" , func () {
1386
+ const spreadLabel = "fake-label"
1387
+ const taintKey = "taint-key"
1388
+
1389
+ nodePools := lo .Map ([][]string {{"foo" , "bar" }, {"foo" , "baz" }}, func (domains []string , i int ) * v1beta1.NodePool {
1390
+ return test .NodePool (v1beta1.NodePool {
1391
+ Spec : v1beta1.NodePoolSpec {
1392
+ Template : v1beta1.NodeClaimTemplate {
1393
+ Spec : v1beta1.NodeClaimSpec {
1394
+ Taints : []v1.Taint {
1395
+ {
1396
+ Key : taintKey ,
1397
+ Value : fmt .Sprintf ("nodepool-%d" , i ),
1398
+ Effect : v1 .TaintEffectNoSchedule ,
1399
+ },
1400
+ },
1401
+ Requirements : []v1.NodeSelectorRequirement {
1402
+ {
1403
+ Key : v1beta1 .CapacityTypeLabelKey ,
1404
+ Operator : v1 .NodeSelectorOpExists ,
1405
+ },
1406
+ {
1407
+ Key : spreadLabel ,
1408
+ Operator : v1 .NodeSelectorOpIn ,
1409
+ Values : domains ,
1410
+ },
1411
+ },
1412
+ },
1321
1413
},
1322
1414
},
1415
+ })
1416
+ })
1417
+
1418
+ honor := v1 .NodeInclusionPolicyHonor
1419
+ topology := []v1.TopologySpreadConstraint {{
1420
+ TopologyKey : spreadLabel ,
1421
+ WhenUnsatisfiable : v1 .DoNotSchedule ,
1422
+ LabelSelector : & metav1.LabelSelector {MatchLabels : labels },
1423
+ MaxSkew : 1 ,
1424
+ NodeTaintsPolicy : & honor ,
1425
+ }}
1426
+
1427
+ pods := lo .Flatten (lo .Map (nodePools , func (np * v1beta1.NodePool , _ int ) []* v1.Pod {
1428
+ return test .UnschedulablePods (test.PodOptions {
1429
+ ObjectMeta : metav1.ObjectMeta {
1430
+ Labels : labels ,
1431
+ },
1323
1432
TopologySpreadConstraints : topology ,
1324
- }, 5 )... ,
1325
- )
1326
- // and should schedule all of the pods on the same node
1327
- ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (5 ))
1433
+ Tolerations : []v1.Toleration {{
1434
+ Key : taintKey ,
1435
+ Effect : v1 .TaintEffectNoSchedule ,
1436
+ Value : np .Spec .Template .Spec .Taints [0 ].Value ,
1437
+ }},
1438
+ }, 2 )
1439
+ }))
1440
+
1441
+ ExpectApplied (ctx , env .Client , nodePools [0 ], nodePools [1 ])
1442
+ ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pods ... )
1443
+
1444
+ // Expect 3 total nodes provisioned, 2 pods schedule to foo, 1 to bar, and 1 to baz
1445
+ ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (1 , 2 , 1 ))
1328
1446
})
1329
1447
})
1330
1448
@@ -1333,8 +1451,8 @@ var _ = Describe("Topology", func() {
1333
1451
if env .Version .Minor () < 26 {
1334
1452
Skip ("NodeAffinityPolicy ony enabled by default for K8s >= 1.26.x" )
1335
1453
}
1336
- const spreadLabel = "karpenter.sh/ fake-label"
1337
- const affinityLabel = "karpenter.sh/ selector"
1454
+ const spreadLabel = "fake-label"
1455
+ const affinityLabel = "selector"
1338
1456
const affinityMismatch = "mismatch"
1339
1457
const affinityMatch = "value"
1340
1458
@@ -1404,8 +1522,8 @@ var _ = Describe("Topology", func() {
1404
1522
if env .Version .Minor () < 26 {
1405
1523
Skip ("NodeAffinityPolicy ony enabled by default for K8s >= 1.26.x" )
1406
1524
}
1407
- const spreadLabel = "karpenter.sh/ fake-label"
1408
- const affinityLabel = "karpenter.sh/ selector"
1525
+ const spreadLabel = "fake-label"
1526
+ const affinityLabel = "selector"
1409
1527
const affinityMismatch = "mismatch"
1410
1528
const affinityMatch = "value"
1411
1529
0 commit comments