在Amazon EKS上设置Milvus
Milvus从一开始就被设计为支持Kubernetes,并且可以轻松部署在AWS上。为了构建一个可靠、弹性的Milvus向量数据库集群,我们可以使用Amazon Elastic Kubernetes Service(Amazon EKS)作为托管的Kubernetes服务,Amazon S3作为对象存储,Amazon Managed Streaming for Apache Kafka(Amazon MSK)作为消息存储,以及Amazon Elastic Load Balancing(Amazon ELB)作为负载均衡器。
Milvus_Architecture_Overview_fd10aeffb8.png
Milvus架构概览
EKS是Amazon的托管Kubernetes服务,它运行在EC2或无服务器的Fargate上。它非常适合已经在使用Kubernetes的本地组织,允许他们将部署迁移到AWS,而无需进行最小化的更改。
这篇博客使用EC2进行部署,因为Fargate无法处理Milvus依赖项(如etcD)所需的持久卷声明(PVCs)。
我们将提供使用EKS和其他服务部署Milvus集群的逐步指导。这篇博客的更详细版本可以在这里找到。
先决条件
AWS CLI
在您的本地PC/Mac或Amazon EC2实例上安装AWS CLI,它将作为本文档中涵盖的操作的端点。如果您使用的是Amazon Linux 2或Amazon Linux 2023,AWS CLI工具默认已安装。参考如何安装AWS CLI。
% which aws
/usr/local/bin/aws
% aws --version
aws-cli/2.15.34 Python/3.11.8 Darwin/23.5.0 exe/x86_64 prompt/off
EKS工具:Kubectl、eksctl、helm
在首选的端点设备上安装EKS工具,包括:
- kubectl
- eksctl
- helm
参考EKS入门指南以获取详细的安装步骤。以下是一个在Mac M2笔记本电脑上使用z shell验证安装和版本的截图:
% kubectl version
Client Version: v1.30.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
# Download eksctl
ARCH=arm64
PLATFORM=$(uname -s)_$ARCH
curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
sudo mv /tmp/eksctl /usr/local/bin
% eksctl version
0.185.0
% helm list --all-namespaces
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-milvus default 1 2024-07-09 16:00:14.117945 -0700 PDT deployed milvus-4.1.34 2.4.5
创建一个Amazon S3存储桶
阅读存储桶命名规则,并在命名AWS S3存储桶时遵守它们,使用AWS控制台。
Create_an_Amazon_S3_Bucket_37e2a9fe03.png
创建一个Amazon S3存储桶
创建一个KMS,客户管理的密钥
KMS密钥不能是AWS管理的密钥。它必须是客户管理的密钥。创建后,您需要等待大约10分钟,直到密钥激活后才能在AWS Secrets Manager中使用。使用AWS控制台,转到KMS > 客户管理的密钥。
Create_a_KMS_Customer_managed_key_de23b579d7.png
创建一个KMS,客户管理的密钥
在AWS Secrets Manager中创建一个自定义密钥
确保在创建KMS客户管理密钥后等待了大约10分钟。现在,创建一个新的AWS Secrets Manager密钥。使用AWS控制台。
- 选择另一种类型的密钥作为密钥类型。
- 将键/值对编辑器切换为纯文本。输入具有完全匹配的“用户名”和“密码”的JSON键。
- 密钥的名称必须以AmazonMSK_开头。
- 加密密钥必须是KMS客户管理的密钥,而不是AWS管理的密钥。
Create_a_custom_secret_in_the_AWS_Secrets_Manager_3f33a9ef75.png
在AWS Secrets Manager中创建一个自定义密钥
创建一个MSK实例
接下来,使用AWS控制台创建一个带有Kafka自动创建主题功能的Amazon MSK集群,并启用SASL/SCRAM安全性。
创建MSK时的注意事项:
Milvus的最新稳定版本(v2.4.x)依赖于Kafka的autoCreateTopics功能,因此创建MSK时需要使用自定义配置,并且需要将auto.create.topics.enable属性从默认的false更改为true。
此外,为了提高MSK的消息吞吐量,建议增加message.max.bytes和replica.fetch.max.bytes的值。
auto.create.topics.enable=true message.max.bytes=10485880 replica.fetch.max.bytes=20971760
有关详细信息,请参见自定义MSK配置。
Create_a_MSK_Instance_704b34bd45.png
创建一个MSK实例
- Milvus不支持MSK的IAM基于角色的认证,因此创建MSK时,在安全配置中启用SASL/SCRAM认证选项,并在AWS Secrets Manager中配置用户名和密码。有关详细信息,请参见使用AWS Secrets Manager进行签名凭据认证。
- MSK的安全组需要允许来自EKS集群的安全组或IP地址范围的访问。
security_settings_f10ab85b9e.jpg
安全设置
等待MSK实例大约15分钟的准备时间。一旦准备好,单击它,您可以关联之前创建的AWS Secrets Manager自定义密钥。
AWS_Secrets_Manager_328687252b.png
AWS Secrets Manager
创建一个Amazon EKS集群
创建EKS集群有很多方法,例如通过控制台、CloudFormation或eksctl。参考文档设置使用Amazon EKS。
本文将使用eksctl。eksctl是一个简单的命令行工具,用于在Amazon EKS上创建和管理Kubernetes集群。eksctl提供了创建新集群和Amazon EKS节点的最快、最简单的方法。有关更多信息,请参考eksctl的官方文档。
步骤1:创建一个eks_cluster.yaml文件。
有关示例.yaml文件,请参见Milvus文档。
- 将集群名称替换为您的集群名称,
- 将region-code替换为您要创建集群的AWS区域代码。
- 将private-subnet-idx替换为您的私有子网。注意:此配置文件通过指定私有子网在现有VPC中创建EKS集群。您也可以删除VPC和子网配置,以便eksctl自动创建一个新的VPC。
步骤2:运行eksctl create cluster -f eks_cluster.yaml命令以创建EKS集群。
create cluster -f eks_cluster.yaml
参考Amazon EKS快速入门。此命令将创建以下资源:
- 一个指定版本的EKS集群。
- 一个带有3个m6i.2xlarge EC2实例的管理节点组。
- 一个IAM OIDC身份提供者和一个名为aws-load-balancer-controller的ServiceAccount,稍后将在安装AWS负载均衡器控制器时使用。
- 一个名为milvus的命名空间,以及在此命名空间内名为milvus-s3-access-sa的ServiceAccount。稍后将在配置Milvus的对象存储为S3时使用。
- 注意:为简单起见,milvus-s3-access-sa被授予了完整的S3访问权限。在生产部署中,建议遵循最小权限原则,仅授予对Milvus使用的特定S3存储桶的访问权限。
- 多个附加组件,其中vpc-cni、coredns、kube-proxy是EKS所需的核心附加组件。aws-ebs-csi-driver是AWS EBS CSI驱动程序,允许EKS集群管理Amazon EBS卷的生命周期。
% eksctl create cluster -f eks_cluster.yaml
2024-07-10 17:45:32 [ℹ] eksctl version 0.185.0
2024-07-10 17:45:32 [ℹ] using region us-west-2
2024-07-10 17:45:32 [✔] using existing VPC (vpc-84c5b3fc) and
…
2024-07-10 17:45:32 [ℹ] building cluster stack "eksctl-MilvusEKSTest-cluster"
2024-07-10 17:45:33 [ℹ] deploying stack
…
等待集群创建完成。完成后,您应该看到类似以下输出:
% EKS cluster "MilvusEKSTest" in "us-west-2" region is ready
创建集群后,您可以通过运行以下命令来查看节点:
% kubectl get nodes -A -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-172-31-22-240.us-west-2.compute.internal Ready <none> 11m v1.28.8-eks-ae9a62a 172.31.22.240 52.40.226.172 Amazon Linux 2 5.10.219-208.866.amzn2.x86_64 containerd://1.7.11
ip-172-31-31-71.us-west-2.compute.internal Ready <none> 11m v1.28.8-eks-ae9a62a 172.31.31.71 35.165.133.62 Amazon Linux 2 5.10.219-208.866.amzn2.x86_64 containerd://1.7.11
ip-172-31-33-44.us-west-2.compute.internal Ready <none> 11m v1.28.8-eks-ae9a62a 172.31.33.44 35.91.5.162 Amazon Linux 2 5.10.219-208.866.amzn2.x86_64 containerd://1.7.11
步骤3:创建一个配置为GP3存储类型的ebs-sc StorageClass,并将其设置为默认的StorageClass。
Milvus使用etcD作为元存储,需要这个StorageClass来创建和管理PVC。
运行此cat命令。
% cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
EOF
storageclass.storage.k8s.io/ebs-sc created
创建后运行patch命令使其成为默认的StorageClass。
% kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
storageclass.storage.k8s.io/gp2 patched
验证存储类是否配置正确。
% kubectl get storageclassNAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ebs-sc ebs.csi.aws.com Delete WaitForFirstConsumer false 6m39s
gp2 kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 44m
步骤4:安装AWS负载均衡器控制器
这将在后面用于Milvus服务和Attu入口。参考官方EKS负载均衡器控制器指南。
添加eks-charts存储库并更新它。
% helm repo add eks https://aws.github.io/eks-charts"eks" has been added to your repositories
% helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "eks" chart repository
...Successfully got an update from the "zilliztech" chart repository
...Successfully got an update from the "milvus" chart repository
Update Complete. ⎈Happy Helming!⎈
安装AWS负载均衡器控制器。将cluster-name替换为您的集群名称。当创建EKS集群时,已经创建了名为aws-load-balancer-controller的ServiceAccount。
% helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=MilvusEKSTest \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
NAME: aws-load-balancer-controller
LAST DEPLOYED: Wed Jul 10 19:00:34 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!
验证控制器是否成功安装。输出应该如下所示:
% kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 88s
在Amazon EKS上部署Milvus集群
Milvus支持多种部署方法,如Operator和Helm。使用Operator更简单,但Helm更直接、更灵活。因此我们使用Helm进行部署。 您可以通过values在部署Milvus时自定义配置,使用milvus_helm.yaml文件。
默认情况下,Milvus在集群内创建minio和pulsar作为对象存储和消息存储。我们将做一些配置更改,使其更适合生产环境。
步骤1:添加Milvus Helm存储库并更新它。
% helm repo add milvus https://zilliztech.github.io/milvus-helm/
helm repo update"milvus" already exists with the same configuration, skipping
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "eks" chart repository
...Successfully got an update from the "zilliztech" chart repository
...Successfully got an update from the "milvus" chart repository
Update Complete. ⎈Happy Helming!⎈
步骤2:创建一个milvus_cluster.yaml文件。
以下代码自定义了Milvus的安装,例如配置Amazon S3作为对象存储,Amazon MSK作为消息队列等。我们将在代码块之后提供详细的解释和配置指导。
###################################### Section 1# # Configure S3 as the Object Storage#####################################
# Service account# - this service account are used by External S3 access
serviceAccount:
create: false
name: milvus-s3-access-sa
# Close in-cluster minio
minio:
enabled: false
# External S3# - these configs are only used when `externalS3.enabled` is true
externalS3:
enabled: true
host: "s3.<region-code>.amazonaws.com"
port: "443"
useSSL: true
bucketName: "<bucket-name>"
rootPath: "<root-path>"
useIAM: true
cloudProvider: "aws"
iamEndpoint: ""
###################################### Section 2# # Configure MSK as the Message Storage#####################################
# Close in-cluster pulsar
pulsar:
enabled: false
# External kafka# - these configs are only used when `externalKafka.enabled` is true
externalKafka:
enabled: true
brokerList: "<broker-list>"
securityProtocol: SASL_SSL
sasl:
mechanisms: SCRAM-SHA-512
username: "<username>"
password: "<password>"
###################################### Section 3# # Expose the Milvus service to be accessed from outside the cluster (LoadBalancer service).# or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it.#####################################
service:
type: LoadBalancer
port: 19530
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: external #AWS Load Balancer Controller fulfills services that has this annotation
service.beta.kubernetes.io/aws-load-balancer-name : milvus-service #User defined name given to AWS Network Load Balancer
#service.beta.kubernetes.io/aws-load-balancer-scheme: internal # internal or internet-facing, later allowing for public access via internet
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing" #Places the load balancer on public subnets
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip #The Pod IPs should be used as the target IPs (rather than the node IPs)
###################################### Section 4# # Installing Attu the Milvus management GUI#####################################
attu:
enabled: true
name: attu
service:
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/aws-load-balancer-name : milvus-attu-service
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
labels: {}
type: LoadBalancer
port: 3000
ingress:
enabled: false
###################################### Section 5# # HA deployment of Milvus Core Components#####################################
rootCoordinator:
replicas: 2
activeStandby:
enabled: true # Enable active-standby when you set multiple replicas for root coordinator
resources:
limits:
cpu: 1
memory: 2Gi
indexCoordinator:
replicas: 2
activeStandby:
enabled: true # Enable active-standby when you set multiple replicas for index coordinator
resources:
limits:
cpu: "0.5"
memory: 0.5Gi
queryCoordinator:
replicas: 2
activeStandby:
enabled: true # Enable active-standby when you set multiple replicas for query coordinator
resources:
limits:
cpu: "0.5"
memory: 0.5Gi
dataCoordinator:
replicas: 2
activeStandby:
enabled: true # Enable active-standby when you set multiple replicas for data coordinator
resources:
limits:
cpu: "0.5"
memory: 0.5Gi
proxy:
replicas: 2
resources:
limits:
cpu: 1
memory: 4Gi
###################################### Section 6# # Milvus Resource Allocation#####################################
queryNode:
replicas: 1
resources:
limits:
cpu: 2
memory: 8Gi
dataNode:
replicas: 1
resources:
limits:
cpu: 1
memory: 4Gi
indexNode:
replicas: 1
resources:
limits:
cpu: 4
memory: 8Gi
代码分为六个部分。按照以下说明更改相应的配置。
第1部分:配置S3作为对象存储。serviceAccount授予Milvus访问S3的权限(此处为milvus-s3-access-sa,在创建EKS集群时已创建)。
- 将<region-code>替换为您创建集群的AWS区域代码。
- 将<bucket-name>替换为S3存储桶的名称,将<root-path>替换为S3存储桶的前缀(可以为空)。
第2部分:配置MSK作为消息存储。
将<broker-list>替换为MSK端点的SASL/SCRAM认证类型,
view_client_information_78697567b5.jpg
view client information.jpg
第3部分:此部分将Milvus服务端点暴露给集群外部。默认情况下,Milvus端点使用ClusterIP类型服务,只能在EKS集群内访问。如果需要,您可以将其更改为LoadBalancer类型以允许从EKS集群外部访问。LoadBalancer类型服务使用Amazon NLB作为负载均衡器。
根据安全最佳实践,默认情况下,aws-load-balancer-scheme配置为内部模式,这意味着只允许内部网络访问Milvus。如果您确实需要通过Internet访问Milvus,您需要将internal更改为internet-facing。点击这里查看NLB配置指南。
将该行更改为:
aws-load-balancer-scheme: internet-facing
# service.beta.kubernetes.io/aws-load-balancer-scheme: internal
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
第4部分:安装并配置Attu,这是一个开源的Milvus管理工具。它具有直观的GUI,允许您轻松与数据库交互。我们启用了Attu,使用AWS ALB配置入口,并将其设置为internet-facing类型,以便可以通过Internet访问Attu。
第5部分:启用Milvus核心组件的HA部署。根据架构,我们已经知道Milvus包含多个独立且解耦的组件。例如,协调器服务作为控制层,处理Root、Query、Data和Index组件的协调。访问层中的Proxy作为数据库访问端点。这些组件默认只有1个pod副本。为了提高Milvus的可用性,特别需要部署这些服务组件的多个副本。
请注意,Root、Query、Data和Index协调器组件必须以多副本部署,并启用activeStandby选项。
第6部分:根据工作负载的要求调整Milvus组件的资源分配。Milvus网站还提供了一个尺寸工具,可以根据数据量、向量维度、索引类型等生成配置建议。它还可以一键生成Helm配置文件。
以下配置是工具为100万1024维向量和HNSW索引类型给出的建议。
使用Helm在命名空间milvus中创建Milvus(可以替换为自定义名称)。
% helm install demo-milvus milvus/milvus -n milvus -f milvus_cluster.yaml
W0710 19:35:08.789610 64030 warnings.go:70] annotation "kubernetes.io/ingress.class" is deprecated, please use 'spec.ingressClassName' instead
NAME: demo-milvus
LAST DEPLOYED: Wed Jul 10 19:35:06 2024
NAMESPACE: milvus
STATUS: deployed
REVISION: 1
TEST SUITE: None
运行以下命令以检查部署状态。
% kubectl get deployment -n milvus
NAME READY UP-TO-DATE AVAILABLE AGE
demo-milvus-attu 1/1 1 1 5m27s
demo-milvus-datacoord 2/2 2 2 5m27s
demo-milvus-datanode 1/1 1 1 5m27s
demo-milvus-indexcoord 2/2 2 2 5m27s
demo-milvus-indexnode 1/1 1 1 5m27s
demo-milvus-proxy 2/2 2 2 5m27s
demo-milvus-querycoord 2/2 2 2 5m27s
demo-milvus-querynode 1/1 1 1 5m27s
demo-milvus-rootcoord 2/2 2 2 5m27s
上面的输出显示 Milvus 组件全部可用,并且协调组件启用了多个副本。
访问和管理 Milvus 端点
到目前为止,我们已经成功部署了 Milvus 数据库。现在我们可以通过端点访问 Milvus。Milvus 通过 Kubernetes 服务暴露端点。Attu 通过 Kubernetes Ingress 暴露端点。
使用 Kubernetes 服务访问 Milvus 端点
运行以下命令以获取服务端点:
% kubectl get svc -n milvus
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-etcd ClusterIP 172.20.103.138 <none> 2379/TCP,2380/TCP 62m
demo-etcd-headless ClusterIP None <none> 2379/TCP,2380/TCP 62m
demo-milvus LoadBalancer 172.20.219.33 milvus-nlb-xxxx.elb.us-west-2.amazonaws.com 19530:31201/TCP,9091:31088/TCP 62m
demo-milvus-datacoord ClusterIP 172.20.214.106 <none> 13333/TCP,9091/TCP 62m
demo-milvus-datanode ClusterIP None <none> 9091/TCP 62m
demo-milvus-indexcoord ClusterIP 172.20.106.51 <none> 31000/TCP,9091/TCP 62m
demo-milvus-indexnode ClusterIP None <none> 9091/TCP 62m
demo-milvus-querycoord ClusterIP 172.20.136.213 <none> 19531/TCP,9091/TCP 62m
demo-milvus-querynode ClusterIP None <none> 9091/TCP 62m
demo-milvus-rootcoord ClusterIP 172.20.173.98 <none> 53100/TCP,9091/TCP 62m
您可以看到几个服务。Milvus 支持两个端口,端口 19530 和端口 9091:
- 端口 19530 用于 gRPC 和 RESTful API。当您使用不同的 Milvus SDK 或 HTTP 客户端连接到 Milvus 服务器时,默认使用此端口。
- 端口 9091 是用于指标收集、pprof 分析和 Kubernetes 内的健康探针的管理端口。
其中,demo-milvus 服务提供了数据库访问端点,用于与客户端建立连接。数据库端点通过 NLB 作为服务负载均衡器进行访问。您可以从 EXTERNAL-IP 列中获取 NLB 服务端点。
请注意 NLB EXTERNAL-IP 列,在这个例子中是:
milvus-nlb-xxxx.elb.us-west-2.amazonaws.com 19530:31201/TCP,9091:31088/TCP
使用 Attu 访问 Milvus 端点
当我们安装 Milvus 时,我们还安装了 Attu,这是一个管理 Milvus 的管理工具。运行以下命令以获取端点:
% kubectl get ingress -n milvus
NAME CLASS HOSTS ADDRESS PORTS AGE
demo-milvus-attu <none> * k8s-attu-xxxx.us-west-2.elb.amazonaws.com 80 27s
您应该看到一个名为 demo-milvus-attu 的入口,其中 ADDRESS 列是外部 URL。
在浏览器中打开入口地址,您将看到以下页面。
点击 Connect 登录。
attu_interface_386e736450.jpg
attu 界面
登录后,您可以通过以下方式管理 Milvus 数据库:
manage_Milvus_using_Attu_bae81fea2e.jpg
使用 Attu 管理 Milvus
测试 Milvus 向量数据库
您可以使用 Milvus 的官方示例代码来测试 Milvus 数据库是否正常工作。
步骤 1:直接下载 hello_milvus.py 示例代码。
% wget https://raw.githubusercontent.com/milvus-io/pymilvus/master/examples/hello_milvus.py
步骤 2:将示例代码中的主机修改为之前获取的 Milvus Kubernetes 端点。
print(fmt.format("start connecting to Milvus"))
connections.connect("default",
host="milvus-nlb-xxx.elb.us-west-2.amazonaws.com",
port="19530")
步骤 3:运行代码。如果返回以下结果,则 Milvus 正常运行。
% python3 hello_milvus.py
=== start connecting to Milvus ===Does collection hello_milvus exist in Milvus: False
=== Create collection `hello_milvus` ===
=== Start inserting entities ===Number of entities in Milvus: 3000
=== Start Creating index IVF_FLAT ===
=== Start loading ===
您现在已经成功在 EKS 上设置了 Milvus!恭喜!!!
结论
本文介绍了开源向量数据库 Milvus,并解释了如何使用 Amazon EKS、S3、MSK 和 ELB 等托管服务在 AWS 上部署它,以实现更高的弹性和可靠性。
注:本文为AI翻译,查看原文
技术干货
理解视觉变换器(ViT)的初学者指南
视觉变换器(ViT)是使用变换器执行计算机视觉任务(如目标检测和图像分类)的神经网络模型。
2024-11-20技术干货
使用 Milvus Lite、Llama3 和 LlamaIndex 搭建 RAG 应用
大语言模型(LLM)已经展示出与人类交互并生成文本响应的卓越能力。这些模型可以执行各种自然语言任务,如翻译、概括、代码生成和信息检索等。
2024-11-20技术干货
使用Milvus和Llama-agents构建更强大的Agent系统
本文将探讨如何使用 llama-agents 和 Milvus 构建 Agent 系统。通过将 LLM 的强大功能与 Milvus 的向量相似性搜索能力相结合,我们可以创建智能且高效、可扩展的复杂 Agent 系统。
2024-11-19