k8s 部署 milvus 集群
本文说明如何使用 Milvus Operator 在 Kubernetes 中启动 Milvus Distributed
[TOC]
1.前期准备
- 机器规划清单如下:
注:生产集群部署建议 CPU 8核+、内存 128G+,访问 https://milvus.io/zh/tools/sizing 估算硬件需求。
| ip地址 | 机器名称 | 角色 | 操作系统 | 配置 |
|---|---|---|---|---|
| 192.168.31.101 | k8s-node101 | master、rancher | Ubuntu 24.04.3 LTS | 4C-8G-60G |
| 192.168.31.102 | k8s-node102 | worker | Ubuntu 24.04.3 LTS | 4C-4G-60G |
| 192.168.31.103 | k8s-node103 | worker | Ubuntu 24.04.3 LTS | 4C-4G-60G |
- 系统初始化
#.修改机器名
newhost=`ifconfig -a|grep inet|grep 192.168.31|awk '{print $2}'|tail -1|awk -F'.' '{print "k8s-node"$4}'`
hostnamectl set-hostname $newhost
cat /etc/hosts | grep `cat /etc/hostname` || echo 127.0.0.1 `cat /etc/hostname` >> /etc/hosts
#.配置hosts文件
cat /etc/hosts | grep "192.168.31.101" > /dev/null || echo "192.168.31.101 k8s-node101" >> /etc/hosts
cat /etc/hosts | grep "192.168.31.102" > /dev/null || echo "192.168.31.102 k8s-node102" >> /etc/hosts
cat /etc/hosts | grep "192.168.31.103" > /dev/null || echo "192.168.31.103 k8s-node103" >> /etc/hosts
cat /etc/hosts | grep "k8s"
#.设置时区
timedatectl set-timezone "Asia/Shanghai"
#.配置ntp时间同步,时间不同步会导致证书错误和集群不稳定
apt-get remove --purge -y systemd-timesyncd ntpsec
apt-get install -y ntp ntpdate
/usr/sbin/ntpdate -u ntp.aliyun.com
- 安装 docker 24.0.1
注:若使用 Rancher 2.7.1,就不要安装过新的 docker 版本,否则会与 RKE 集群 Docker 版本不兼容
curl -sL 'http://iso.sqlfans.cn/docker/install_docker_2401.sh' | bash
docker --version
- 配置 docker 加速
mkdir -p /etc/docker
curl http://iso.sqlfans.cn/config/docker/daemon.202504.json > /etc/docker/daemon.json
systemctl daemon-reload
systemctl restart docker
2.通过 Rancher 部署 k8s 集群
- 第1步,登录 rancher 节点(示例 192.168.31.101),安装 rancher v2.7.1
注:下载不到 rancher v2.12.9,而 rancher v2.14.2 访问控制台会报错 API Aggregation not ready,未解决...
mkdir -p /data/{images,docker}
docker pull rancher/rancher:v2.7.1
# curl -L http://oss.sqlfans.cn/2026/rancher.v2.14.2.tar -o /opt/rancher.v2.14.2.tar && docker load -i /opt/rancher.v2.14.2.tar
docker run --name rancher -d --privileged --restart=unless-stopped -p 80:80 -p 8443:443 -v /etc/localtime:/etc/localtime:ro -v /data/docker/rancher:/var/lib/rancher/ rancher/rancher:v2.7.1
docker exec -it rancher /bin/bash -c '/usr/bin/rancher --version'
docker ps -a
- 第2步,执行
docker logs rancher 2>&1 | grep Password获取 rancher 控制台的初始密码,比如:
root@k8s-rancher:~# sleep 10 && docker logs rancher 2>&1 | grep Password
2026/06/08 17:16:52 [INFO] Bootstrap Password: jl7tzxlqwf4kcpk56lk2pp92n7vb94ctszbgvdsg6m4n2v9rddj8qz
- 第3步,使用浏览器访问 rancher 控制台 https://192.168.31.101:8443 ,设置 admin 新的密码,比如:Admin_147258
- 第4步,在欢迎页,点 Create 创建集群
- 第5步,选择 Custom,即:使用现有节点并使用 RKE 创建集群
- 第6步,创建集群,比如 k8s
- 第7步,关于角色选择,若 Master 请勾选 Etcd + Control,若 Worker 请勾选 Worker,若 Master 也充当 Worker 则请全选。
示例:k8s-node01 全选,k8s-node02 和 k8s-node03 只勾选 Worker
- 第8步,复制上一步的命令去相应节点的SSH终端运行,示例如下:
[root@k8s-node01 ~]# sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.7.1 --server https://192.168.31.101:8443 --token ****** --ca-checksum ****** --etcd --controlplane --worker
[root@k8s-node02 ~]# sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.7.1 --server https://192.168.31.101:8443 --token ****** --ca-checksum ****** --worker
[root@k8s-node03 ~]# sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.7.1 --server https://192.168.31.101:8443 --token ****** --ca-checksum ****** --worker
注:所有节点执行完之后,上一步的页面下面会提示 3 new nodes have registered.
- 第9步,待复制上一步的命令并去对应节点运行之后,再点最下面的 Done,然后等待集群初始化
- 第10步,登录 rancher 节点(示例 192.168.31.101),确认k8s集群信息
docker exec -it rancher /bin/bash -c '/usr/bin/kubectl version --short'
docker exec -it rancher /bin/bash -c '/usr/bin/kubectl get componentstatuses'
docker exec -it rancher /bin/bash -c '/usr/bin/kubectl get nodes'
- 第11步,刷新 rancher 控制台,查看集群- Nodes 查看节点状态
- 第12步,登录 rancher 节点(示例 192.168.31.101),安装kubectl v1.26.3
curl -L https://dl.k8s.io/release/v1.26.3/bin/linux/amd64/kubectl -o /usr/bin/kubectl
#curl -L http://iso.sqlfans.cn/k8s/kubectl.v1.26.3 -o /usr/bin/kubectl
chmod +x /usr/bin/kubectl
kubectl version --short
- 第13步,将 kubectl 关联k8s资源
mkdir ~/.kube
touch ~/.kube/config
#.集群首页右上角,点击 Copy KubeConfig to Clipboard,并将内容覆盖到~/.kube/config
kubectl get nodes
3.部署 StorageClass
- 第1步,刚搭建的 k8s 集群默认没有 StorageClass(存储类)
$ kubectl get sc
No resources found
- 第2步,准备 StorageClass 部署文件,通过 name 指定名称为 gold、numberOfReplicas 指定3个数据副本、fsType 指定文件系统为xfs
cat > /opt/k8s_storageclass.yaml <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gold
provisioner: driver.longhorn.io
allowVolumeExpansion: true
parameters:
numberOfReplicas: "3"
fsType: "xfs"
EOF
- 第3步,创建一个名为 gold 的 StorageClass,并将其标记为 (default) 默认
#.安装 StorageClass, 名为 gold
$ kubectl apply -f /opt/k8s_storageclass.yaml
storageclass.storage.k8s.io/gold created
#.确认 StorageClass, 名为 gold
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gold driver.longhorn.io Delete Immediate true 23s
#.如果此时有一个默认的storageclass, 比如名为 standard, 则需要将其标记为非默认
# kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
#.将 gold 标记为默认
$ kubectl patch storageclass gold -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
storageclass.storage.k8s.io/gold patched
#.确认 gold 为默认的 StorageClass
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gold (default) driver.longhorn.io Delete Immediate true 93s
4.通过 Milvus Operator 部署 Milvus 集群
- 第1步,安装 Milvus Operator,示例中 命名空间为 milvus-operator
注:配置文件参考:
https://raw.githubusercontent.com/zilliztech/milvus-operator/main/deploy/manifests/deployment.yaml
#.安装 Milvus Operator
$ kubectl apply -f http://iso.sqlfans.cn/2026/milvus-operator-k8s-deployment.yaml
namespace/milvus-operator created
......
deployment.apps/milvus-operator created
#.查看命名空间
$ kubectl get namespace | grep -E "default|milvus"
default Active 15h
milvus-operator Active 11s
#.确认 milvus-operator 这个命名空间中的 pod 状态为 Running
$ kubectl get pods -n milvus-operator
NAME READY STATUS RESTARTS AGE
milvus-operator-867c87788b-jrbqv 1/1 Running 0 14m
# 查看默认命名空间的 pod 状态
$ kubectl get pods -n default
No resources found in default namespace.
- 第2步,准备配置文件 /opt/milvus_cluster_woodpecker.yaml,示例中 metadata 名为 my-release
注:从 Milvus 2.6 开始用自研的 woodpecker 来替代外部消息队列(比如 Kafka、Pulsar)以降低复杂性和运维负担,配置文件参考:
https://raw.githubusercontent.com/zilliztech/milvus-operator/main/config/samples/milvus_cluster_woodpecker.yaml
cat > /opt/milvus_cluster_woodpecker.yaml <<EOF
apiVersion: milvus.io/v1beta1
kind: Milvus
metadata:
name: my-release
labels:
app: milvus
spec:
mode: cluster
components:
image: milvusdb/milvus:v2.6.0
config: {}
dependencies:
msgStreamType: woodpecker
EOF
- 第3步,使用 Milvus Operator 部署 Milvus 2.6.0 集群
注:Operator 会先创建 Milvus 依赖组件, 如 etcd(元数据存储)、消息队列、MinIO(对象存储), 然后创建 Milvus 组件, 如代理、协调器和节点
$ kubectl apply -f /opt/milvus_cluster_woodpecker.yaml
milvus.milvus.io/my-release created
- 第4步,部署依赖组件可能需要几分钟时间,可以通过以下命令监控部署状态:
# 查看 Milvus 集群状态
$ kubectl get milvus my-release
NAME MODE STATUS UPDATED AGE
my-release cluster Pending False 33s
# 查看 events 事件
kubectl get events --sort-by='.lastTimestamp' | tail -20
# 查看 Milvus 集群状态的更多信息, 若 status.status 变为 Healthy 则表示群集已创建成功
$ kubectl get milvus my-release -o yaml | tail -1
status: Healthy
# 查看 pvc 持久化卷 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-my-release-etcd-0 Pending gold 4h40m
data-my-release-etcd-1 Pending gold 4h40m
data-my-release-etcd-2 Pending gold 4h40m
export-my-release-minio-0 Pending gold 4h40m
export-my-release-minio-1 Pending gold 4h40m
export-my-release-minio-2 Pending gold 4h40m
export-my-release-minio-3 Pending gold 4h40m
# 查看默认命名空间的 Pod 的状态 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-release-etcd-0 1/1 Running 0 2m36s
my-release-etcd-1 1/1 Running 0 2m36s
my-release-etcd-2 1/1 Running 0 2m36s
my-release-milvus-datanode-58955c65b9-j4j7s 1/1 Running 0 92s
my-release-milvus-mixcoord-686f84968f-jcv5d 1/1 Running 0 92s
my-release-milvus-proxy-646f48fc7c-4lctb 1/1 Running 0 92s
my-release-milvus-querynode-0-d89d7677b-x7j7q 1/1 Running 0 91s
my-release-milvus-streamingnode-556bdcc87c-2qwcc 1/1 Running 0 92s
my-release-minio-0 1/1 Running 0 2m36s
my-release-minio-1 1/1 Running 0 2m36s
my-release-minio-2 1/1 Running 0 2m35s
my-release-minio-3 1/1 Running 0 2m35s
- 第5步,获取 Milvus 集群的服务端口
$ kubectl get pod my-release-milvus-proxy-646f48fc7c-4lctb --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
19530
- 第6步,配置端口外发(格式:本地端口:容器端口),以便外部访问 Milvus
# 查看 svc 服务及端口监听状态
kubectl get svc
# 确认端口已监听
netstat -lnpt | grep -E "2379|9000|9001|9091|19530"
# 配置 Milvus 端口外发
kubectl port-forward --address 0.0.0.0 service/my-release-milvus 19530:19530
# 配置 Milvus Web UI 端口外发
kubectl port-forward --address 0.0.0.0 service/my-release-milvus 9091:9091
- 第7步,使用 Python SDK 连接测试:保持端口转发开启,打开一个新终端,运行以下 Python 脚本进行连接测试:
from pymilvus import MilvusClient
# 连接Milvus
client = MilvusClient(uri="http://localhost:19530")
# 创建集合
collection_name = "example_collection"
if client.has_collection(collection_name):
client.drop_collection(collection_name)
client.create_collection(
collection_name=collection_name,
dimension=768,
)
print(f"Collection '{collection_name}' created successfully!")
- 如果控制台成功输出了创建集合的信息,则表示 Milvus 集群已经在 K8s 上跑起来了。
5.卸载 Milvus
# 卸载 Milvus
kubectl delete milvus my-release
# 卸载 Milvus Operator
# kubectl delete -f https://raw.githubusercontent.com/zilliztech/milvus-operator/main/deploy/manifests/deployment.yaml
kubectl delete -f http://iso.sqlfans.cn/2026/milvus-operator-k8s-deployment.yaml






