Skip to content

Commit

Permalink
feat(rwx): share manager pod respects the storageClass.allowedTopologies
Browse files Browse the repository at this point in the history
In the Longhorn storage system, a share manager pod of a rwx volume is created on a random node.
The purpose of this update is to enhance the locality of an RWX volume and its share manager pod.
It accomplishes this by converting the storageClass.allowedTopologies setting into an affinity
configuration for the share manager pod. As a result, both the pod and the RWX volume respect
this affinity, ensuring their allocation to an optimal node.

Longhorn 7872

Signed-off-by: Derek Su <derek.su@suse.com>
  • Loading branch information
derekbit committed Apr 10, 2024
1 parent b74a1c7 commit 845acdf
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions controller/share_manager_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,36 @@ func (c *ShareManagerController) syncShareManagerPod(sm *longhorn.ShareManager)
return nil
}

func (c *ShareManagerController) getAffinityFromStorageClass(sc *storagev1.StorageClass) *corev1.Affinity {
var matchLabelExpressions []corev1.NodeSelectorRequirement

for _, topology := range sc.AllowedTopologies {
for _, expression := range topology.MatchLabelExpressions {
matchLabelExpressions = append(matchLabelExpressions, corev1.NodeSelectorRequirement{
Key: expression.Key,
Operator: corev1.NodeSelectorOpIn,
Values: expression.Values,
})
}
}

if len(matchLabelExpressions) == 0 {
return nil
}

return &corev1.Affinity{
NodeAffinity: &corev1.NodeAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: &corev1.NodeSelector{
NodeSelectorTerms: []corev1.NodeSelectorTerm{
{
MatchExpressions: matchLabelExpressions,
},
},
},
},
}
}

func (c *ShareManagerController) getShareManagerNodeSelectorFromStorageClass(sc *storagev1.StorageClass) map[string]string {
value, ok := sc.Parameters["shareManagerNodeSelector"]
if !ok {
Expand Down Expand Up @@ -815,15 +845,18 @@ func (c *ShareManagerController) createShareManagerPod(sm *longhorn.ShareManager
return nil, err
}

var affinity *corev1.Affinity
if pv.Spec.StorageClassName != "" {
sc, err := c.ds.GetStorageClass(pv.Spec.StorageClassName)
if err != nil {
c.logger.WithError(err).Warnf("Failed to get storage class %v, will continue the share manager pod creation", pv.Spec.StorageClassName)
} else {
affinity = c.getAffinityFromStorageClass(sc)

// Find the node selector from the storage class and merge it with the system managed components node selector
if nodeSelector == nil {
nodeSelector = map[string]string{}
}
// Find the node selector from the storage class and merge it with the system managed components node selector
nodeSelectorFromStorageClass := c.getShareManagerNodeSelectorFromStorageClass(sc)
for k, v := range nodeSelectorFromStorageClass {
nodeSelector[k] = v
Expand Down Expand Up @@ -855,7 +888,7 @@ func (c *ShareManagerController) createShareManagerPod(sm *longhorn.ShareManager
string(secret.Data[csi.CryptoPBKDF]))
}

manifest := c.createPodManifest(sm, annotations, tolerations, imagePullPolicy, nil, registrySecret,
manifest := c.createPodManifest(sm, annotations, tolerations, affinity, imagePullPolicy, nil, registrySecret,
priorityClass, nodeSelector, fsType, mountOptions, cryptoKey, cryptoParams)
pod, err := c.ds.CreatePod(manifest)
if err != nil {
Expand Down Expand Up @@ -891,7 +924,7 @@ func (c *ShareManagerController) createServiceManifest(sm *longhorn.ShareManager
}

func (c *ShareManagerController) createPodManifest(sm *longhorn.ShareManager, annotations map[string]string, tolerations []corev1.Toleration,
pullPolicy corev1.PullPolicy, resourceReq *corev1.ResourceRequirements, registrySecret, priorityClass string,
affinity *corev1.Affinity, pullPolicy corev1.PullPolicy, resourceReq *corev1.ResourceRequirements, registrySecret, priorityClass string,
nodeSelector map[string]string, fsType string, mountOptions []string, cryptoKey string, cryptoParams *crypto.EncryptParams) *corev1.Pod {

// command args for the share-manager
Expand All @@ -915,6 +948,7 @@ func (c *ShareManagerController) createPodManifest(sm *longhorn.ShareManager, an
OwnerReferences: datastore.GetOwnerReferencesForShareManager(sm, true),
},
Spec: corev1.PodSpec{
Affinity: affinity,
ServiceAccountName: c.serviceAccount,
Tolerations: util.GetDistinctTolerations(tolerations),
NodeSelector: nodeSelector,
Expand Down

0 comments on commit 845acdf

Please sign in to comment.