Skip to main content
NetApp artificial intelligence solutions
Se proporciona el idioma español mediante traducción automática para su comodidad. En caso de alguna inconsistencia, el inglés precede al español.

Configuración de un clúster Milvus con Kubernetes en instalaciones locales

En esta sección se analiza la configuración del clúster milvus para la solución de base de datos vectorial para NetApp.

Configuración de un clúster Milvus con Kubernetes en instalaciones locales

Los desafíos del cliente para escalar de forma independiente en almacenamiento y computación, administración efectiva de la infraestructura y administración de datos, Kubernetes y las bases de datos vectoriales juntas forman una solución poderosa y escalable para administrar operaciones de grandes datos. Kubernetes optimiza los recursos y administra los contenedores, mientras que las bases de datos vectoriales manejan eficientemente datos de alta dimensión y búsquedas de similitud. Esta combinación permite el procesamiento rápido de consultas complejas en grandes conjuntos de datos y se adapta sin problemas a volúmenes de datos crecientes, lo que la hace ideal para aplicaciones de big data y cargas de trabajo de IA.

  1. En esta sección, detallamos el proceso de instalación de un clúster Milvus en Kubernetes, utilizando un controlador de almacenamiento NetApp para los datos del clúster y los datos del cliente.

  2. Para instalar un clúster Milvus, se requieren volúmenes persistentes (PV) para almacenar datos de varios componentes del clúster Milvus. Estos componentes incluyen etcd (tres instancias), pulsar-bookie-journal (tres instancias), pulsar-bookie-ledgers (tres instancias) y pulsar-zookeeper-data (tres instancias).

    Nota En el clúster Milvus, podemos usar Pulsar o Kafka como motor subyacente que respalda el almacenamiento confiable y la publicación/suscripción de flujos de mensajes del clúster Milvus. Para Kafka con NFS, NetApp ha implementado mejoras en ONTAP 9.12.1 y versiones posteriores. Estas mejoras, junto con los cambios en NFSv4.1 y Linux incluidos en RHEL 8.7 o 9.1 y versiones posteriores, resuelven el problema de "cambio de nombre tonto" que puede ocurrir al ejecutar Kafka sobre NFS. Si está interesado en obtener información más detallada sobre la ejecución de Kafka con la solución NFS de NetApp, consulte:"este enlace" .
  3. Creamos un único volumen NFS desde NetApp ONTAP y establecimos 12 volúmenes persistentes, cada uno con 250 GB de almacenamiento. El tamaño de almacenamiento puede variar según el tamaño del clúster; por ejemplo, tenemos otro clúster donde cada PV tiene 50 GB. Consulte a continuación uno de los archivos PV YAML para obtener más detalles; teníamos 12 archivos de este tipo en total. En cada archivo, storageClassName se establece en 'predeterminado' y el almacenamiento y la ruta son únicos para cada 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. Ejecute el comando 'kubectl apply' para cada archivo PV YAML para crear los volúmenes persistentes y luego verifique su creación usando '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. Para almacenar datos de clientes, Milvus admite soluciones de almacenamiento de objetos como MinIO, Azure Blob y S3. En esta guía, utilizamos S3. Los siguientes pasos se aplican tanto al almacén de objetos ONTAP S3 como al StorageGRID . Usamos Helm para implementar el clúster Milvus. Descargue el archivo de configuración, values.yaml, desde la ubicación de descarga de Milvus. Consulte el apéndice para ver el archivo values.yaml que usamos en este documento.

  6. Asegúrese de que 'storageClass' esté configurado como 'predeterminado' en cada sección, incluidas las de registro, etcd, zookeeper y bookkeeper.

  7. En la sección MinIO, desactive MinIO.

  8. Cree un depósito NAS desde el almacenamiento de objetos ONTAP o StorageGRID e inclúyalos en un S3 externo con las credenciales de almacenamiento de objetos.

    ###################################
    # 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. Antes de crear el clúster Milvus, asegúrese de que PersistentVolumeClaim (PVC) no tenga ningún recurso preexistente.

    root@node2:~# kubectl get pvc
    No resources found in default namespace.
    root@node2:~#
  10. Utilice Helm y el archivo de configuración values.yaml para instalar e iniciar el clúster 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. Verificar el estado de los 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. Verifique el estado de los 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>

    Asegúrese de que el estado de los pods sea "en ejecución" y funcione como se espera.

  13. Pruebe la escritura y lectura de datos en el almacenamiento de objetos Milvus y NetApp .

    • Escriba datos utilizando el programa 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:~#
    • Lea los datos utilizando el archivo 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}}]}

      Con base en la validación anterior, la integración de Kubernetes con una base de datos vectorial, como se demostró a través de la implementación de un clúster Milvus en Kubernetes usando un controlador de almacenamiento NetApp , ofrece a los clientes una solución robusta, escalable y eficiente para administrar operaciones de datos a gran escala. Esta configuración brinda a los clientes la capacidad de manejar datos de alta dimensión y ejecutar consultas complejas de manera rápida y eficiente, lo que la convierte en una solución ideal para aplicaciones de big data y cargas de trabajo de IA. El uso de volúmenes persistentes (PV) para varios componentes del clúster, junto con la creación de un único volumen NFS desde NetApp ONTAP, garantiza una utilización óptima de los recursos y la gestión de datos. El proceso de verificar el estado de PersistentVolumeClaims (PVC) y pods, así como probar la escritura y lectura de datos, brinda a los clientes la seguridad de contar con operaciones de datos confiables y consistentes. El uso del almacenamiento de objetos ONTAP o StorageGRID para los datos de los clientes mejora aún más la accesibilidad y la seguridad de los datos. En general, esta configuración brinda a los clientes una solución de gestión de datos resistente y de alto rendimiento que puede escalar sin problemas con sus crecientes necesidades de datos.