微信扫码
添加专属顾问
我要投稿
Milvus Operator,一键部署的智能运维革命。 核心内容: 1. Kubernetes Operator的设计理念及工作原理 2. Milvus Operator如何简化集群部署和管理 3. Operator相对于YAML和Helm的优势分析
周一早会,老板发话:"小M,客户那边要上线一个向量搜索服务,你把Milvus集群部署一下,今天下班前搞定啊!对了,要高可用,要能扩展,要监控齐全...(省略八百字需求)"
你强颜欢笑地点头,心里却在盘算:手动配置一大堆yaml文件,改一个配置要改好几个地方,还得担心改错了整个集群就挂。想扩展节点?那得手动调度资源、配均衡,搞不好还会数据丢失。更别提监控告警了,光是配置Prometheus和Grafana就够喝一壶的。
但在Kubernetes的世界里,这活儿的环,闭了,但没完全闭。
与其像原始人一样手动搭建每一块积木,不如用现代工具一键生成高楼大厦。今天我们就来聊聊Milvus Operator这个"懒人神器",如何让你的集群部署从"处处是坑"变成"一键搞定",让老板的变态需求变成你的得心应手。
毕竟老运维都知道,针对脱发,一次Milvus Operator部署,顶十瓶米诺地尔。
Kubernetes Operator是一个用于管理和自动化Kubernetes应用程序的框架。它的设计初衷是为了简化Kubernetes应用程序的部署、管理和升级过程。
Operator 会定义一种“自定义资源”(Custom Resource Definition,简称 CRD)。你可以把它理解为一个新的“配置文件类型”,专门用来描述你的应用程序。
比如,你有一个数据库应用,Operator 可以定义一个叫 Database 的 CRD,你只需要在这个文件里写清楚你想要什么样的数据库(比如多大、什么版本等)。
Operator 的核心是一个“控制器”。这个控制器会一直盯着你定义的 CRD,看看你有没有创建新的资源,或者有没有修改现有的资源。
比如,你创建了一个 Database 资源,控制器会看到这个资源,然后开始按照你写的配置去部署数据库。
自动化操作:
控制器会根据 CRD 里的配置,自动执行一系列操作。比如,创建 Pod、配置网络、设置存储等等。
如果出了问题,控制器还会尝试自动修复。比如,如果数据库崩溃了,控制器会自动重启它。
Operator 还会持续监控应用程序的状态,确保它一直按照你期望的方式运行。
如果发现状态不符合预期,Operator 会自动进行调整,直到一切恢复正常。
(3)为什么要选用Operator管理Milvus而不是Helm或YAML?
Milvus作为一个分布式向量数据库,其运维管理可以通过YAML、Helm或Operator三种方式实现。相比前两者,Operator在自动化程度、状态管理和运维效率上具有显著优势。
YAML和Helm这类传统方式需要运维人员手动处理大量日常任务。比如集群扩容时,需要手动修改配置、检查资源状态、调整负载均衡。版本升级更是个精细活,要确保服务不中断,还得准备回滚方案。
Operator则把这些繁琐的任务都自动化了。它能自动检测负载情况进行扩缩容,执行滚动升级时自动处理服务切换,甚至在发现异常时自动进行故障转移。这就像从手动挡换成了自动挡,让运维工作轻松很多。
YAML只能描述期望状态,但不知道实际运行状态。Helm虽然能管理配置版本,但也不了解应用健康状况。要靠运维人员去监控、判断、处理问题。
Operator则像个尽职的管家,时刻关注着集群的每个组件。哪个节点负载高了、哪个服务响应慢了,它都能立即发现并采取措施。这种主动式的状态管理大大提高了集群的可靠性。
用YAML维护大规模集群时,配置文件会越来越多,改一处可能要动好几个地方。Helm虽然通过模板简化了一些工作,但复杂场景下仍需要大量人工操作。
Operator把Milvus运维的最佳实践都编码到了控制器中,新手也能轻松管理好集群。它提供了一致的操作接口,无论集群规模多大,维护成本都不会显著增加。
选择Operator管理Milvus,就是选择了更智能、更可靠的运维方式。它不仅降低了运维团队的工作负担,还通过自动化和智能化手段保障了集群的稳定运行。在云原生时代,这样的运维效率提升是很有价值的。
架构图清晰展示了Milvus Operator在Kubernetes集群中的部署结构。左侧蓝色区域展示了Operator的核心组件,包括Controller和Milvus-CRD。右侧绿色区域展示了Milvus集群的各个组件,如Proxy、Coord和Node等。中间通过'创建/管理'的箭头说明了Operator如何控制Milvus集群。底部橙色区域显示了依赖服务etcd和MinIO/S3/MQ。整体架构通过不同的颜色区块和箭头,直观地展示了组件间的交互关系和数据流向。
实战环境涉及软件版本信息
操作系统:openEuler 22.03 LTS SP3 x86_64
Kubernetes:v1.28.8
Milvus: v.2.5.4
确认 k8s 集群存在存储类(StorageClass),本试验环境存在两个存储类:
默认的使用本地盘的存储类local
使用 NFS 的存储类nfs-sc
,生产环境不建议使用 NFS
kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGElocal (default) openebs.io/local Delete WaitForFirstConsumer false 284dnfs-sc k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 230d
参阅 Milvus 官网安装文档,我们可以看到安装 Milvus Operator
有以下两种方式:
With Helm
With kubectl
本文使用简单、方便的 Kubectl 安装 Operator。
下载 Operator 部署资源清单
wget https://raw.githubusercontent.com/zilliztech/milvus-operator/main/deploy/manifests/deployment.yaml
替换镜像地址(可选)
当访问 DockerHub 受限,或是想使用自己镜像仓库时,执行以下命令替换镜像。
说明:本文中的镜像仓库地址为测试,请替换真实可用的仓库地址。
sed -i 's#milvusdb/milvus-operator:v1.2.1#registry.milvus-mirror.cn/&#g' deployment.yaml
运行以下命令,安装 Milvus Operator。
kubectl apply -f deployment.yaml
安装过程结束后,您将看到类似以下内容的输出。
namespace/milvus-operator createdserviceaccount/milvus-operator createdcustomresourcedefinition.apiextensions.k8s.io/milvusclusters.milvus.io createdcustomresourcedefinition.apiextensions.k8s.io/milvuses.milvus.io createdcustomresourcedefinition.apiextensions.k8s.io/milvusupgrades.milvus.io createdclusterrole.rbac.authorization.k8s.io/milvus-operator-manager-role createdclusterrolebinding.rbac.authorization.k8s.io/milvus-operator-manager-rolebinding createdrole.rbac.authorization.k8s.io/milvus-operator-leader-election-role createdrolebinding.rbac.authorization.k8s.io/milvus-operator-leader-election-rolebinding createdservice/milvus-operator-metrics-service createdservice/milvus-operator-webhook-service createddeployment.apps/milvus-operator created
运行以下命令,检查 Milvus Operator deployment 和 pod 资源是否创建成功
kubectl get deployment,pod -n milvus-operator
NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/milvus-operator 1/1 1 1 10mNAME READY STATUS RESTARTS AGEpod/milvus-operator-54d4fb854b-7hprh 1/1 Running 0 97s
一旦 Milvus Operator pod 正确运行,您就可以按如下方式部署 Milvus 集群。
下载 Milvus 集群部署资源清单。
wget https://raw.githubusercontent.com/zilliztech/milvus-operator/main/config/samples/milvus_cluster_default.yaml
默认文件内容如下:
This is a sample to deploy a milvus cluster in milvus-operator's default configurations.apiVersion: milvus.io/v1beta1kind: Milvusmetadata: name: my-release labels: app: milvusspec: mode: cluster dependencies: {} components: {} config: {}
本文考虑以下几个常用场景,修改配置文件,实现自定义需求:
自定义集群名字: milvus-release-v25
自定义镜像(使用其它在线镜像或是本地离线镜像): registry.milvus-mirror.cn/milvusdb/milvus:v2.5.4
自定义存储类的名字: 当 k8s 集群有多个存储时,可以需要指定持久化存储组件比如 Minio、etcd等,使用的存储类名称,本文使用 nfs-sc 作为示例
自定义 resource: 修改 Milvus 相关服务使用的 CPU 和内存上限,默认没有上限,设置 resource 上限,避免资源使用率激增导致 k8s 节点宕机
自动删除所有相关资源: 默认的配置删除 Milvus 集群时,不会删除已经创建的相关资源
参数配置参考链接:
Milvus Custom Resource Definition
https://github.com/zilliztech/milvus-operator/blob/main/docs/CRD/milvus.md
Pulsar Values::https://artifacthub.io/packages/helm/apache/pulsar/3.3.0?modal=values
修改后的内容如下:
apiVersion: milvus.io/v1beta1kind: Milvusmetadata: name: milvus-release-v25 labels: app: milvusspec: mode: cluster config: {} components: image: registry.milvus-mirror.cn/milvusdb/milvus:v2.5.4 resources: limits: cpu: 2 memory: 8Gi dependencies: etcd: inCluster: deletionPolicy: Delete pvcDeletion: true values: global: imageRegistry: registry.milvus-mirror.cn storageClass: nfs-sc storage: inCluster: deletionPolicy: Delete pvcDeletion: true values: resources: limits: cpu: 2 memory: 8Gi image: repository: registry.milvus-mirror.cn/milvusdb/minio tag: RELEASE.2023-03-20T20-16-18Z persistence: storageClass: nfs-sc accessMode: ReadWriteOnce size: 10Gi pulsar: inCluster: chartVersion: pulsar-v3 deletionPolicy: Delete pvcDeletion: true values: existingStorageClassName: nfs-sc pulsar_metadata: image: repository: registry.milvus-mirror.cn/apachepulsar/pulsar tag: 3.0.7 zookeeper: replicaCount: 3 volumes: data: size: 5Gi storageClassName: nfs-sc bookkeeper: volumes: journal: size: 5Gi storageClassName: nfs-sc ledgers: size: 5Gi storageClassName: nfs-sc images: zookeeper: repository: registry.milvus-mirror.cn/apachepulsar/pulsar tag: 3.0.7 proxy: repository: registry.milvus-mirror.cn/apachepulsar/pulsar tag: 3.0.7 broker: repository: registry.milvus-mirror.cn/apachepulsar/pulsar tag: 3.0.7 bookie: repository: registry.milvus-mirror.cn/apachepulsar/pulsar tag: 3.0.7 autorecovery: repository: registry.milvus-mirror.cn/apachepulsar/pulsar tag: 3.0.7
运行以下命令,部署 Milvus 集群。
kubectl apply -f milvus_cluster_default.yaml
Milvus Operator 首先会创建 Milvus 依赖的中间件,例如 Etcd、Zookeeper、Pulsar 和 MinIO,然后创建 Milvus 组件,例如代理、协调器和节点。
kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGEmilvus-release-v25-milvus-datanode 1/1 1 1 52mmilvus-release-v25-milvus-indexnode 1/1 1 1 52mmilvus-release-v25-milvus-mixcoord 1/1 1 1 52mmilvus-release-v25-milvus-proxy 1/1 1 1 52mmilvus-release-v25-milvus-querynode-0 1/1 1 1 52mmilvus-release-v25-milvus-querynode-1 0/0 0 0 52mmilvus-release-v25-milvus-standalone 0/0 0 0 52m
特别说明:
查看结果中发现Milvus Operator 会创建一个副本数为 0 的 standalone
和querynode-1
。
为什么会出现这2个副本数为0的服务呢?带着疑问向Milvus Operator仓库 提交了一个 Issue
官方的回复如下:
答复的结果大概意思是:
a、它像预期的那样工作。我们保留了独立部署,以便在不停止服务的情况下从集群扩展到独立部署。
b、对于querynode-1和querynode-0,它们在滚动升级时很有用。最终,正如您在本期中所粘贴的那样,两者中只有一个会运行。
一旦您的 Milvus 集群准备就绪,Milvus 集群中所有 pod 的状态应类似于以下内容。
kubectl get pods
NAME READY STATUS RESTARTS AGEmilvus-release-v25-etcd-0 1/1 Running 0 7m15smilvus-release-v25-etcd-1 1/1 Running 0 7m15smilvus-release-v25-etcd-2 1/1 Running 0 7m15smilvus-release-v25-milvus-datanode-65bff7b4d9-9h2xv 1/1 Running 0 4m35smilvus-release-v25-milvus-indexnode-5b5cbb4cdc-cxvwj 1/1 Running 0 4m35smilvus-release-v25-milvus-mixcoord-64488898b5-r76rw 1/1 Running 0 4m35smilvus-release-v25-milvus-proxy-5c7fbcb69-cqmq4 1/1 Running 0 4m35smilvus-release-v25-milvus-querynode-0-bc6f57d64-k2wnt 1/1 Running 0 4m35smilvus-release-v25-minio-0 1/1 Running 0 7m14smilvus-release-v25-minio-1 1/1 Running 0 7m14smilvus-release-v25-minio-2 1/1 Running 0 7m14smilvus-release-v25-minio-3 1/1 Running 0 7m14smilvus-release-v25-pulsar-bookie-0 1/1 Running 0 7m12smilvus-release-v25-pulsar-bookie-1 1/1 Running 0 7m12smilvus-release-v25-pulsar-bookie-2 1/1 Running 0 7m12smilvus-release-v25-pulsar-bookie-init-5zf2z 0/1 Completed 0 7m12smilvus-release-v25-pulsar-broker-0 1/1 Running 0 7m12smilvus-release-v25-pulsar-broker-1 1/1 Running 0 7m12smilvus-release-v25-pulsar-proxy-0 1/1 Running 0 7m12smilvus-release-v25-pulsar-proxy-1 1/1 Running 0 7m12smilvus-release-v25-pulsar-pulsar-init-twznd 0/1 Completed 0 7m12smilvus-release-v25-pulsar-recovery-0 1/1 Running 1 (6m25s ago) 7m12smilvus-release-v25-pulsar-zookeeper-0 1/1 Running 0 7m12smilvus-release-v25-pulsar-zookeeper-1 1/1 Running 0 7m12smilvus-release-v25-pulsar-zookeeper-2 1/1 Running 0 7m12s
验证是否使用了自定义的 storageClass: nfs-sc
及自定义容量大小是否正确。
kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEdata-milvus-release-v25-etcd-0 Bound pvc-3273f9ec-819f-4e84-bdbe-3cd9df697a5f 10Gi RWO nfs-sc 36mdata-milvus-release-v25-etcd-1 Bound pvc-01743e13-a989-4aea-8fd0-632ea8b13f98 10Gi RWO nfs-sc 36mdata-milvus-release-v25-etcd-2 Bound pvc-594f1a63-efba-4993-89e6-3ee5e333073d 10Gi RWO nfs-sc 36mexport-milvus-release-v25-minio-0 Bound pvc-477d4e3b-69d7-4bbe-80f7-b747dc4c79f7 10Gi RWO nfs-sc 36mexport-milvus-release-v25-minio-1 Bound pvc-b12e46fa-8d29-48fb-9ac1-98f80d67b543 10Gi RWO nfs-sc 36mexport-milvus-release-v25-minio-2 Bound pvc-2e67893e-9611-43dd-9550-b3a7705699ae 10Gi RWO nfs-sc 36mexport-milvus-release-v25-minio-3 Bound pvc-572c4565-bc38-4215-a13c-061d9199fdea 10Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-bookie-journal-milvus-release-v25-pulsar-bookie-0 Bound pvc-183eff99-7a87-406d-9f17-b0fb30c7c0b3 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-bookie-journal-milvus-release-v25-pulsar-bookie-1 Bound pvc-ebe32304-7d92-44d1-b6fb-4cbaf3207d25 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-bookie-journal-milvus-release-v25-pulsar-bookie-2 Bound pvc-2ead9186-3d44-4faa-9ae7-784be7ecf6d2 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-bookie-ledgers-milvus-release-v25-pulsar-bookie-0 Bound pvc-ff1b632d-0a66-4c13-a3bb-2550f9307614 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-bookie-ledgers-milvus-release-v25-pulsar-bookie-1 Bound pvc-57159e85-bb48-48a9-9706-7a95af8da157 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-bookie-ledgers-milvus-release-v25-pulsar-bookie-2 Bound pvc-eb235f29-afbd-4a40-9a7d-0340a9686053 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-zookeeper-data-milvus-release-v25-pulsar-zookeeper-0 Bound pvc-40e02974-3b7d-4f42-bfa7-3252b7615a36 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-zookeeper-data-milvus-release-v25-pulsar-zookeeper-1 Bound pvc-75904229-3bbf-458e-b0e3-3982e430621b 5Gi RWO nfs-sc 36mmilvus-release-v25-pulsar-zookeeper-data-milvus-release-v25-pulsar-zookeeper-2 Bound pvc-2e068b79-75ac-4aa9-9e90-423ff399bad0 5Gi RWO nfs-sc 36m
以 mixcoord 组件为例,验证资源限制resources.limits
配置是否正确。
kubectl get deployment milvus-release-v25-milvus-mixcoord -o jsonpath='{.spec.template.spec.containers[*].resources.limits}' | jq{ "cpu": "2", "memory": "8Gi"}
kubectl get deployment milvus-release-v25-milvus-mixcoord -o jsonpath='{.spec.template.spec.containers[0].image}'registry.milvus-mirror.cn/milvusdb/milvus:v2.5.4
经常有人问我,如何在 k8s 集群外部访问Milvus 服务?
我们使用 Operator 部署的 Milvus 服务默认使用了 ClusterIP 类型。因此,Milvus 只能被 k8s 集群内部应用访问,如果开放给集群外部,需要定义外部访问方式,本文选择最简单的 NodePort 对外发布 Milvus 服务。
创建并编辑外部访问 Milvus 服务的 svc 资源清单
vi milvus-external-svc.yaml
kind: ServiceapiVersion: v1metadata: name: milvus-release-v25-external-svc namespace: default labels: app: dmilvus-release-v25-external-svcspec: ports: - name: milvus protocol: TCP port: 19530 targetPort: 19530 nodePort: 31530 - name: milvus-web protocol: TCP port: 9091 targetPort: 9091 nodePort: 31531 selector: app.kubernetes.io/component: proxy app.kubernetes.io/instance: milvus-release-v25 app.kubernetes.io/name: milvus clusterIP: type: NodePort
kubectl apply -f milvus-external-svc.yaml
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEmilvus-release-v25-external-svc NodePort 10.233.8.166 <none> 19530:31530/TCP,9091:31531/TCP 43smilvus-release-v25-etcd ClusterIP 10.233.27.134 <none> 2379/TCP,2380/TCP 16mmilvus-release-v25-etcd-headless ClusterIP None <none> 2379/TCP,2380/TCP 16mmilvus-release-v25-milvus ClusterIP 10.233.55.194 <none> 19530/TCP,9091/TCP 13mmilvus-release-v25-minio ClusterIP 10.233.1.56 <none> 9000/TCP 16mmilvus-release-v25-minio-svc ClusterIP None <none> 9000/TCP 16mmilvus-release-v25-pulsar-bookie ClusterIP None <none> 3181/TCP,8000/TCP 16mmilvus-release-v25-pulsar-broker ClusterIP None <none> 8080/TCP,6650/TCP 16mmilvus-release-v25-pulsar-proxy ClusterIP 10.233.30.132 <none> 80/TCP,6650/TCP 16mmilvus-release-v25-pulsar-recovery ClusterIP None <none> 8000/TCP 16mmilvus-release-v25-pulsar-zookeeper ClusterIP None <none> 8000/TCP,2888/TCP,3888/TCP,2181/TCP 16m
Milvus 内置 GUI 工具,名为 Milvus WebUI,您可以通过浏览器访问。Milvus Web UI 通过简单直观的界面增强了系统的可观察性。您可以使用 Milvus Web UI 观察 Milvus 组件和依赖项的统计数据和指标,检查数据库和集合详细信息,并列出详细的 Milvus 配置。有关 Milvus Web UI 的详细信息,请参阅Milvus WebUI 官方文档。
Milvus 部署完成后,使用浏览器打开以下链接,http://k8s任意节点IP:31531/webui/
,打开 Web UI 界面。
使用Milvus Operator管理,日常运维工作量大幅减少,特别是管理大型集群时效果更明显。手动配置容易出错的问题基本消失了,集群配置变得更可靠。需要扩容时,只需修改几个参数,资源利用率自然提高。系统出现故障时,Operator能自动修复,不用半夜爬起来救火。版本升级也从原来的漫长折腾变成了简单几步,回滚风险也小多了。
Operator使用成本
团队需要学习Kubernetes基础知识,这对传统运维人员来说需要时间适应。你还得有一个成熟的Kubernetes环境,小团队可能觉得有点小题大做。第一次设置也需要额外投入时间,而且会增加对Kubernetes生态的依赖。
从实用角度看,不同规模团队的收益差别很大。如果你只有几个节点的小集群,可能学习成本比收益还高。中等规模的集群大概半年到一年能看到回报。而大型集群则能很快体会到好处,通常几个月就能收回投资。
使用Opeartor存在的风险
使用Operator也有一些风险需要注意。过度依赖自动化可能导致团队对底层原理理解不足。Kubernetes与Operator版本不匹配有时会出问题。当系统出现故障,调试可能比传统方式更复杂。从手动部署迁移到Operator也需要谨慎规划,避免数据丢失。某种程度上,你也会更依赖特定的技术路线。
Operator使用建议
该不该用Operator?这要看你的实际情况。小团队资源有限,可以先用简单的手动部署,等业务稳定再考虑升级。正在快速发展的团队应该尽早学习Operator,为将来扩展做准备。大型团队则应该把Operator作为标准配置,投入资源构建自动化运维能力。
无论选择哪种方式,关键是要根据自身情况做出合理决策。Operator不是万能药,而是一种强大的工具。明智的做法是在充分了解自身需求和能力的基础上,逐步引入自动化,平衡短期成本和长期收益。
随着向量数据库在AI时代的重要性日益凸显,选择合适的运维策略将成为技术团队的关键竞争力。Milvus Operator为我们提供了一条高效之路,但每个团队都需要找到适合自己的节奏,在自动化与可控性之间取得平衡。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-04-01
官宣,Milvus SDK v2发布!原生异步接口、支持MCP、性能提升
2025-03-30
大模型+知识图谱:重塑企业制度标准管理
2025-03-30
解锁LLM知识库检索:高返回率背后的关键密码
2025-03-29
RAG知识库的数据方案:图数据库、向量数据库和知识图谱怎么选?
2025-03-28
知识图谱落地难,大道至简,二八定律——RAG+Agent
2025-03-26
向量数据库概述
2025-03-26
010:通过 MCP PostgreSQL 安全访问数据
2025-03-25
斯坦福最新KGGEN,用LLM从纯文本中提取知识图,采用DSPy超出GraphRAG精度18.27%
2025-01-02
2024-07-17
2024-08-13
2025-01-03
2024-07-11
2024-08-27
2024-06-24
2024-07-13
2024-07-12
2024-06-10
2025-03-29
2025-02-13
2025-01-14
2025-01-10
2025-01-06
2025-01-02
2024-12-16
2024-12-10