Tous les produits
Search
Centre de documentation

Container Service for Kubernetes:Schedule pods based on cache affinity

Dernière mise à jour :Aug 11, 2026

Le webhook de mutation de Fluid injecte des règles d'affinité dans les spécifications des pods afin que le planificateur kube-scheduler place les pods d'application sur les nœuds contenant les données mises en cache. Si aucun nœud disposant du cache n'est disponible, les pods sont placés sur des nœuds situés dans la même zone ou la même région que le cache. Avec Fluid, vous pouvez :

  • Planifier les pods sur le nœud contenant les données mises en cache (affinité de nœud, pondération 100)

  • Planifier les pods sur n'importe quel nœud de la même zone que le cache (affinité de zone, pondération 50)

  • Planifier les pods sur n'importe quel nœud de la même région que le cache (affinité de région, pondération 20)

  • Forcer le placement des pods sur les nœuds contenant le cache lorsque la localité des données est critique (affinité requise)

  • Éloigner les pods qui n'utilisent pas de datasets des nœuds contenant le cache pour réduire la contention des ressources

Limites

Prérequis

Avant de commencer, assurez-vous d'avoir :

Fonctionnement

Lors de la création d'un pod, le webhook de mutation de Fluid lit les étiquettes du pod et le Dataset référencé, puis injecte des règles nodeAffinity dans la spécification du pod avant que kube-scheduler n'évalue le placement. Par défaut, les règles injectées utilisent preferredDuringSchedulingIgnoredDuringExecution (affinité souple). Pour forcer un placement strict sur les nœuds contenant le cache, ajoutez l'étiquette fluid.io/dataset.<dataset_name>.sched: required au pod.

L'ordre de repli est le suivant : nœud → zone → région. Si un pod ne peut pas être placé sur un nœud contenant les données mises en cache, kube-scheduler se rabat sur un nœud de la même zone, puis de la même région, en fonction des pondérations configurées.

Les pods qui ne référencent pas de dataset sont gérés par le plugin PreferNodesWithoutCache qui les éloigne des nœuds réservés à la mise en cache des données.

Configurer la politique de planification

Configuration par défaut

La politique de planification est stockée dans la ConfigMap webhook-plugins du namespace fluid-system. Pour l'inspecter :

kubectl get cm -n fluid-system webhook-plugins -oyaml

Sortie attendue :

apiVersion: v1
data:
  pluginsProfile: |
    pluginConfig:
    - args: |
        preferred:
          # fluid.io/node: built-in, name cannot be changed. Schedules pods to the node holding cached data.
          - name: fluid.io/node
            weight: 100
          # topology.kubernetes.io/zone: schedules pods to nodes in the same zone as the cache. Adjust key for your cluster.
          - name: topology.kubernetes.io/zone
            weight: 50
          # topology.kubernetes.io/region: schedules pods to nodes in the same region as the cache. Adjust key for your cluster.
          - name: topology.kubernetes.io/region
            weight: 20
        # required: applies when a pod carries the label fluid.io/dataset.{dataset name}.sched=required
        required:
          - fluid.io/node
      name: NodeAffinityWithCache
    plugins:
      serverful:
        withDataset:
        - RequireNodeWithFuse
        - NodeAffinityWithCache
        - MountPropagationInjector
        withoutDataset:
        - PreferNodesWithoutCache
      serverless:
        withDataset:
        - FuseSidecar
        withoutDataset: []

La liste preferred contrôle les pondérations de l'affinité souple. La liste required définit quelle étiquette doit correspondre lorsqu'un pod opte pour une planification stricte. Le nom fluid.io/node dans les deux sections ne peut pas être modifié.

Configuration personnalisée

Les clusters ACK peuvent utiliser différentes étiquettes de nœud pour représenter la topologie. Pour ajouter, supprimer ou remplacer des clés de topologie :

  1. Modifiez la ConfigMap :

    kubectl edit -n fluid-system cm webhook-plugins
  2. Modifiez la liste preferred . Deux scénarios courants sont décrits ci-dessous. Exemple : Ignorer l'affinité de cache au niveau du nœud Mettez en commentaire fluid.io/node pour supprimer la préférence de placement au niveau du nœud. Fluid privilégie toujours l'affinité de zone et de région.

    preferred:
      # - name: fluid.io/node   # commented out: node affinity disabled
      #   weight: 100
      - name: topology.kubernetes.io/zone
        weight: 50
      - name: topology.kubernetes.io/region
        weight: 20

    Exemple : Ajouter une affinité de pool de nœuds Insérez une clé de topologie personnalisée entre l'affinité au niveau du nœud et celle au niveau de la zone pour privilégier la planification au sein du même pool de nœuds.

    preferred:
      - name: fluid.io/node
        weight: 100
      - name: alibabacloud.com/nodepool-id   # custom topology key
        weight: 80
      - name: topology.kubernetes.io/zone
        weight: 50
      - name: topology.kubernetes.io/region
        weight: 20
  3. Redémarrez le webhook Fluid pour appliquer les modifications :

    kubectl rollout restart deployment -n fluid-system fluid-webhook

