首页
/ Milvus .deb 包构建实战:用容器化构建环境打包并安装 Standalone 部署包

Milvus .deb 包构建实战:用容器化构建环境打包并安装 Standalone 部署包

2026-09-07 17:41:54作者:申梦珏Efrain

本篇基于仓库中 build/deb/README.md 展开,讲解如何利用 Docker 容器化构建环境,把已编译好的 Milvus 二进制打包成 Debian/Ubuntu 可安装的 .deb 软件包。读完本文,你将掌握完整的 build_deb.sh 构建流程、Debian 包内部的目录布局与 systemd 服务配置,以及安装后的嵌入式 etcd/MinIO 配置切换方法,能够独立完成 Milvus 在 Debian 系系统上的本地化部署。

构建流程总览

Milvus 的 deb 包构建被设计为"容器内构建"模式:借助 milvusdb/milvus 官方镜像作为构建环境(镜像内已包含编译好的 /milvus 产物与完整依赖库),在宿主机上只负责提供 build/deb 目录,打包动作全部在容器内完成。整体流程分为 7 步:

  1. 安装 Docker(按所使用操作系统的官方指引安装即可);
  2. 获取开源代码并复制打包目录;
  3. 启动 Milvus 容器并执行 build_deb.sh 生成 deb 包;
  4. 在 Ubuntu/Debian 系统上安装该包;
  5. 通过 systemd 检查 Milvus 服务状态;
  6. 连接 Milvus 验证;
  7. 卸载或切换为外部依赖模式(可选)。

下面逐步展开。

获取代码并准备构建目录

首先克隆仓库并把 build/deb 目录复制出来,作为容器挂载的工作目录:

git clone https://github.com/milvus-io/milvus.git
cp -r milvus/build/deb .
cd deb

注意这里只复制了 build/deb 一个目录,因为真正需要参与打包的只有构建脚本和 debian/ 元数据;Milvus 二进制本身来自构建镜像内的 /milvus,无需在宿主机上执行 C++/Go 编译。

在容器中执行构建

启动一个 milvusdb/milvus 镜像容器,把当前 deb 目录挂载进容器,并将 entrypoint 改为 bash 以便交互执行脚本:

# Replace the VERSION with your own
sudo docker run -v .:/deb -ti --entrypoint /bin/bash milvusdb/milvus:v$VERSION
# in the container
cd /deb
bash build_deb.sh $VERSION $VERSION $MAINTAINER $DEBEMAIL

build_deb.sh 接收 4 个参数:前两个均为版本号(脚本内部第二个参数用于生成包名 milvus-$2.tar.gz 与 changelog),后两个分别作为 Debian 包的 Maintainer 姓名与邮箱(写入 DEBFULLNAME/DEBEMAIL 环境并执行 bzr whoami "$3 $4")。

build_deb.sh 到底做了什么

从源码 build/deb/build_deb.sh 看,整个构建过程可分为四个阶段,理解它有助于排查打包失败问题:

1. 改造运行时配置为嵌入式模式(L4–L16)

脚本从镜像内的 /milvus 拷贝出一份运行时目录,并针对 deb 场景做四处关键修改:

cp -r /milvus .
sed -i 's#embed: false#embed: true#' milvus/configs/milvus.yaml
sed -i 's#dir: default.etcd#data.dir: /var/lib/milvus/etcd#' milvus/configs/milvus.yaml
sed -i '/data.dir: \/var\/lib\/milvus\/etcd/a \  config:\n    path: /etc/milvus/configs/embedEtcd.yaml' milvus/configs/milvus.yaml
sed -i 's#storageType: remote#storageType: local#' milvus/configs/milvus.yaml

这解释了原文档中"By default, Milvus is started in embed mode"的说法:deb 包安装出的 Milvus 默认内嵌 etcd、本地存储common.storageType: local),无需外部依赖即可启动。同时脚本生成了一份独立的嵌入式 etcd 配置 embedEtcd.yaml

listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://0.0.0.0:2379
quota-backend-bytes: 4294967296
auto-compaction-mode: revision
auto-compaction-retention: '1000'

2. 组装 deb 包目录树(L19–L32)

