milvus-logo
LFAI
Casa

(Deprecato) Distribuzione di un cluster Milvus su EC2

Questo argomento descrive come distribuire un cluster Milvus su Amazon EC2 con Terraform e Ansible.

Questo argomento è obsoleto e sarà presto rimosso. Si consiglia di consultare invece Deploy di un cluster Milvus su EKS.

Provisionare un cluster Milvus

Questa sezione descrive come utilizzare Terraform per il provisioning di un cluster Milvus.

Terraform è uno strumento software IaC (Infrastructure as Code). Con Terraform è possibile eseguire il provisioning dell'infrastruttura utilizzando file di configurazione dichiarativi.

Prerequisiti

Preparare la configurazione

È possibile scaricare i file di configurazione modello da Google Drive.

  • main.tf

    Questo file contiene la configurazione per il provisioning di un cluster Milvus.

  • variables.tf

    Questo file consente di modificare rapidamente le variabili utilizzate per impostare o aggiornare un cluster Milvus.

  • output.tf e inventory.tmpl

    Questi file memorizzano i metadati di un cluster Milvus. I metadati utilizzati in questo argomento sono public_ip per ogni istanza di nodo, private_ip per ogni istanza di nodo e tutti gli ID delle istanze EC2.

Preparare variables.tf

Questa sezione descrive la configurazione che un file variables.tf contiene.

  • Numero di nodi

    Il modello seguente dichiara una variabile index_count usata per impostare il numero di nodi dell'indice.

    Il valore di index_count deve essere maggiore o uguale a uno.
    variable "index_count" {
      description = "Amount of index instances to run"
      type        = number
      default     = 5
    }
    
  • Tipo di istanza per un tipo di nodo

    Il modello seguente dichiara una variabile index_ec2_type utilizzata per impostare il tipo di istanza per i nodi indice.

    variable "index_ec2_type" {
      description = "Which server type"
      type        = string
      default     = "c5.2xlarge"
    }
    
  • Permesso di accesso

    Il modello seguente dichiara una variabile key_name e una variabile my_ip. La variabile key_name rappresenta la chiave di accesso AWS. La variabile my_ip rappresenta l'intervallo di indirizzi IP per un gruppo di sicurezza.

    variable "key_name" {
      description = "Which aws key to use for access into instances, needs to be uploaded already"
      type        = string
      default     = ""
    }
    
    variable "my_ip" {
      description = "my_ip for security group. used so that ansible and terraform can ssh in"
      type        = string
      default     = "x.x.x.x/32"
    }
    

Preparare main.tf

Questa sezione descrive le configurazioni che un file main.tf contiene.

  • Provider cloud e regione

    Il modello seguente utilizza la regione us-east-2. Per ulteriori informazioni, vedere Regioni disponibili.

    provider "aws" {
      profile = "default"
      region  = "us-east-2"
    }
    
  • Gruppo di sicurezza

    Il modello seguente dichiara un gruppo di sicurezza che consente il traffico in entrata dall'intervallo di indirizzi CIDR rappresentato da my_ip dichiarato in variables.tf.

    resource "aws_security_group" "cluster_sg" {
      name        = "cluster_sg"
      description = "Allows only me to access"
      vpc_id      = aws_vpc.cluster_vpc.id
    
      ingress {
        description      = "All ports from my IP"
        from_port        = 0
        to_port          = 65535
        protocol         = "tcp"
        cidr_blocks      = [var.my_ip]
      }
    
      ingress {
        description      = "Full subnet communication"
        from_port        = 0
        to_port          = 65535
        protocol         = "all"
        self             = true
      }
    
      egress {
        from_port        = 0
        to_port          = 0
        protocol         = "-1"
        cidr_blocks      = ["0.0.0.0/0"]
        ipv6_cidr_blocks = ["::/0"]
      }
    
      tags = {
        Name = "cluster_sg"
      }
    }
    
  • VPC

    Il modello seguente specifica una VPC con il blocco CIDR 10.0.0.0/24 su un cluster Milvus.

    resource "aws_vpc" "cluster_vpc" {
      cidr_block = "10.0.0.0/24"
      tags = {
        Name = "cluster_vpc"
      }
    }
    
    resource "aws_internet_gateway" "cluster_gateway" {
      vpc_id = aws_vpc.cluster_vpc.id
    
      tags = {
        Name = "cluster_gateway"
      }
    }
    
  • Sottoreti (opzionale)

    Il modello seguente dichiara una sottorete il cui traffico è instradato verso un gateway Internet. In questo caso, la dimensione del blocco CIDR della sottorete è uguale a quella del blocco CIDR della VPC.

    resource "aws_subnet" "cluster_subnet" {
      vpc_id                  = aws_vpc.cluster_vpc.id
      cidr_block              = "10.0.0.0/24"
      map_public_ip_on_launch = true
    
      tags = {
        Name = "cluster_subnet"
      }
    }
    
    resource "aws_route_table" "cluster_subnet_gateway_route" {
      vpc_id       = aws_vpc.cluster_vpc.id
    
      route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.cluster_gateway.id
      }
    
      tags = {
        Name = "cluster_subnet_gateway_route"
      }
    }
    
    resource "aws_route_table_association" "cluster_subnet_add_gateway" {
      subnet_id      = aws_subnet.cluster_subnet.id
      route_table_id = aws_route_table.cluster_subnet_gateway_route.id
    }
    
    
  • Istanze di nodo (Nodi)

    Il modello seguente dichiara un'istanza di nodo MinIO. Il file di modello main.tf dichiara nodi di 11 tipi di nodi. Per alcuni tipi di nodo, è necessario impostare root_block_device. Per ulteriori informazioni, vedere Dispositivi a blocchi EBS, effimeri e radice.

    resource "aws_instance" "minio_node" {
      count         = var.minio_count
      ami           = "ami-0d8d212151031f51c"
      instance_type = var.minio_ec2_type
      key_name      = var.key_name
      subnet_id     = aws_subnet.cluster_subnet.id 
      vpc_security_group_ids = [aws_security_group.cluster_sg.id]
    
      root_block_device {
        volume_type = "gp2"
        volume_size = 1000
      }
      
      tags = {
        Name = "minio-${count.index + 1}"
      }
    }
    