Exemples

Exemple 1 : Affinité de nœud préférée (planification souple)

Cet exemple planifie un pod sur le nœud contenant les données mises en cache. Si aucun nœud disposant du cache n'est planifiable, kube-scheduler se rabat sur l'affinité de zone et de région en fonction des pondérations configurées.

  1. Créez un Secret avec vos identifiants OSS :

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    stringData:
      fs.oss.accessKeyId: <ACCESS_KEY_ID>
      fs.oss.accessKeySecret: <ACCESS_KEY_SECRET>
  2. Créez un Dataset et un JindoRuntime :

    Important

    Cet exemple utilise JindoRuntime. Pour utiliser d'autres runtimes de cache, consultez la rubrique Utiliser EFC pour accélérer l'accès à NAS ou CPFS. Pour l'accélération JindoFS et Object Storage Service (OSS), consultez la rubrique Utiliser JindoFS pour accélérer l'accès à OSS.

    apiVersion: data.fluid.io/v1alpha1
    kind: Dataset
    metadata:
      name: demo-dataset
    spec:
      mounts:
        - mountPoint: oss://<oss_bucket>/<bucket_dir>
          options:
            fs.oss.endpoint: <oss_endpoint>
          name: hadoop
          path: "/"
          encryptOptions:
            - name: fs.oss.accessKeyId
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: fs.oss.accessKeyId
            - name: fs.oss.accessKeySecret
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: fs.oss.accessKeySecret
    ---
    apiVersion: data.fluid.io/v1alpha1
    kind: JindoRuntime
    metadata:
      name: demo-dataset
    spec:
      replicas: 2
      tieredstore:
        levels:
          - mediumtype: MEM
            path: /dev/shm
            quota: 10G
            high: "0.99"
            low: "0.8"
  3. Créez le pod d'application avec l'injection d'affinité activée :

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        fuse.serverful.fluid.io/inject: "true"   # enables Fluid affinity injection
    spec:
      containers:
        - name: nginx
          image: registry.openanolis.cn/openanolis/nginx:1.14.1-8.6
          volumeMounts:
            - mountPath: /data
              name: data-vol
      volumes:
        - name: data-vol
          persistentVolumeClaim:
            claimName: demo-dataset   # PVC auto-created by Fluid, named after the Dataset
  4. Vérifiez que Fluid a injecté la règle d'affinité :

    kubectl get pod nginx -oyaml

    La spécification du pod doit contenir une règle preferredDuringSchedulingIgnoredDuringExecution ciblant le nœud contenant le cache :

    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              - key: fluid.io/s-default-demo-dataset
                operator: In
                values:
                - "true"
            weight: 100
  5. Confirmez que le pod a été planifié sur un nœud contenant le cache :

    kubectl get pod nginx -o custom-columns=NAME:metadata.name,NODE:.spec.nodeName

    Le nœud indiqué doit être l'un des nœuds de travail JindoRuntime où les données sont mises en cache.

Exemple 2 : Affinité de zone préférée (planification souple)

Cet exemple planifie les pods sur n'importe quel nœud de la zone où résident les données mises en cache. Les règles d'affinité au niveau du nœud et de la zone sont toutes deux injectées, de sorte que kube-scheduler tente d'abord de placer les pods sur les nœuds contenant le cache, puis sur les autres nœuds de la même zone.

