Skip to content

Commit

Permalink
Merge pull request #2737 from jiamin13579/affinity
Browse files Browse the repository at this point in the history
pod admission  mutate patch affinity
  • Loading branch information
volcano-sh-bot authored Apr 10, 2023
2 parents 6250653 + 7197a6a commit bed4a04
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
77 changes: 76 additions & 1 deletion docs/design/multi-scheduler.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ The configmap defines some resource groups, each resource group contains
- Annotation field
- The pod's data volcano needs to patch, volcano support to patch the fields and the fields are optional and not mandatory. User can set them according the application scenario.
- Tolerations
- NodeSelector
- Affinity
- NodeSelector
- SchedulerName

If the object field is not setted, it is filled with a default as the following:
Expand Down Expand Up @@ -67,6 +68,14 @@ data:
schedulerName: volcano # the annotation key is fixed and is "volcano.sh/resource-group", The corresponding value is the resourceGroup field
labels:
volcano.sh/nodetype: gpu
- resourceGroup: fixed # if the object is unsetted, default is: the key is annotation,
schedulerName: volcano # the annotation key is fixed and is "volcano.sh/resource-group", The corresponding value is the resourceGroup field
object:
key: annotation
value:
- "volcano.sh/resource-group-job-role: master"
# set the affinity for patching, the format is a json string.
affinity: "{\"nodeAffinity\":{\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"volcano.sh/nodetype\",\"operator\":\"In\",\"values\":[\"fixed\"]}]}]}}}"
````

### The pod mutate process
Expand Down Expand Up @@ -205,6 +214,72 @@ schedulerName: volcano
The pod in job-A is scheduled to node1.
The pod in job-B job is scheduled to node2.
````

### case 3

Here is a cluster as the following:

|node|label|
|----|-----|
|node1| volcano.sh/nodetype: fixed|
|node2| none| none|

|volcano job | annotation|
|----|----|
|job-A|volcano.sh/resource-group-job-role: master|
|job-B|none|

1. Edit volcano-admission-configmap
````
apiVersion: v1
kind: ConfigMap
metadata:
name: volcano-admission-configmap
namespace: volcano-system
data:
volcano-admission.conf: |
resourceGroups:
- resourceGroup: fixed # if the object is unsetted, default is: the key is annotation,
schedulerName: volcano # the annotation key is fixed and is "volcano.sh/resource-group", The corresponding value is the resourceGroup field
object:
key: annotation
value:
- "volcano.sh/resource-group-job-role: master"
# set the affinity for patching, the format is a json string.
affinity: "{\"nodeAffinity\":{\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"volcano.sh/nodetype",\"operator\":\"In\",\"values\":[\"fixed\"]}]}]}}}"
````
2. Submit job-A and job-B

3. Check the Pod information

````
job-A:
....
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: volcano.sh/nodetype
operator: In
values:
- fixed
...
schedulerName: volcano
....
job-B:
....
...
schedulerName: volcano
....
````
4. Check the result of the pod's scheduling
````
The pod in job-A is scheduled to node1.
The pod in job-B job is scheduled to node1/node2.
````

## NOTE

Enable this feature may modify pod information and affect resource utilization.
Expand Down
27 changes: 27 additions & 0 deletions pkg/webhooks/admission/pods/mutate/mutate_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ func createPatch(pod *v1.Pod) ([]byte, error) {
patch = append(patch, *patchLabel)
}

patchAffinity := patchAffinity(pod, resourceGroup)
if patchAffinity != nil {
patch = append(patch, *patchAffinity)
}

patchToleration := patchTaintToleration(pod, resourceGroup)
if patchToleration != nil {
patch = append(patch, *patchToleration)
Expand Down Expand Up @@ -156,6 +161,28 @@ func patchLabels(pod *v1.Pod, resGroupConfig wkconfig.ResGroupConfig) *patchOper
return &patchOperation{Op: "add", Path: "/spec/nodeSelector", Value: nodeSelector}
}

// patchAffinity patch affinity
func patchAffinity(pod *v1.Pod, resGroupConfig wkconfig.ResGroupConfig) *patchOperation {
if resGroupConfig.Affinity == "" {
return nil
}

if pod.Spec.Affinity != nil {
klog.V(5).Infof("pod affinity exist: %s", pod.Name)
return nil
}

var affinity v1.Affinity
err := json.Unmarshal([]byte(resGroupConfig.Affinity), &affinity)
if err != nil {
fmt.Println("Failed to unmarshal JSON:", err)
klog.V(3).Infof("Failed to unmarshal JSON: %s", err)
return nil
}

return &patchOperation{Op: "add", Path: "/spec/affinity", Value: affinity}
}

// patchTaintToleration patch taint toleration
func patchTaintToleration(pod *v1.Pod, resGroupConfig wkconfig.ResGroupConfig) *patchOperation {
if len(resGroupConfig.Tolerations) == 0 {
Expand Down
9 changes: 9 additions & 0 deletions pkg/webhooks/admission/pods/mutate/mutate_pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import (
)

func TestMutatePods(t *testing.T) {
affinityJsonStr := `{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"kubernetes.io/os","operator":"In","values":["linux"]}]}]}}}`
var affinity v1.Affinity
json.Unmarshal([]byte(affinityJsonStr), &affinity)

admissionConfigData := &webconfig.AdmissionConfiguration{
ResGroupsConfig: []webconfig.ResGroupConfig{
Expand All @@ -48,6 +51,7 @@ func TestMutatePods(t *testing.T) {
Effect: v1.TaintEffectNoSchedule,
},
},
Affinity: affinityJsonStr,
Labels: map[string]string{
"volcano.sh/nodetype": "management",
},
Expand Down Expand Up @@ -105,6 +109,11 @@ func TestMutatePods(t *testing.T) {
"volcano.sh/nodetype": "management",
},
},
{
Op: "add",
Path: "/spec/affinity",
Value: affinity,
},
{
Op: "add",
Path: "/spec/tolerations",
Expand Down
1 change: 1 addition & 0 deletions pkg/webhooks/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type ResGroupConfig struct {
SchedulerName string `yaml:"schedulerName"`
Tolerations []v1.Toleration `yaml:"tolerations"`
Labels map[string]string `yaml:"labels"`
Affinity string `yaml:"affinity"`
}

// AdmissionConfiguration defines the configuration of admission.
Expand Down

0 comments on commit bed4a04

Please sign in to comment.