@@ -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"
@@ -1132,7 +1133,7 @@ var _ = Describe("Topology", func() {
1132
1133
Skip ("NodeTaintsPolicy ony enabled by default for K8s >= 1.26.x" )
1133
1134
}
1134
1135
1135
- const spreadLabel = "karpenter.sh/ fake-label"
1136
+ const spreadLabel = "fake-label"
1136
1137
nodePool .Spec .Template .Labels = map [string ]string {
1137
1138
spreadLabel : "baz" ,
1138
1139
}
@@ -1206,7 +1207,7 @@ var _ = Describe("Topology", func() {
1206
1207
if env .Version .Minor () < 26 {
1207
1208
Skip ("NodeTaintsPolicy ony enabled by default for K8s >= 1.26.x" )
1208
1209
}
1209
- const spreadLabel = "karpenter.sh/ fake-label"
1210
+ const spreadLabel = "fake-label"
1210
1211
nodePool .Spec .Template .Labels = map [string ]string {
1211
1212
spreadLabel : "baz" ,
1212
1213
}
@@ -1275,23 +1276,83 @@ var _ = Describe("Topology", func() {
1275
1276
// and should schedule all of the pods on the same node
1276
1277
ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (5 ))
1277
1278
})
1278
- FIt ("should balance pods across a label when discovered from the provisioner (NodeTaintsPolicy=honor)" , func () {
1279
+ It ("should balance pods across a label when discovered from the provisioner (NodeTaintsPolicy=ignore)" , func () {
1280
+ const spreadLabel = "fake-label"
1281
+ const taintKey = "taint-key"
1282
+ nodePool .Spec .Template .Spec .Requirements = append (nodePool .Spec .Template .Spec .Requirements , v1.NodeSelectorRequirement {
1283
+ Key : spreadLabel ,
1284
+ Operator : v1 .NodeSelectorOpIn ,
1285
+ Values : []string {"foo" },
1286
+ })
1287
+ taintedNodePool := test .NodePool (v1beta1.NodePool {
1288
+ Spec : v1beta1.NodePoolSpec {
1289
+ Template : v1beta1.NodeClaimTemplate {
1290
+ Spec : v1beta1.NodeClaimSpec {
1291
+ Taints : []v1.Taint {
1292
+ {
1293
+ Key : taintKey ,
1294
+ Value : "taint-value" ,
1295
+ Effect : v1 .TaintEffectNoSchedule ,
1296
+ },
1297
+ },
1298
+ Requirements : []v1.NodeSelectorRequirement {
1299
+ {
1300
+ Key : v1beta1 .CapacityTypeLabelKey ,
1301
+ Operator : v1 .NodeSelectorOpExists ,
1302
+ },
1303
+ {
1304
+ Key : spreadLabel ,
1305
+ Operator : v1 .NodeSelectorOpIn ,
1306
+ Values : []string {"bar" },
1307
+ },
1308
+ },
1309
+ },
1310
+ },
1311
+ },
1312
+ })
1313
+
1314
+ honor := v1 .NodeInclusionPolicyIgnore
1315
+ topology := []v1.TopologySpreadConstraint {{
1316
+ TopologyKey : spreadLabel ,
1317
+ WhenUnsatisfiable : v1 .DoNotSchedule ,
1318
+ LabelSelector : & metav1.LabelSelector {MatchLabels : labels },
1319
+ MaxSkew : 1 ,
1320
+ NodeTaintsPolicy : & honor ,
1321
+ }}
1322
+
1323
+ pods := test .UnschedulablePods (test.PodOptions {
1324
+ ObjectMeta : metav1.ObjectMeta {
1325
+ Labels : labels ,
1326
+ },
1327
+ TopologySpreadConstraints : topology ,
1328
+ }, 2 )
1329
+
1330
+ ExpectApplied (ctx , env .Client , nodePool , taintedNodePool )
1331
+ ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pods ... )
1332
+
1333
+ // should fail to schedule both pods, one pod is scheduled to domain "foo" but the other can't be scheduled to domain "bar"
1334
+ ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (1 ))
1335
+ })
1336
+ It ("should balance pods across a label when discovered from the provisioner (NodeTaintsPolicy=honor)" , func () {
1279
1337
if env .Version .Minor () < 26 {
1280
1338
Skip ("NodeTaintsPolicy ony enabled by default for K8s >= 1.26.x" )
1281
1339
}
1282
- const spreadLabel = "karpenter.sh/fake-label"
1283
- nodePool .Spec .Template .Labels = map [string ]string {
1284
- spreadLabel : "baz" ,
1285
- }
1286
1340
1287
- nodePoolTainted := test .NodePool (v1beta1.NodePool {
1341
+ const spreadLabel = "fake-label"
1342
+ const taintKey = "taint-key"
1343
+ nodePool .Spec .Template .Spec .Requirements = append (nodePool .Spec .Template .Spec .Requirements , v1.NodeSelectorRequirement {
1344
+ Key : spreadLabel ,
1345
+ Operator : v1 .NodeSelectorOpIn ,
1346
+ Values : []string {"foo" },
1347
+ })
1348
+ taintedNodePool := test .NodePool (v1beta1.NodePool {
1288
1349
Spec : v1beta1.NodePoolSpec {
1289
1350
Template : v1beta1.NodeClaimTemplate {
1290
1351
Spec : v1beta1.NodeClaimSpec {
1291
1352
Taints : []v1.Taint {
1292
1353
{
1293
- Key : "taintname" ,
1294
- Value : "taintvalue " ,
1354
+ Key : taintKey ,
1355
+ Value : "taint-value " ,
1295
1356
Effect : v1 .TaintEffectNoSchedule ,
1296
1357
},
1297
1358
},
@@ -1303,17 +1364,14 @@ var _ = Describe("Topology", func() {
1303
1364
{
1304
1365
Key : spreadLabel ,
1305
1366
Operator : v1 .NodeSelectorOpIn ,
1306
- Values : []string {"foo" , " bar" },
1367
+ Values : []string {"bar" },
1307
1368
},
1308
1369
},
1309
1370
},
1310
1371
},
1311
1372
},
1312
1373
})
1313
1374
1314
- ExpectApplied (ctx , env .Client , nodePool , nodePoolTainted )
1315
-
1316
- ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov )
1317
1375
honor := v1 .NodeInclusionPolicyHonor
1318
1376
topology := []v1.TopologySpreadConstraint {{
1319
1377
TopologyKey : spreadLabel ,
@@ -1323,20 +1381,80 @@ var _ = Describe("Topology", func() {
1323
1381
NodeTaintsPolicy : & honor ,
1324
1382
}}
1325
1383
1326
- ExpectApplied (ctx , env .Client , nodePool )
1327
- ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov ,
1328
- test .UnschedulablePods (test.PodOptions {
1329
- ObjectMeta : metav1.ObjectMeta {Labels : labels },
1330
- ResourceRequirements : v1.ResourceRequirements {
1331
- Requests : v1.ResourceList {
1332
- v1 .ResourceCPU : resource .MustParse ("1" ),
1384
+ pods := test .UnschedulablePods (test.PodOptions {
1385
+ ObjectMeta : metav1.ObjectMeta {
1386
+ Labels : labels ,
1387
+ },
1388
+ TopologySpreadConstraints : topology ,
1389
+ }, 2 )
1390
+
1391
+ ExpectApplied (ctx , env .Client , nodePool , taintedNodePool )
1392
+ ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pods ... )
1393
+
1394
+ // should schedule all pods to domain "foo", ignoring bar since pods don't tolerate
1395
+ ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (2 ))
1396
+ })
1397
+ It ("should balance pods across a label when mutually exclusive NodePools (by taints) share domains (NodeTaintsPolicy=honor)" , func () {
1398
+ const spreadLabel = "fake-label"
1399
+ const taintKey = "taint-key"
1400
+
1401
+ nodePools := lo .Map ([][]string {{"foo" , "bar" }, {"foo" , "baz" }}, func (domains []string , i int ) * v1beta1.NodePool {
1402
+ return test .NodePool (v1beta1.NodePool {
1403
+ Spec : v1beta1.NodePoolSpec {
1404
+ Template : v1beta1.NodeClaimTemplate {
1405
+ Spec : v1beta1.NodeClaimSpec {
1406
+ Taints : []v1.Taint {
1407
+ {
1408
+ Key : taintKey ,
1409
+ Value : fmt .Sprintf ("nodepool-%d" , i ),
1410
+ Effect : v1 .TaintEffectNoSchedule ,
1411
+ },
1412
+ },
1413
+ Requirements : []v1.NodeSelectorRequirement {
1414
+ {
1415
+ Key : v1beta1 .CapacityTypeLabelKey ,
1416
+ Operator : v1 .NodeSelectorOpExists ,
1417
+ },
1418
+ {
1419
+ Key : spreadLabel ,
1420
+ Operator : v1 .NodeSelectorOpIn ,
1421
+ Values : domains ,
1422
+ },
1423
+ },
1424
+ },
1333
1425
},
1334
1426
},
1427
+ })
1428
+ })
1429
+
1430
+ honor := v1 .NodeInclusionPolicyHonor
1431
+ topology := []v1.TopologySpreadConstraint {{
1432
+ TopologyKey : spreadLabel ,
1433
+ WhenUnsatisfiable : v1 .DoNotSchedule ,
1434
+ LabelSelector : & metav1.LabelSelector {MatchLabels : labels },
1435
+ MaxSkew : 1 ,
1436
+ NodeTaintsPolicy : & honor ,
1437
+ }}
1438
+
1439
+ pods := lo .Flatten (lo .Map (nodePools , func (np * v1beta1.NodePool , _ int ) []* v1.Pod {
1440
+ return test .UnschedulablePods (test.PodOptions {
1441
+ ObjectMeta : metav1.ObjectMeta {
1442
+ Labels : labels ,
1443
+ },
1335
1444
TopologySpreadConstraints : topology ,
1336
- }, 5 )... ,
1337
- )
1338
- // and should schedule all of the pods on the same node
1339
- ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (5 ))
1445
+ Tolerations : []v1.Toleration {{
1446
+ Key : taintKey ,
1447
+ Effect : v1 .TaintEffectNoSchedule ,
1448
+ Value : np .Spec .Template .Spec .Taints [0 ].Value ,
1449
+ }},
1450
+ }, 2 )
1451
+ }))
1452
+
1453
+ ExpectApplied (ctx , env .Client , nodePools [0 ], nodePools [1 ])
1454
+ ExpectProvisioned (ctx , env .Client , cluster , cloudProvider , prov , pods ... )
1455
+
1456
+ // Expect 3 total nodes provisioned, 2 pods schedule to foo, 1 to bar, and 1 to baz
1457
+ ExpectSkew (ctx , env .Client , "default" , & topology [0 ]).To (ConsistOf (1 , 2 , 1 ))
1340
1458
})
1341
1459
})
1342
1460
@@ -1345,8 +1463,8 @@ var _ = Describe("Topology", func() {
1345
1463
if env .Version .Minor () < 26 {
1346
1464
Skip ("NodeAffinityPolicy ony enabled by default for K8s >= 1.26.x" )
1347
1465
}
1348
- const spreadLabel = "karpenter.sh/ fake-label"
1349
- const affinityLabel = "karpenter.sh/ selector"
1466
+ const spreadLabel = "fake-label"
1467
+ const affinityLabel = "selector"
1350
1468
const affinityMismatch = "mismatch"
1351
1469
const affinityMatch = "value"
1352
1470
@@ -1416,8 +1534,8 @@ var _ = Describe("Topology", func() {
1416
1534
if env .Version .Minor () < 26 {
1417
1535
Skip ("NodeAffinityPolicy ony enabled by default for K8s >= 1.26.x" )
1418
1536
}
1419
- const spreadLabel = "karpenter.sh/ fake-label"
1420
- const affinityLabel = "karpenter.sh/ selector"
1537
+ const spreadLabel = "fake-label"
1538
+ const affinityLabel = "selector"
1421
1539
const affinityMismatch = "mismatch"
1422
1540
const affinityMatch = "value"
1423
1541
0 commit comments