Applicare la configurazione

  1. Aprire un terminale e navigare nella cartella in cui è memorizzato main.tf.

  2. Per inizializzare la configurazione, eseguire terraform init.

  3. Per applicare la configurazione, eseguire terraform apply e immettere yes quando richiesto.

A questo punto è stato effettuato il provisioning di un cluster Milvus con Terraform.

Avviare il cluster Milvus

Questa sezione descrive come utilizzare Ansible per avviare il cluster Milvus di cui si è fatto il provisioning.

Ansible è uno strumento di gestione della configurazione utilizzato per automatizzare il provisioning e la gestione della configurazione del cloud.

Prerequisiti

Scaricare il Playbook per la distribuzione dei nodi Milvus di Ansible.

Clonare il repository Milvus da GitHub per scaricare il Playbook per la distribuzione dei nodi di Ansible Milvus.

git clone https://github.com/milvus-io/milvus.git

Configurare i file di installazione

I file inventory.ini e ansible.cfg sono usati per controllare le variabili d'ambiente e i metodi di verifica del login nel playbook di Ansible. Nel file inventory.ini, la sezione dockernodes definisce tutti i server dei motori docker. La sezione ansible.cfg definisce tutti i server dei coordinatori Milvus. La sezione node definisce tutti i server dei nodi Milvus.

Inserire il percorso locale del Playbook e configurare i file di installazione.

$ cd ./milvus/deployments/docker/cluster-distributed-deployment

inventory.ini

Configurare inventory.ini per dividere gli host in gruppi in base al loro ruolo nel sistema Milvus.

Aggiungere i nomi degli host e definire i gruppi docker e vars.

[dockernodes] #Add docker host names.
dockernode01
dockernode02
dockernode03

[admin] #Add Ansible controller name.
ansible-controller

[coords] #Add the host names of Milvus coordinators.
; Take note the IP of this host VM, and replace 10.170.0.17 with it.
dockernode01

[nodes] #Add the host names of Milvus nodes.
dockernode02

[dependencies] #Add the host names of Milvus dependencies.
; dependencies node will host etcd, minio, pulsar, these 3 roles are the foundation of Milvus. 
; Take note the IP of this host VM, and replace 10.170.0.19 with it.
dockernode03

[docker:children]
dockernodes
coords
nodes
dependencies

[docker:vars]
ansible_python_interpreter= /usr/bin/python3
StrictHostKeyChecking= no

; Setup variables to control what type of network to use when creating containers.
dependencies_network= host
nodes_network= host

; Setup varibale to control what version of Milvus image to use.
image= milvusdb/milvus-dev:master-20220412-4781db8a

; Setup static IP addresses of the docker hosts as variable for container environment variable config.
; Before running the playbook, below 4 IP addresses need to be replaced with the IP of your host VM
; on which the etcd, minio, pulsar, coordinators will be hosted.
etcd_ip= 10.170.0.19
minio_ip= 10.170.0.19
pulsar_ip= 10.170.0.19
coords_ip= 10.170.0.17

; Setup container environment which later will be used in container creation.
ETCD_ENDPOINTS= {{etcd_ip}}:2379 
MINIO_ADDRESS= {{minio_ip}}:9000
PULSAR_ADDRESS= pulsar://{{pulsar_ip}}:6650
QUERY_COORD_ADDRESS= {{coords_ip}}:19531
DATA_COORD_ADDRESS= {{coords_ip}}:13333
ROOT_COORD_ADDRESS= {{coords_ip}}:53100
INDEX_COORD_ADDRESS= {{coords_ip}}:31000

ansible.cfg