mkdir -p milvus-deb/milvus
mkdir milvus-deb/milvus/milvus-bin
mkdir milvus-deb/milvus/milvus-lib
cp milvus/bin/milvus milvus-deb/milvus/milvus-bin/        # 主二进制
cp -d milvus/lib/* milvus-deb/milvus/milvus-lib/          # 动态库
cp /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0 milvus-deb/milvus/milvus-lib/libgomp.so.1
cp -r scripts milvus-deb/milvus/                          # systemd/ld.so 脚本
cp -r milvus/configs milvus-deb/milvus/                   # 运行配置

从源码结构看,这一阶段把产物分为四类:主程序 milvus-bin、依赖库 milvus-lib(含从系统拷贝的 libgomp.so.1)、systemd 与库路径脚本 scripts、以及 configs 配置目录,为后续按 Debian 规范布局做准备。

3. 安装打包工具链并初始化包(L34–L57)

apt install gnupg pbuilder ubuntu-dev-tools apt-file dh-make build-essential brz-debian -y
bzr whoami "$3 $4"
export DEBFULLNAME="$3"
export DEBEMAIL="$4"

随后进入 milvus-deb,把 milvus 目录打成源码包并让 dh-make 生成 Debian 工程骨架:

tar zcf milvus-$2.tar.gz milvus
bzr dh-make milvus $2 milvus-$2.tar.gz

接着用 sed 修正自动生成的 debian/changelog(把 unstable 改为 bionic、填入版本号 $2-1),清理 README.Debian/README.source 的占位内容,再用仓库中人工维护的 build/deb/debian/ 覆盖自动生成的 debian/*,并删除 *.ex/*.EX 示例文件——这正是仓库 build/deb/debian/ 目录下那批元数据文件的用途。

4. 执行 dpkg-buildpackage(L59–L63)

cd milvus
bzr add debian/source/format
bzr commit -m "Initial commit of Debian packaging."
dpkg-buildpackage -us -uc -ui

-us -uc -ui 表示不签名、不校验签名,适合本地/CI 构建。构建完成后,deb 包生成在 milvus-deb/ 目录中,文件名形如 milvus_$VERSION-1_amd64.deb

Debian 包内部结构:目录布局与 systemd 服务

包的实际布局由 build/deb/debian/rules 中的 override_dh_auto_install 决定(override_dh_auto_build 直接跳过编译,因为二进制已在镜像内构建好)。安装后的文件系统布局如下:

包内路径 安装目标 作用
milvus-bin/milvus /usr/bin/milvus 主可执行文件
milvus-lib/* /usr/lib/milvus/ 动态依赖库
configs/milvus.yamlconfigs/glog.confconfigs/embedEtcd.yamlconfigs/advanced/* /etc/milvus/configs/ 运行配置
scripts/milvus.conf /etc/ld.so.conf.d/ 动态库搜索路径声明
scripts/milvus.service /lib/systemd/system/ systemd 服务单元

其中 build/deb/scripts/milvus.conf 内容仅一行 /usr/lib/milvus,通过 ld.so.conf.d 机制让系统动态链接器能找到打包在内的第三方库,避免与宿主系统库冲突;dh_shlibdeps 也被覆写为 -l milvus-lib,显式指定库搜索目录以正确计算 ${shlibs:Depends}

服务单元 build/deb/scripts/milvus.service 定义了服务的启动方式:

[Unit]
Description=Milvus Standalone Server
After=network.target syslog.target

[Install]
WantedBy=multi-user.target
Alias=milvus.service

[Service]
Type=simple
StandardOutput=journal
StandardError=inherit
Restart=always

Environment=MILVUSCONF=/etc/milvus/configs/
ExecStart=/usr/bin/milvus run standalone

两个值得注意的点:一是 ExecStart=/usr/bin/milvus run standalone,即 deb 包安装的就是 Standalone 模式,配置目录通过环境变量 MILVUSCONF 注入;二是 Restart=always 配合 WantedBy=multi-user.target,意味着服务开机自启且异常退出后会自动拉起。

包元数据见 build/deb/debian/controlArchitecture: any-amd64(当前只支持 x86_64,这也解释了为何产物文件名固定带 amd64 后缀)、依赖 ${shlibs:Depends}, ${misc:Depends}, tzdataBuild-Depends 要求 debhelper 10 与 gcc/g++ 7.5 以上。此外 build/deb/debian/source/format 声明源码格式为 3.0 (quilt)build/deb/debian/compat 声明 debhelper 兼容级别 10。作为对照,仓库 build/rpm/ 下提供了 RPM 发行版(milvus.spec + 独立 etcd/minio 服务单元),两者是并列的发行版打包方案,deb 路线走的是嵌入式单包,而 RPM 路线附带了 milvus-etcd.servicemilvus-minio.service 外部组件。

在 Ubuntu/Debian 系统上安装

构建成功后回到宿主机,在目标机器上执行:

sudo apt-get update
sudo dpkg -i milvus_$VERSION-1_amd64.deb # This package is in the milvus-deb directory
sudo apt-get -f install

dpkg -i 安装后若因 ${shlibs:Depends} 计算出缺失的系统库(如 glibc、libgomp 等动态库依赖),用 apt-get -f install 自动补齐依赖是标准做法。

随后检查服务状态:

sudo systemctl status milvus

由于服务单元已配置开机自启与自动重启,正常情况下安装完成后 milvus.service 即处于 active (running) 状态。

连接 Milvus

安装完成后,可参考 Milvus 官方的 Hello Milvus 示例代码连接实例。仓库中 client/ 目录提供了 Go SDK(含 client/milvusclient 客户端实现),tests/go_client/ 下也有完整的 Go 客户端测试用例可供参考。deb 包安装的是 Standalone 模式,gRPC 默认端口可在 configs/milvus.yaml 中确认相关监听配置。

卸载

sudo dpkg -P milvus

dpkg -P--purge)会同时删除包文件与 /etc/milvus/ 下的配置;若只需保留配置,可改用 dpkg -r

可选:切换为外部 etcd 与 MinIO

原文档特别指出:默认情况下 Milvus 以 embed 模式启动(内嵌 etcd + 本地存储)。如果生产环境依赖外部的 etcd 与 MinIO,需要修改配置后重启服务:

sudo vim /etc/milvus/configs/milvus.yaml

按如下方式修改(与 configs/milvus.yaml 中的字段含义一致):

etcd:
  endpoints: etcd-ip:2379
  ...
minio:
  address: minio-ip
  ...
common:
  storageType: remote

各字段在仓库配置中的对应关系可以佐证:

  • etcd.endpoints 默认值为 localhost:2379(见 configs/milvus.yaml,且 ETCD_ENDPOINTS 环境变量优先级更高);
  • minio.address 默认值为 localhost:9000(见 configs/milvus.yaml);
  • common.storageType 的可选值为 [local, remote],其中 minio 取值已废弃、以 remote 代替(见 configs/milvus.yaml 的注释)。

关于嵌入开关,从 build_deb.sh 的 sed 逻辑(s#embed: false#embed: true#)可以推断:上游镜像的 milvus.yamletcd.embed 默认为 false,deb 打包阶段把它翻转为 true,并追加 data.dir: /var/lib/milvus/etcdconfig.path: /etc/milvus/configs/embedEtcd.yaml 两处 etcd 内嵌数据/配置路径;因此切换外部 etcd 时,除修改 endpoints 外,还应将 etcd.embed 置回 false(原文档示例中的 use: embed: false 一节),否则内嵌 etcd 仍会监听 2379 端口,可能与外部 etcd 或本机服务冲突。

修改完成后重启服务使配置生效:

sudo systemctl restart milvus
sudo systemctl status milvus

小结

Milvus 的 deb 打包方案将"编译产物供给"与"Debian 工程构建"解耦:容器镜像负责提供 /milvus 编译产物与完整库依赖,build/deb.sh + debian/ 元数据负责配置改写(嵌入式 etcd、本地存储)、目录树组装、dh-make/dpkg-buildpackage 流水线。安装后得到的是一套开箱即用的 Standalone 部署——/usr/bin/milvus run standalone 由 systemd 托管,配置位于 /etc/milvus/configs/,并可通过 storageType: remoteetcd.embed 两个开关平滑切换到外部 etcd/MinIO 的生产形态。排查打包问题时,建议按"配置改写 → 目录树组装 → dh-make 骨架生成 → dpkg-buildpackage 报错"四个阶段对照 build/deb/build_deb.sh 定位。

登录后查看全文
热门项目推荐
相关项目推荐