Skip to main content
NetApp artificial intelligence solutions
La version française est une traduction automatique. La version anglaise prévaut sur la française en cas de divergence.

Configuration du cluster Milvus avec Kubernetes sur site

Cette section décrit la configuration du cluster Milvus pour la solution de base de données vectorielle pour NetApp.

Configuration du cluster Milvus avec Kubernetes sur site

Les défis des clients sont de pouvoir évoluer indépendamment en termes de stockage et de calcul, de gestion efficace de l'infrastructure et de gestion des données. Kubernetes et les bases de données vectorielles forment ensemble une solution puissante et évolutive pour la gestion des opérations de données volumineuses. Kubernetes optimise les ressources et gère les conteneurs, tandis que les bases de données vectorielles gèrent efficacement les données de grande dimension et les recherches de similarité. Cette combinaison permet un traitement rapide de requêtes complexes sur de grands ensembles de données et s'adapte de manière transparente aux volumes de données croissants, ce qui la rend idéale pour les applications Big Data et les charges de travail d'IA.

  1. Dans cette section, nous détaillons le processus d’installation d’un cluster Milvus sur Kubernetes, en utilisant un contrôleur de stockage NetApp pour les données du cluster et les données client.

  2. Pour installer un cluster Milvus, des volumes persistants (PV) sont nécessaires pour stocker les données de divers composants du cluster Milvus. Ces composants incluent etcd (trois instances), pulsar-bookie-journal (trois instances), pulsar-bookie-ledgers (trois instances) et pulsar-zookeeper-data (trois instances).

    Remarque Dans le cluster Milvus, nous pouvons utiliser Pulsar ou Kafka pour le moteur sous-jacent prenant en charge le stockage fiable et la publication/l'abonnement des flux de messages du cluster Milvus. Pour Kafka avec NFS, NetApp a apporté des améliorations à ONTAP 9.12.1 et versions ultérieures. Ces améliorations, ainsi que les modifications apportées à NFSv4.1 et Linux incluses dans RHEL 8.7 ou 9.1 et versions ultérieures, résolvent le problème de « renommage inutile » qui peut survenir lors de l'exécution de Kafka sur NFS. Si vous souhaitez obtenir des informations plus détaillées sur l'exécution de Kafka avec la solution NetApp NFS, veuillez consulter :"ce lien" .
  3. Nous avons créé un seul volume NFS à partir de NetApp ONTAP et établi 12 volumes persistants, chacun avec 250 Go de stockage. La taille de stockage peut varier en fonction de la taille du cluster ; par exemple, nous avons un autre cluster où chaque PV dispose de 50 Go. Veuillez vous référer ci-dessous à l'un des fichiers PV YAML pour plus de détails ; nous avions 12 de ces fichiers au total. Dans chaque fichier, le storageClassName est défini sur « default », et le stockage et le chemin sont uniques à chaque PV.

    root@node2:~# cat sai_nfs_to_default_pv1.yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: karthik-pv1
    spec:
      capacity:
        storage: 250Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: default
      local:
        path: /vectordbsc/milvus/milvus1
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - node2
              - node3
              - node4
              - node5
              - node6
    root@node2:~#
  4. Exécutez la commande « kubectl apply » pour chaque fichier PV YAML pour créer les volumes persistants, puis vérifiez leur création à l'aide de « kubectl get pv ».

    root@node2:~# for i in $( seq 1 12 ); do kubectl apply -f sai_nfs_to_default_pv$i.yaml; done
    persistentvolume/karthik-pv1 created
    persistentvolume/karthik-pv2 created
    persistentvolume/karthik-pv3 created
    persistentvolume/karthik-pv4 created
    persistentvolume/karthik-pv5 created
    persistentvolume/karthik-pv6 created
    persistentvolume/karthik-pv7 created
    persistentvolume/karthik-pv8 created
    persistentvolume/karthik-pv9 created
    persistentvolume/karthik-pv10 created
    persistentvolume/karthik-pv11 created
    persistentvolume/karthik-pv12 created
    root@node2:~#
  5. Pour stocker les données client, Milvus prend en charge les solutions de stockage d'objets telles que MinIO, Azure Blob et S3. Dans ce guide, nous utilisons S3. Les étapes suivantes s’appliquent à la fois au magasin d’objets ONTAP S3 et StorageGRID . Nous utilisons Helm pour déployer le cluster Milvus. Téléchargez le fichier de configuration, values.yaml, à partir de l'emplacement de téléchargement de Milvus. Veuillez vous référer à l'annexe pour le fichier values.yaml que nous avons utilisé dans ce document.

  6. Assurez-vous que la « classe de stockage » est définie sur « par défaut » dans chaque section, y compris celles du journal, etcd, zookeeper et bookkeeper.

  7. Dans la section MinIO, désactivez MinIO.

  8. Créez un bucket NAS à partir du stockage d'objets ONTAP ou StorageGRID et incluez-les dans un S3 externe avec les informations d'identification de stockage d'objets.

    ###################################
    # External S3
    # - these configs are only used when `externalS3.enabled` is true
    ###################################
    externalS3:
      enabled: true
      host: "192.168.150.167"
      port: "80"
      accessKey: "24G4C1316APP2BIPDE5S"
      secretKey: "Zd28p43rgZaU44PX_ftT279z9nt4jBSro97j87Bx"
      useSSL: false
      bucketName: "milvusdbvol1"
      rootPath: ""
      useIAM: false
      cloudProvider: "aws"
      iamEndpoint: ""
      region: ""
      useVirtualHost: false
  9. Avant de créer le cluster Milvus, assurez-vous que le PersistentVolumeClaim (PVC) ne dispose d'aucune ressource préexistante.

    root@node2:~# kubectl get pvc
    No resources found in default namespace.
    root@node2:~#
  10. Utilisez Helm et le fichier de configuration values.yaml pour installer et démarrer le cluster Milvus.

    root@node2:~# helm upgrade --install my-release milvus/milvus --set global.storageClass=default  -f values.yaml
    Release "my-release" does not exist. Installing it now.
    NAME: my-release
    LAST DEPLOYED: Thu Mar 14 15:00:07 2024
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    root@node2:~#
  11. Vérifiez l’état des PersistentVolumeClaims (PVC).

    root@node2:~# kubectl get pvc
    NAME                                                             STATUS   VOLUME         CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    data-my-release-etcd-0                                           Bound    karthik-pv8    250Gi      RWO            default        3s
    data-my-release-etcd-1                                           Bound    karthik-pv5    250Gi      RWO            default        2s
    data-my-release-etcd-2                                           Bound    karthik-pv4    250Gi      RWO            default        3s
    my-release-pulsar-bookie-journal-my-release-pulsar-bookie-0      Bound    karthik-pv10   250Gi      RWO            default        3s
    my-release-pulsar-bookie-journal-my-release-pulsar-bookie-1      Bound    karthik-pv3    250Gi      RWO            default        3s
    my-release-pulsar-bookie-journal-my-release-pulsar-bookie-2      Bound    karthik-pv1    250Gi      RWO            default        3s
    my-release-pulsar-bookie-ledgers-my-release-pulsar-bookie-0      Bound    karthik-pv2    250Gi      RWO            default        3s
    my-release-pulsar-bookie-ledgers-my-release-pulsar-bookie-1      Bound    karthik-pv9    250Gi      RWO            default        3s
    my-release-pulsar-bookie-ledgers-my-release-pulsar-bookie-2      Bound    karthik-pv11   250Gi      RWO            default        3s
    my-release-pulsar-zookeeper-data-my-release-pulsar-zookeeper-0   Bound    karthik-pv7    250Gi      RWO            default        3s
    root@node2:~#
  12. Vérifiez l'état des pods.

    root@node2:~# kubectl get pods -o wide
    NAME                                            READY   STATUS      RESTARTS        AGE    IP              NODE    NOMINATED NODE   READINESS GATES
    <content removed to save page space>

    Veuillez vous assurer que l'état des pods est « en cours d'exécution » et fonctionne comme prévu

  13. Écriture et lecture de données de test dans le stockage d'objets Milvus et NetApp .

    • Écrivez des données à l'aide du programme Python « prepare_data_netapp_new.py ».

      root@node2:~# date;python3 prepare_data_netapp_new.py ;date
      Thu Apr  4 04:15:35 PM UTC 2024
      === start connecting to Milvus     ===
      === Milvus host: localhost         ===
      Does collection hello_milvus_ntapnew_update2_sc exist in Milvus: False
      === Drop collection - hello_milvus_ntapnew_update2_sc ===
      === Drop collection - hello_milvus_ntapnew_update2_sc2 ===
      === Create collection `hello_milvus_ntapnew_update2_sc` ===
      === Start inserting entities       ===
      Number of entities in hello_milvus_ntapnew_update2_sc: 3000
      Thu Apr  4 04:18:01 PM UTC 2024
      root@node2:~#
    • Lisez les données à l'aide du fichier Python « verify_data_netapp.py ».

      root@node2:~# python3 verify_data_netapp.py
      === start connecting to Milvus     ===
      === Milvus host: localhost         ===
      
      Does collection hello_milvus_ntapnew_update2_sc exist in Milvus: True
      {'auto_id': False, 'description': 'hello_milvus_ntapnew_update2_sc', 'fields': [{'name': 'pk', 'description': '', 'type': <DataType.INT64: 5>, 'is_primary': True, 'auto_id': False}, {'name': 'random', 'description': '', 'type': <DataType.DOUBLE: 11>}, {'name': 'var', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 65535}}, {'name': 'embeddings', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 16}}]}
      Number of entities in Milvus: hello_milvus_ntapnew_update2_sc : 3000
      
      === Start Creating index IVF_FLAT  ===
      
      === Start loading                  ===
      
      === Start searching based on vector similarity ===
      
      hit: id: 2998, distance: 0.0, entity: {'random': 0.9728033590489911}, random field: 0.9728033590489911
      hit: id: 2600, distance: 0.602496862411499, entity: {'random': 0.3098157043984633}, random field: 0.3098157043984633
      hit: id: 1831, distance: 0.6797959804534912, entity: {'random': 0.6331477114129169}, random field: 0.6331477114129169
      hit: id: 2999, distance: 0.0, entity: {'random': 0.02316334456872482}, random field: 0.02316334456872482
      hit: id: 2524, distance: 0.5918987989425659, entity: {'random': 0.285283165889066}, random field: 0.285283165889066
      hit: id: 264, distance: 0.7254047393798828, entity: {'random': 0.3329096143562196}, random field: 0.3329096143562196
      search latency = 0.4533s
      
      === Start querying with `random > 0.5` ===
      
      query result:
      -{'random': 0.6378742006852851, 'embeddings': [0.20963514, 0.39746657, 0.12019053, 0.6947492, 0.9535575, 0.5454552, 0.82360446, 0.21096309, 0.52323616, 0.8035404, 0.77824664, 0.80369574, 0.4914803, 0.8265614, 0.6145269, 0.80234545], 'pk': 0}
      search latency = 0.4476s
      
      === Start hybrid searching with `random > 0.5` ===
      
      hit: id: 2998, distance: 0.0, entity: {'random': 0.9728033590489911}, random field: 0.9728033590489911
      hit: id: 1831, distance: 0.6797959804534912, entity: {'random': 0.6331477114129169}, random field: 0.6331477114129169
      hit: id: 678, distance: 0.7351570129394531, entity: {'random': 0.5195484662306603}, random field: 0.5195484662306603
      hit: id: 2644, distance: 0.8620758056640625, entity: {'random': 0.9785952878381153}, random field: 0.9785952878381153
      hit: id: 1960, distance: 0.9083120226860046, entity: {'random': 0.6376039340439571}, random field: 0.6376039340439571
      hit: id: 106, distance: 0.9792704582214355, entity: {'random': 0.9679994241326673}, random field: 0.9679994241326673
      search latency = 0.1232s
      Does collection hello_milvus_ntapnew_update2_sc2 exist in Milvus: True
      {'auto_id': True, 'description': 'hello_milvus_ntapnew_update2_sc2', 'fields': [{'name': 'pk', 'description': '', 'type': <DataType.INT64: 5>, 'is_primary': True, 'auto_id': True}, {'name': 'random', 'description': '', 'type': <DataType.DOUBLE: 11>}, {'name': 'var', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 65535}}, {'name': 'embeddings', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 16}}]}

      Sur la base de la validation ci-dessus, l'intégration de Kubernetes avec une base de données vectorielle, comme démontré par le déploiement d'un cluster Milvus sur Kubernetes à l'aide d'un contrôleur de stockage NetApp , offre aux clients une solution robuste, évolutive et efficace pour la gestion des opérations de données à grande échelle. Cette configuration offre aux clients la possibilité de gérer des données de grande dimension et d’exécuter des requêtes complexes rapidement et efficacement, ce qui en fait une solution idéale pour les applications Big Data et les charges de travail d’IA. L'utilisation de volumes persistants (PV) pour divers composants de cluster, ainsi que la création d'un volume NFS unique à partir de NetApp ONTAP, garantissent une utilisation optimale des ressources et une gestion des données. Le processus de vérification de l'état des PersistentVolumeClaims (PVC) et des pods, ainsi que le test de l'écriture et de la lecture des données, offrent aux clients l'assurance d'opérations de données fiables et cohérentes. L’utilisation du stockage d’objets ONTAP ou StorageGRID pour les données client améliore encore l’accessibilité et la sécurité des données. Dans l’ensemble, cette configuration offre aux clients une solution de gestion de données résiliente et performante, capable de s’adapter de manière transparente à leurs besoins croissants en matière de données.