ansible.cfg controlla l'azione del playbook, ad esempio la chiave SSH, ecc. Non impostare la passphrase tramite la chiave SSH sugli host docker. Altrimenti, la connessione SSH di Ansible fallirà. Si consiglia di impostare lo stesso nome utente e la stessa chiave SSH sui tre host e di impostare il nuovo account utente per eseguire sudo senza password. In caso contrario, si riceveranno errori che indicano che il nome utente non corrisponde alla password o che non sono stati concessi privilegi elevati durante l'esecuzione del playbook di Ansible.

[defaults]
host_key_checking = False
inventory = inventory.ini # Specify the Inventory file
private_key_file=~/.my_ssh_keys/gpc_sshkey # Specify the SSH key that Ansible uses to access Docker host

deploy-docker.yml

deploy-docker.yml definisce le attività durante l'installazione di Docker. Vedere i commenti al codice nel file per i dettagli.

---
- name: setup pre-requisites # Install prerequisite
  hosts: all
  become: yes
  become_user: root
  roles:
    - install-modules
    - configure-hosts-file

- name: install docker
  become: yes
  become_user: root
  hosts: dockernodes
  roles:
    - docker-installation

Test della connettività di Ansible

Verificare la connettività con Ansible.

$ ansible all -m ping

Aggiungere -i al comando per specificare il percorso del file di inventario se non è stato specificato in ansible.cfg, altrimenti Ansible usa /etc/ansible/hosts.

Il terminale restituisce il seguente risultato:

dockernode01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
ansible-controller | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
dockernode03 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
dockernode02 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Controllare la sintassi del Playbook

Controllare la sintassi del Playbook.

$ ansible-playbook deploy-docker.yml --syntax-check

Normalmente, il terminale restituisce il seguente messaggio:

playbook: deploy-docker.yml

Installa Docker

Installare Docker con il Playbook.

$ ansible-playbook deploy-docker.yml

Se Docker è stato installato correttamente sui tre host, il terminale restituisce il seguente messaggio:

TASK [docker-installation : Install Docker-CE] *******************************************************************
ok: [dockernode01]
ok: [dockernode03]
ok: [dockernode02]

TASK [docker-installation : Install python3-docker] **************************************************************
ok: [dockernode01]
ok: [dockernode02]
ok: [dockernode03]

TASK [docker-installation : Install docker-compose python3 library] **********************************************
changed: [dockernode01]
changed: [dockernode03]
changed: [dockernode02]

PLAY RECAP *******************************************************************************************************
ansible-controller         : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
dockernode01               : ok=10   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
dockernode02               : ok=10   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
dockernode03               : ok=10   changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Verifica dell'installazione

Accedere ai tre host con la chiave SSH e verificare l'installazione sugli host.

  • Per l'host root:
$ docker -v
  • Per gli host non root:
$ sudo docker -v

Normalmente, il terminale restituisce il seguente messaggio:

Docker version 20.10.14, build a224086

Controllare lo stato di esecuzione dei container.

$ docker ps

Controllare la sintassi

Controllare la sintassi di deploy-milvus.yml.

$ ansible-playbook deploy-milvus.yml --syntax-check

Normalmente, il terminale restituisce il seguente messaggio:

playbook: deploy-milvus.yml

Creare il contenitore Milvus

I compiti per creare il contenitore Milvus sono definiti in deploy-milvus.yml.

$ ansible-playbook deploy-milvus.yml

Il terminale restituisce:

PLAY [Create milvus-etcd, minio, pulsar] *****************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [dockernode03]

TASK [etcd] *******************************************************************************************************
changed: [dockernode03]

TASK [pulsar] *****************************************************************************************************
changed: [dockernode03]

TASK [minio] ******************************************************************************************************
changed: [dockernode03]

PLAY [Create milvus nodes] ****************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [dockernode02]

TASK [querynode] **************************************************************************************************
changed: [dockernode02]

TASK [datanode] ***************************************************************************************************
changed: [dockernode02]

TASK [indexnode] **************************************************************************************************
changed: [dockernode02]

PLAY [Create milvus coords] ***************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [dockernode01]

TASK [rootcoord] **************************************************************************************************
changed: [dockernode01]

TASK [datacoord] **************************************************************************************************
changed: [dockernode01]

TASK [querycoord] *************************************************************************************************
changed: [dockernode01]

TASK [indexcoord] *************************************************************************************************
changed: [dockernode01]

TASK [proxy] ******************************************************************************************************
changed: [dockernode01]

PLAY RECAP ********************************************************************************************************
dockernode01               : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
dockernode02               : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
dockernode03               : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Ora Milvus è distribuito sui tre host.

Arresto dei nodi

È possibile arrestare tutti i nodi quando non si ha più bisogno di un cluster Milvus.

Assicuratevi che il binario terraform sia disponibile sul vostro PATH.
  1. Eseguite terraform destroy e inserite yes quando richiesto.

  2. In caso di successo, tutte le istanze dei nodi vengono fermate.

Cosa fare dopo

Se volete imparare a distribuire Milvus su altri cloud:

Tradotto daDeepL

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Questa pagina è stata utile?