🚀 Milvus 实战部署全记录

🚀 Milvus 实战部署全记录

Milvus 2.5.23 + Attu + 鉴权 + 幂等初始化(Docker Compose)


一、背景说明

在实际工程中部署 Milvus,并不是简单 docker run 就能解决的问题。

本文完整记录了一次 从踩坑到稳定上线 的 Milvus 私有化部署过程。

最终方案选择:

  • Milvus v2.5.23(Standalone)
  • 开启官方鉴权(RBAC)
  • Attu 管理界面
  • 幂等的初始化用户方案
  • Docker Compose 一键部署

二、为什么选择 Milvus 2.5.23?

放弃 2.6.7 的原因

  1. 内存要求更高

    • 2.6.x 引入 StreamingNode
    • 启动时内存占用明显增加
    • 8G 内存机器非常吃力
  2. MinIO 依赖更激进

    • 常搭配 minio/minio:RELEASE.2024-05-28T17-19-04Z
    • 部分环境下存在 GPU / 指令集兼容问题
    • MinIO 起不来 → Milvus 直接失败

选择 2.5.23 的理由

  • 架构成熟
  • 资源占用低
  • MinIO 兼容性好
  • Attu / SDK 稳定

结论:2.5.23 是当前工程部署的"甜点版本"


三、项目目录结构

text 复制代码
milvus/
├── docker-compose.yml
├── config/
│   └── milvus.yaml
├── init/
│   ├── Dockerfile
│   └── init_user.py
└── volumes/

四、docker-compose.yml

yaml 复制代码
version: '3.5'

services:
  etcd:
    container_name: milvus-etcd
    image: quay.io/coreos/etcd:v3.5.18
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision
      - ETCD_AUTO_COMPACTION_RETENTION=1000
      - ETCD_QUOTA_BACKEND_BYTES=4294967296
      - ETCD_SNAPSHOT_COUNT=50000
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd
    command: etcd -advertise-client-urls=http://etcd:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
    healthcheck:
      test: ["CMD", "etcdctl", "endpoint", "health"]
      interval: 30s
      timeout: 20s
      retries: 3
    networks:
      - milvus
  minio:
    container_name: milvus-minio
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    ports:
      - "9001:9001"
      - "9000:9000"
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data
    command: minio server /minio_data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3
    networks:
      - milvus
  milvus:
    container_name: milvus-standalone
    image: milvusdb/milvus:v2.5.23
    command: ["milvus", "run", "standalone"]
    security_opt:
      - seccomp:unconfined
    environment:
      MINIO_REGION: us-east-1
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
      - ${DOCKER_VOLUME_DIRECTORY:-.}/config/milvus.yaml:/milvus/configs/milvus.yaml
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
      interval: 30s
      start_period: 90s
      timeout: 20s
      retries: 3
    ports:
      - "19530:19530"
      - "9091:9091"
    depends_on:
      - "etcd"
      - "minio"
    networks:
      - milvus
  attu:
    container_name: milvus-attu
    image: zilliz/attu:v2.4
    environment:
      MILVUS_URL: milvus:19530
      MILVUS_USERNAME: root
      MILVUS_PASSWORD: Milvus@123
    ports:
      - "17000:3000"
    depends_on:
      - "milvus"
    networks:
      - milvus
  init:
    build: ./init
    container_name: milvus-init
    environment:
      MILVUS_HOST: milvus
      NEW_ROOT_PASSWORD: ********  #设置自己新的密码
      APP_USER: ********			#应用账号
      APP_PASSWORD: ********		#应用密码
      APP_ROLE: admin
    networks:
      - milvus
    depends_on:
      - milvus
    restart: "no"
networks:
  milvus:

五、开启 Milvus 官方鉴权

config/milvus.yaml

yaml 复制代码
common:
  security:
    authorizationEnabled: true

开启后:

  • 所有客户端必须登录
  • Attu 也必须使用账号密码

六、幂等的 Milvus 初始化用户方案

init/Dockerfile

dockerfile 复制代码
FROM python:3.10-slim-bullseye
RUN pip install --no-cache-dir pymilvus==2.5.16
WORKDIR /app
COPY init-user.py /app/init-user.py
CMD ["python", "/app/init-user.py"]

init/init_user.py

python 复制代码
import os
import time
from pymilvus import connections, utility, Role
from pymilvus.exceptions import MilvusException

# ---------- 基础配置 ----------
MILVUS_HOST = os.getenv("MILVUS_HOST", "milvus")
MILVUS_PORT = os.getenv("MILVUS_PORT", "19530")

ROOT_USER = "root"
DEFAULT_ROOT_PASSWORD = os.getenv("ROOT_PASSWORD", "Milvus")
NEW_ROOT_PASSWORD = os.getenv("NEW_ROOT_PASSWORD")  # 可选

APP_USER = os.getenv("APP_USER", "app_user")
APP_PASSWORD = os.getenv("APP_PASSWORD", "App@123456")
APP_ROLE = os.getenv("APP_ROLE", "admin")