Pour activer l'affinité de zone, épinglez le Dataset et le maître JindoRuntime sur une zone spécifique.

  1. Créez un Secret (identique à l'exemple 1) :

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    stringData:
      fs.oss.accessKeyId: <ACCESS_KEY_ID>
      fs.oss.accessKeySecret: <ACCESS_KEY_SECRET>
  2. Créez un Dataset et un JindoRuntime, tous deux épinglés sur la zone cible :

    apiVersion: data.fluid.io/v1alpha1
    kind: Dataset
    metadata:
      name: demo-dataset
    spec:
      nodeAffinity:
        required:
          nodeSelectorTerms:
            - matchExpressions:
                - key: topology.kubernetes.io/zone
                  operator: In
                  values:
                  - "<ZONE_ID>"   # e.g., cn-beijing-i
      mounts:
        - mountPoint: oss://<oss_bucket>/<bucket_dir>
          options:
            fs.oss.endpoint: <oss_endpoint>
          name: hadoop
          path: "/"
          encryptOptions:
            - name: fs.oss.accessKeyId
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: fs.oss.accessKeyId
            - name: fs.oss.accessKeySecret
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: fs.oss.accessKeySecret
    ---
    apiVersion: data.fluid.io/v1alpha1
    kind: JindoRuntime
    metadata:
      name: demo-dataset
    spec:
      replicas: 2
      master:
        nodeSelector:
          topology.kubernetes.io/zone: <ZONE_ID>   # e.g., cn-beijing-i
      tieredstore:
        levels:
          - mediumtype: MEM
            path: /dev/shm
            quota: 10G
            high: "0.99"
            low: "0.8"

    La contrainte nodeAffinity.required.nodeSelectorTerms sur le Dataset indique à Fluid dans quelle zone se trouve le cache. Fluid lit cette information pour générer la règle d'affinité au niveau de la zone injectée dans les pods d'application.

  3. Créez le pod d'application :

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        fuse.serverful.fluid.io/inject: "true"
    spec:
      containers:
        - name: nginx
          image: registry.openanolis.cn/openanolis/nginx:1.14.1-8.6
          volumeMounts:
            - mountPath: /data
              name: data-vol
      volumes:
        - name: data-vol
          persistentVolumeClaim:
            claimName: demo-dataset
  4. Vérifiez les règles d'affinité injectées :

    kubectl get pod nginx -oyaml

    Une règle d'affinité au niveau du nœud et une autre au niveau de la zone doivent apparaître :

    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - preference:
              matchExpressions:
              - key: fluid.io/s-default-demo-dataset
                operator: In
                values:
                - "true"
            weight: 100
          - preference:
              matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values:
                - <ZONE_ID>   # e.g., cn-beijing-i
            weight: 50
  5. Confirmez que le pod a été planifié sur un nœud de la zone cible :

    kubectl get pod nginx -o custom-columns=NAME:metadata.name,NODE:.spec.nodeName
    kubectl get node <node_name> --show-labels | grep topology.kubernetes.io/zone

    Le nœud doit porter l'étiquette topology.kubernetes.io/zone=<ZONE_ID> .

Exemple 3 : Affinité de nœud requise (planification stricte)

Cet exemple force le placement du pod sur un nœud contenant les données mises en cache. Si aucun nœud disposant du cache n'est planifiable, le pod reste en attente. Utilisez cette option lorsque la localité des données est non négociable, par exemple pour des travaux d'entraînement sensibles à la latence.

  1. Créez un Secret (identique à l'exemple 1) :

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    stringData:
      fs.oss.accessKeyId: <ACCESS_KEY_ID>
      fs.oss.accessKeySecret: <ACCESS_KEY_SECRET>
  2. Créez un Dataset et un JindoRuntime (identiques à l'exemple 1) :

    apiVersion: data.fluid.io/v1alpha1
    kind: Dataset
    metadata:
      name: demo-dataset
    spec:
      mounts:
        - mountPoint: oss://<oss_bucket>/<bucket_dir>
          options:
            fs.oss.endpoint: <oss_endpoint>
          name: hadoop
          path: "/"
          encryptOptions:
            - name: fs.oss.accessKeyId
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: fs.oss.accessKeyId
            - name: fs.oss.accessKeySecret
              valueFrom:
                secretKeyRef:
                  name: mysecret
                  key: fs.oss.accessKeySecret
    ---
    apiVersion: data.fluid.io/v1alpha1
    kind: JindoRuntime
    metadata:
      name: demo-dataset
    spec:
      replicas: 2
      tieredstore:
        levels:
          - mediumtype: MEM
            path: /dev/shm
            quota: 10G
            high: "0.99"
            low: "0.8"
  3. Créez le pod d'application avec l'étiquette de planification requise :

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        fuse.serverful.fluid.io/inject: "true"
        fluid.io/dataset.demo-dataset.sched: required   # forces hard affinity for demo-dataset
    spec:
      containers:
        - name: nginx
          image: registry.openanolis.cn/openanolis/nginx:1.14.1-8.6
          volumeMounts:
            - mountPath: /data
              name: data-vol
      volumes:
        - name: data-vol
          persistentVolumeClaim:
            claimName: demo-dataset

    Le format de l'étiquette est fluid.io/dataset.<dataset_name>.sched: required . Remplacez <dataset_name> par le nom de votre Dataset.

  4. Vérifiez la règle d'affinité injectée :

    kubectl get pod nginx -oyaml

    Une règle requiredDuringSchedulingIgnoredDuringExecution doit apparaître, empêchant le pod d'être planifié sur tout nœud ne contenant pas les données mises en cache :

    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: fluid.io/s-default-demo-dataset
                operator: In
                values:
                - "true"
  5. Confirmez que le pod a été planifié sur un nœud contenant le cache :

    kubectl get pod nginx -o custom-columns=NAME:metadata.name,NODE:.spec.nodeName

    Le nœud indiqué doit être l'un des nœuds de travail JindoRuntime. Si aucun nœud de ce type n'est disponible, le pod reste dans l'état Pending jusqu'à ce qu'un nœud contenant le cache devienne planifiable.

Étapes suivantes