文章目录
-
- 一、先决条件
-
- [1.1 安装AWS CLI ✅](#1.1 安装AWS CLI ✅)
- [1.2 安装 EKS 相关工具✅](#1.2 安装 EKS 相关工具✅)
- [1.3 创建 Amazon S3 存储桶✅](#1.3 创建 Amazon S3 存储桶✅)
- [1.4 创建 Amazon MSK 实例✅](#1.4 创建 Amazon MSK 实例✅)
- 二、创建EKS集群
- [三、创建 ebs-sc StorageClass](#三、创建 ebs-sc StorageClass)
- [四、安装 AWS Load Balancer Controller](#四、安装 AWS Load Balancer Controller)
- [五、部署 Milvus 数据库](#五、部署 Milvus 数据库)
-
- [5.1 添加 Milvus Helm 仓库](#5.1 添加 Milvus Helm 仓库)
- [5.2 配置 S3 作为 Object Storage](#5.2 配置 S3 作为 Object Storage)
- [5.3 配置 MSK 作为 Message Storage](#5.3 配置 MSK 作为 Message Storage)
- [六、优化 Milvus 配置](#六、优化 Milvus 配置)
-
- [6.1 配置 Milvus 服务可供 EKS 集群外访问](#6.1 配置 Milvus 服务可供 EKS 集群外访问)
- [6.2 安装可视化管理工具 Attu](#6.2 安装可视化管理工具 Attu)
- 七、清理资源
- 八、参考链接
一、先决条件
1.1 安装AWS CLI ✅
一台个人电脑或者 Amazon EC2,安装 AWS CLI,并配置相应的权限。如果您使用 Amazon Linux 2 或者 Amazon Linux 2023,AWS CLI 工具默认已经安装。
参考链接:【Amazon】安装卸载AWS CLI操作流程(Windows 、Linux系统)
1.2 安装 EKS 相关工具✅
安装 EKS 相关工具,包括 Helm,Kubectl,eksctl 等。
bash
C:\Users\xyb>helm version
version.BuildInfo{Version:"v3.16.2", GitCommit:"13654a52f7c70a143b1dd51416d633e1071faffb", GitTreeState:"clean", GoVersion:"go1.22.7"}
C:\Users\xyb>kubectl version
Client Version: v1.30.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Unable to connect to the server: dial tcp 127.0.0.1:7548: connectex: No connection could be made because the target machine actively refused it.
C:\Users\xyb>eksctl version
0.145.0
1.3 创建 Amazon S3 存储桶✅
bash
C:\Users\xyb>aws s3api create-bucket --bucket xybdiy-milvus-bucket --region us-east-1
{
"Location": "/xybdiy-milvus-bucket"
}
1.4 创建 Amazon MSK 实例✅
MSK 创建注意事项:
1)当前最新稳定版本的 Milvus(v2.2.8)依赖 Kafka 的 autoCreateTopics 特性,因此在创建 MSK 时需要使用自定义配置,并将属性 auto.create.topics.enable 由默认的 false 改为 true。另外,为了提高 MSK 的消息吞吐量,建议调大 message.max.bytes 和 replica.fetch.max.bytes 的值。
javascript
auto.create.topics.enable=true
message.max.bytes=10485880
replica.fetch.max.bytes=20971760
2)Milvus 不支持 MSK 的 IAM role-based 认证,因此 MSK 创建时需要在安全配置里打开 SASL/SCRAM authentication 选项,并在 Secret Manager 里配置 username 和 password。s
3)MSK 的安全组要允许 EKS 集群安全组或者 IP 地址段进行访问。
二、创建EKS集群
- 创建eks_cluster.yaml配置文件
yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: xyb-milvus-cluster
region: us-east-1
version: "1.26"
iam:
withOIDC: true
serviceAccounts:
- metadata:
name: aws-load-balancer-controller
namespace: kube-system
wellKnownPolicies:
awsLoadBalancerController: true
- metadata:
name: milvus-s3-access-sa
# if no namespace is set, "default" will be used;
# the namespace will be created if it doesn't exist already
namespace: milvus
labels: {aws-usage: "milvus"}
attachPolicyARNs:
- "arn:aws:iam::aws:policy/AmazonS3FullAccess"
managedNodeGroups:
- name: ng-1-milvus
labels: { role: milvus }
instanceType: m6i.2xlarge
desiredCapacity: 3
privateNetworking: true
iam:
withAddonPolicies:
autoScaler: true
availabilityZones: ["us-east-1a", "us-east-1b", "us-east-1c"]
availabilityZones: ["us-east-1a", "us-east-1b", "us-east-1c"]
addons:
- name: vpc-cni # no version is specified so it deploys the default version
attachPolicyARNs:
- arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy
- name: coredns
version: latest # auto discovers the latest available
- name: kube-proxy
version: latest
- name: aws-ebs-csi-driver
wellKnownPolicies: # add IAM and service account
ebsCSIController: true
- 运行 eksctl 命令创建 EKS 集群。
bash
eksctl create cluster -f eks_cluster.yaml
创建完成。
该过程将创建如下资源:
- 创建一个指定版本的 EKS 集群。
- 创建一个拥有 3 个 m6i.2xlarge EC2 实例的托管节点组。
- 创建 **IAM OIDC 身份提供商**和名为 aws-load-balancer-controller 的 ServiceAccount,后文安装 AWS Load Balancer Controller 时使用。
- 创建一个命名空间 milvus,并在此命名空间里创建名 milvus-s3-access-sa 的 ServiceAccount。后文为 Milvus 配置 S3 做 Object Storage 时使用。
注意,此处为了方便授予了 milvus-s3-access-sa 所有 S3 访问权限,在生产环境部署时建议遵循最小化授权原则,只授予指定用于 Milvus 的 S3 存储桶的访问权限。- 安装多个插件,其中 vpc-cni,coredns,kube-proxy 为 EKS 必备核心插件。aws-ebs-csi-driver 是 AWS EBS CSI 驱动程序,允许 EKS 集群管理 Amazon EBS 持久卷的生命周期。
等待集群创建完成。集群创建过程中会自动创建或者更新 kubeconfig 文件。您也可以运行如下命令手动更新,注意将 region-code 替换为创建集群的 AWS 区域,将 cluster-name 替换为您的集群名称。
bashaws eks update-kubeconfig --region <region-code> --name <cluster-name>
;bashaws eks update-kubeconfig --region us-east-1 --name xyb-milvus-cluster
输出内容:
bashAdded new context arn:aws:eks:us-east-1:580001333004:cluster/xyb-milvus-cluster to C:\Users\xyb\.kube\config
- 集群创建完毕之后,运行如下命令就可以查看您的集群节点。
bash
kubectl get nodes -A -o wide
输出内容:
bash
C:\Users\xyb>kubectl get nodes -A -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-192-168-123-251.ec2.internal Ready <none> 3d21h v1.26.15-eks-f479e3c 192.168.123.251 <none> Amazon Linux 2 5.10.226-214.879.amzn2.x86_64 containerd://1.7.22
ip-192-168-142-202.ec2.internal Ready <none> 3d21h v1.26.15-eks-f479e3c 192.168.142.202 <none> Amazon Linux 2 5.10.226-214.879.amzn2.x86_64 containerd://1.7.22
ip-192-168-160-82.ec2.internal Ready <none> 3d21h v1.26.15-eks-f479e3c 192.168.160.82 <none> Amazon Linux 2 5.10.226-214.879.amzn2.x86_64 containerd://1.7.22
三、创建 ebs-sc StorageClass
创建 ebs-sc-StorageClass,配置 GP3 作为存储类型,并设置为 default StorageClass。Milvus 使用 etcd 作为 Meta Storage,需要依赖该 StorageClass 创建和管理 PVC。
yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
bash
kubectl apply -f ebs-sc-StorageClass.yaml
并将原来的 gp2 StorageClass 设置为非默认:
bash
$ kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
storageclass.storage.k8s.io/gp2 patched
bash
C:\Users\xyb>kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ebs-sc (default) ebs.csi.aws.com Delete WaitForFirstConsumer false 3d21h
gp2 kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 3d22h
四、安装 AWS Load Balancer Controller
安装 AWS Load Balancer Controller,后文中 Milvus Service 和 Attu Ingress 需要用到该 Controller,我们在此提前进行安装。
- 安装helm
bash
$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 11521 100 11521 0 0 64727 0 --:--:-- --:--:-- --:--:-- 65090
$ chmod 700 get_helm.sh
$ ./get_helm.sh
[WARNING] Could not find git. It is required for plugin installation.
Downloading https://get.helm.sh/helm-v3.12.3-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
[ec2-user@ip-172-31-35-151 ~]$ helm version
version.BuildInfo{Version:"v3.12.3", GitCommit:"3a31588ad33fe3b89af5a2a54ee1d25bfe6eaa5e", GitTreeState:"clean", GoVersion:"go1.20.7"}
- 添加 eks-charts 仓库并更新。
bash
helm repo add eks https://aws.github.io/eks-charts
helm repo update
bash
C:\Users\xyb>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 "crane" chart repository
...Successfully got an update from the "prometheus-community" chart repository
...Successfully got an update from the "grafana" chart repository
Update Complete. ⎈Happy Helming!⎈
安装 AWS Load Balancer Controller。请将 cluster-name 替换为您的集群名称。此处名为 aws-load-balancer-controller 的 ServiceAccount 已经在创建 EKS 集群时创建。
bash
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=xyb-milvus-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
js
C:\Users\xyb>helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=xyb-milvus-cluster --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
NAME: aws-load-balancer-controller
LAST DEPLOYED: Fri Oct 18 19:20:36 2024
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
AWS Load Balancer controller installed!
检查 Controller 是否安装成功。
bash
kubectl get deployment -n kube-system aws-load-balancer-controller
输出示例如下。
bash
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 3d21h
五、部署 Milvus 数据库
Milvus 支持 Operator 和 Helm 等多种部署方式,相比较而言,通过 Operator 进行部署和管理要更为简单,但 Helm 方式要更加直接和灵活,因此本文采用 Helm 的部署方式。 在使用 Helm 部署 Milvus 时,可以通过配置文件 values.yaml 进行自定义配置,点击 values.yaml 可以查看所有配置选项。 Milvus 默认创建 in-cluster 的 minio 和 pulsar 分别作为 Object Storage 和 Message Storage。为了更适合在生产环境使用,我们通过配置文件使用 S3 和 MSK 作为替代。
5.1 添加 Milvus Helm 仓库
首先,添加 Milvus Helm 仓库并更新。
bash
helm repo add milvus https://milvus-io.github.io/milvus-helm/
helm repo update
helm repo list
bash
$ helm repo add milvus https://milvus-io.github.io/milvus-helm/
"milvus" 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 "crane" chart repository
...Successfully got an update from the "milvus" chart repository
...Successfully got an update from the "eks" chart repository
...Successfully got an update from the "prometheus-community" chart repository
...Successfully got an update from the "grafana" chart repository
Update Complete. ⎈Happy Helming!⎈
$ helm repo list
NAME URL
prometheus-community https://prometheus-community.github.io/helm-charts
grafana https://grafana.github.io/helm-charts
crane https://gocrane.github.io/helm-charts
eks https://aws.github.io/eks-charts
milvus https://milvus-io.github.io/milvus-helm/
5.2 配置 S3 作为 Object Storage
配置 S3 作为 Object Storage。配置 serviceAccount 是为了授予 Milvus 访问 S3 的权限(此处为 milvus-s3-access-sa
,在创建 EKS 集群时已经创建)。注意将替换为创建集群的 AWS 区域。将替换为 S3 存储桶的名字,替换为 S3 存储桶的前缀(可以为空)。
- milvus_cluster.yaml
bash
###################################
# 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.us-east-1.amazonaws.com"
port: "443"
useSSL: true
bucketName: "xybdiy-milvus-bucket"
rootPath: ""
useIAM: true
cloudProvider: "aws"
iamEndpoint: ""
###################################
# Close in-cluster pulsar
###################################
pulsar:
enabled: false
###################################
# External kafka
# - these configs are only used when `externalKafka.enabled` is true
###################################
externalKafka:
enabled: true
brokerList: "b-3.xybmskcluster.loo6pa.c5.kafka.us-east-1.amazonaws.com:9096,b-2.xybmskcluster.loo6pa.c5.kafka.us-east-1.amazonaws.com:9096,b-1.xybmskcluster.loo6pa.c5.kafka.us-east-1.amazonaws.com:9096"
securityProtocol: SASL_SSL
sasl:
mechanisms: SCRAM-SHA-512
username: "xyb"
password: "xyb-secret"
5.3 配置 MSK 作为 Message Storage
注意将替换为 MSK 的 SASL/SCRAM 认证类型对应的 endpoint 地址,和替换为 MSK 的账号和密码。注意
:MSK 的安全组要配置允许 EKS 集群安全组或者 IP 地址段进行访问。
将 2-3 步的配置合并并保存为 milvus_cluster.yaml 文件,并使用 Helm 命令创建 Milvus(部署在 milvus 命名空间)。注意,您可以将 demo 替换为自定义名称。
bash
helm install xyb milvus/milvus -n milvus -f milvus_cluster.yaml
运行如下命令检查 pods 的状态。
bash
kubectl get pods -n milvus
bash
$ helm install xyb milvus/milvus -n milvus -f milvus_cluster.yaml
NAME: xyb
LAST DEPLOYED: Sat Aug 26 02:38:51 2023
NAMESPACE: milvus
STATUS: deployed
REVISION: 1
TEST SUITE: None
running 状态表明创建成功。
bash
C:\Users\xyb>kubectl get pods -n milvus
NAME READY STATUS RESTARTS AGE
xybdiy-etcd-0 1/1 Running 0 2d2h
xybdiy-etcd-1 1/1 Running 0 2d2h
xybdiy-etcd-2 1/1 Running 0 2d2h
xybdiy-milvus-attu-6f9b87d587-rsswc 1/1 Running 0 2d2h
xybdiy-milvus-datacoord-5fb796c6b9-557qk 1/1 Running 0 2d2h
xybdiy-milvus-datanode-7c5cd77cd7-jp2bb 1/1 Running 0 2d2h
xybdiy-milvus-indexcoord-55bc557c95-kwbkz 1/1 Running 0 2d2h
xybdiy-milvus-indexnode-6cd5d59666-5bphz 1/1 Running 0 2d2h
xybdiy-milvus-proxy-6745bb9c4f-jq584 1/1 Running 0 2d2h
xybdiy-milvus-querycoord-68b6bf796d-fsw5j 1/1 Running 0 2d2h
xybdiy-milvus-querynode-df7c4cd8-5h46h 1/1 Running 0 2d2h
xybdiy-milvus-rootcoord-69fd744f4c-6vkn2 1/1 Running 0 2d2h
获取 Milvus 访问终端节点。
bash
kubectl get svc -n milvus
bash
C:\Users\xyb>kubectl get svc -n milvus
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
xybdiy-etcd ClusterIP 10.100.184.133 <none> 2379/TCP,2380/TCP 2d3h
xybdiy-etcd-headless ClusterIP None <none> 2379/TCP,2380/TCP 2d3h
xybdiy-milvus LoadBalancer 10.100.95.102 milvus-service-b239e43411544264.elb.us-east-1.amazonaws.com 19530:31778/TCP,9091:30223/TCP 2d3h
xybdiy-milvus-attu ClusterIP 10.100.224.189 <none> 3000/TCP 2d2h
xybdiy-milvus-datacoord ClusterIP 10.100.203.27 <none> 13333/TCP,9091/TCP 2d3h
xybdiy-milvus-datanode ClusterIP None <none> 9091/TCP 2d3h
xybdiy-milvus-indexcoord ClusterIP 10.100.49.235 <none> 31000/TCP,9091/TCP 2d3h
xybdiy-milvus-indexnode ClusterIP None <none> 9091/TCP 2d3h
xybdiy-milvus-querycoord ClusterIP 10.100.34.57 <none> 19531/TCP,9091/TCP 2d3h
xybdiy-milvus-querynode ClusterIP None <none> 9091/TCP 2d3h
xybdiy-milvus-rootcoord ClusterIP 10.100.33.171 <none> 53100/TCP,9091/TCP 2d3h
六、优化 Milvus 配置
至此,我们已经成功地部署了 Milvus 集群,但很多 Milvus 的默认配置无发满足生产环境自定义需求,本部分主要围绕如下三个方面进行配置优化。
Milvus 默认部署 ClusterIP 类型的 service,这种 service 只能在 EKS 内部访问,将 Milvus service 更改为 Loadbalancer 类型,使集群外也可以进行访问。
安装 Attu,通过可视化界面管理 Milvus 数据库。
优化各个组件的配置,使其满足于您的负载情况。
前两项配置需要用到 AWS Load Balancer Controller,请确认在第三章中完成安装。
6.1 配置 Milvus 服务可供 EKS 集群外访问
Helm 支持在创建之后使用 helm upgrade 命令进行配置更新,我们采用这种方式对 Milvus 进行配置。 使用如下代码创建 milvus_service.yaml 配置文件,该配置文件指定使用 Load Balancer Controller 创建 LoadBalancer 类型的 service,以方便在集群外进行访问。LoadBalancer 类型的 Service 使用 Amazon NLB 作为负载均衡器。根据安全最佳实践,此处 aws-load-balancer-scheme 默认配置为 internal 模式,即只允许内网访问 Milvus。如果您确实需要通过 Internet 访问 Milvus,需要将 internal 更改为 internet-facing。点击**查看** NLB 配置说明。
bash
## 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: internet-facing # internal or internet-facing, later allowing for public access via internet
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)
然后使用 Helm 更新配置文件。
bash
helm upgrade xyb milvus/milvus -n milvus --reuse-values -f milvus_service.yaml
运行如下命令:
bash
kubectl get svc -n milvus
可以看到 xybdiy-milvus 服务已经更改为 LoadBalancer 类型,底层使用 NLB 作为服务均衡器,其中 EXTERNAL-IP 一栏即为集群外访问地址。
bash
C:\Users\xyb>kubectl get svc -n milvus
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
xybdiy-etcd ClusterIP 10.100.184.133 <none> 2379/TCP,2380/TCP 2d3h
xybdiy-etcd-headless ClusterIP None <none> 2379/TCP,2380/TCP 2d3h
xybdiy-milvus LoadBalancer 10.100.95.102 milvus-service-b239e43411544264.elb.us-east-1.amazonaws.com 19530:31778/TCP,9091:30223/TCP 2d3h
xybdiy-milvus-attu ClusterIP 10.100.224.189 <none> 3000/TCP 2d2h
xybdiy-milvus-datacoord ClusterIP 10.100.203.27 <none> 13333/TCP,9091/TCP 2d3h
xybdiy-milvus-datanode ClusterIP None <none> 9091/TCP 2d3h
xybdiy-milvus-indexcoord ClusterIP 10.100.49.235 <none> 31000/TCP,9091/TCP 2d3h
xybdiy-milvus-indexnode ClusterIP None <none> 9091/TCP 2d3h
xybdiy-milvus-querycoord ClusterIP 10.100.34.57 <none> 19531/TCP,9091/TCP 2d3h
xybdiy-milvus-querynode ClusterIP None <none> 9091/TCP 2d3h
xybdiy-milvus-rootcoord ClusterIP 10.100.33.171 <none> 53100/TCP,9091/TCP 2d3h
6.2 安装可视化管理工具 Attu
Attu 是 Milvus 的高效开源管理工具。它具有直观的图形用户界面(GUI),使您可以轻松地与数据库进行交互。 只需点击几下,您就可以可视化集群状态、管理元数据、执行数据查询等等。
本部分我们使用 Helm 安装并配置 Attu。
首先,使用如下代码创建 milvus_attu.yaml 配置文件。在配置文件里开启 Attu 选项,配置使用 AWS ALB 作为 Ingress,并设置为 internet-facing 类型可通过 Internet 亦可访问 Attu。点击**查看** ALB 配置说明。
yaml
attu:
enabled: true
name: attu
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: alb # Annotation: set ALB ingress type
alb.ingress.kubernetes.io/scheme: internet-facing #Places the load balancer on public subnets
alb.ingress.kubernetes.io/target-type: ip #The Pod IPs should be used as the target IPs (rather than the node IPs)
alb.ingress.kubernetes.io/group.name: attu # Groups multiple Ingress resources
hosts:
-
然后使用 Helm 更新配置文件。
bash
helm upgrade xyb milvus/milvus -n milvus --reuse-values -f milvus_attu.yaml
再次运行如下命令:
bash
kubectl get ingress -n milvus
可以看到名为 xyb-milvus-attu 的 Ingress,其中 ADDRESS 一栏即为访问地址。
bash
C:\Users\xyb>kubectl get ingress -n milvus
NAME CLASS HOSTS ADDRESS PORTS AGE
xybdiy-milvus-attu <none> * k8s-attu-f6a1785390-1056545378.us-east-1.elb.amazonaws.com 80 2d2h
七、清理资源
bash
C:\Users\xyb>helm uninstall xybdiy -n milvus
release "xybdiy" uninstalled
bash
C:\Users\xyb>eksctl delete cluster --name xyb-milvus-cluster --region us-east-1
2
八、参考链接
【1】 https://zilliz.com/what-is-milvus
【2】在 EKS 上部署 Milvus 集群 | Milvus 文档
【3】https://aws.amazon.com/cn/blogs/china/build-open-source-vector-database-milvus-based-on-amazon-eks/