# ---------- 等待 Milvus ----------
print("⏳ Waiting for Milvus to be ready...")
time.sleep(12)

# ---------- 使用默认 root 密码连接 ----------
connections.connect(
    alias="default",
    host=MILVUS_HOST,
    port=MILVUS_PORT,
    user=ROOT_USER,
    password=DEFAULT_ROOT_PASSWORD
)

# ---------- 修改 root 密码(幂等) ----------
if NEW_ROOT_PASSWORD and NEW_ROOT_PASSWORD != DEFAULT_ROOT_PASSWORD:
    try:
        utility.update_password(
            ROOT_USER,
            DEFAULT_ROOT_PASSWORD,
            NEW_ROOT_PASSWORD
        )
        print("✅ Root password updated")

        # 重新连接(非常重要)
        connections.disconnect("default")
        connections.connect(
            alias="default",
            host=MILVUS_HOST,
            port=MILVUS_PORT,
            user=ROOT_USER,
            password=NEW_ROOT_PASSWORD
        )
    except MilvusException as e:
        if "password is incorrect" in str(e) or "authentication failed" in str(e):
            print("ℹ️ Root password already changed, continue")
            connections.disconnect("default")
            connections.connect(
                alias="default",
                host=MILVUS_HOST,
                port=MILVUS_PORT,
                user=ROOT_USER,
                password=NEW_ROOT_PASSWORD
            )
        else:
            raise

# ---------- 创建用户 ----------
try:
    utility.create_user(APP_USER, APP_PASSWORD)
    print(f"✅ User created: {APP_USER}")
except MilvusException as e:
    if "already exists" in str(e):
        print(f"ℹ️ User already exists: {APP_USER}")
    else:
        raise

# ---------- 创建角色 ----------
role = Role(APP_ROLE)
try:
    role.create()
    print(f"✅ Role created: {APP_ROLE}")
except MilvusException as e:
    if "already exists" in str(e):
        print(f"ℹ️ Role already exists: {APP_ROLE}")
    else:
        raise

# ---------- 绑定角色 ----------
try:
    role.add_user(APP_USER)
    print(f"✅ Granted role [{APP_ROLE}] to user [{APP_USER}]")
except MilvusException as e:
    if "already" in str(e):
        print("ℹ️ Role already granted")
    else:
        raise

print("🎉 Milvus RBAC initialization finished")

幂等性说明

  • 重复执行不会报错
  • 适合 CI/CD
  • 容器只执行一次即可退出

七、运行与验证

bash 复制代码
docker compose up -d

成功标志:

  • milvus-init 容器执行后退出,具体的执行日志如下:

    csharp 复制代码
    #执行脚本
    docker logs -f milvus-init
  • Milvus 日志无 ERROR

  • Milvus 的webui管理端,注意这个管理端没有账号与密码,能直接访问

  • Attu需要账号密码才能登录,需要自己测试下新的root密码、应用账号与密码

八、踩坑记录

9091 访问不了?

原因:

  • Milvus 未完全就绪
  • MixCoord 尚未启动完成

解决:

  • 耐心等待
  • 通过 docker logs -f milvus-standalone 查看状态

docker start 看不到日志?

bash 复制代码
docker logs -f milvus-standalone

没有 /var/lib/milvus/logs 目录?

  • 2.5.x 默认日志输出 stdout
  • 属于正常现象

有异常需要重新操作

  • 看情况,可以选择从新编译init的镜像

    csharp 复制代码
     docker-compose build init
  • 账号信息放在ect里面,根据情况可以删除

    bash 复制代码
    rm -rf ./volumes/*

九、总结

  • Milvus 是工程系统,不是 Demo
  • 2.5.23 是当前最稳妥的生产选择
  • 初始化用户一定要做成幂等
  • 鉴权 + Attu 才是完整方案

一次搭好,后面都省心


完 🎉

相关推荐
蝎子莱莱爱打怪5 小时前
GitLab CI/CD + Docker Registry + K8s 部署完整实战指南
后端·docker·kubernetes
KEEN的创享空间6 小时前
AI编程从0到1之10X提效(Vibe Coding 氛围式编码 )09篇
openai·ai编程
AlienZHOU7 小时前
为 AI Agent 编写高质量 Skill:Claude 官方指南
agent·ai编程·claude
倔强的石头_7 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
恋猫de小郭7 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
KaneLogger8 小时前
【翻译】打造 Agent Skills 的最佳实践
agent·ai编程·claude
王小酱9 小时前
Everything Claude Code 文档
openai·ai编程·aiops
雮尘10 小时前
如何在非 Claude IDE (TARE、 Cursor、Antigravity 等)下使用 Agent Skills
前端·agent·ai编程
刘贺同学10 小时前
Day12-龙虾哥打工日记:OpenClaw 子 Agent 到底看到了什么?
aigc·ai编程
程序员鱼皮12 小时前
离大谱,我竟然在 VS Code 里做了个视频!
github·aigc·ai编程