尧图精选

Qdrant E2E 测试指南:TLS 证书再生成与存储数据兼容性维护

🕒 发布时间:2026/9/10 17:26:43 📁 来源:尧图网络
Qdrant E2E 测试指南TLS 证书再生成与存储数据兼容性维护【免费下载链接】qdrantQdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/项目地址: https://gitcode.com/GitHub_Trending/qd/qdrant本文面向 Qdrant 仓库贡献者与自建 CI 的维护者系统讲解tests/e2e_tests/端到端测试中两类“需要手工维护外部依赖”的任务一是本地根 CA / 服务端 / 客户端 mTLS 证书的重新签发二是为存储后向兼容性测试重新生成参考存储目录与快照并发布到 GCP bucket。读完本文你既能按步骤复现两类再生成流程也能理解其背后的 Docker 集群编排、OpenSSL 配置与多版本兼容性验证机制。一、端到端测试目录全景在动手维护前先明确tests/e2e_tests/的整体布局与本文聚焦的文件。该目录承载的是面向真实运行态的“端到端”测试区别于tests/openapi等接口级测试大量用例依赖 Docker 与镜像构建核心入口定义如下tests/e2e_tests/README.md本文依据的主文档包含 TLS 测试与数据兼容性测试的说明tests/e2e_tests/test_data/全部测试数据与辅助脚本所在目录tests/e2e_tests/conftest.py会话级 fixture如docker_client、qdrant_image、test_data_dir其中qdrant_image默认会构建标签为qdrant/qdrant:e2e-tests的镜像仅在镜像不存在或显式要求重建时才构建tests/e2e_tests/utils.py公共工具函数如run_docker_compose向 compose 环境注入QDRANT_IMAGE。主文档把维护工作划分为两大主题本章节按主文档脉络逐层展开TLS 测试TLS test如何重新签发证书以驱动双向 TLSmTLS集群测试数据兼容性测试Data compatibility test如何在格式演进后重新生成参考存储数据保证当前代码仍能读懂上一个稳定版写出的磁盘格式。二、TLS 测试基于 mTLS 的集群安全验证2.1 测试要验证什么主文档中“TLS test”一节对应的是 tests/e2e_tests/test_tls.py。从该测试实现看其核心断言覆盖三层能力HTTP/HTTPS 双向 TLS以requests.Session携带 CA 校验 客户端证书请求/telemetry、/cluster断言集群内恰好 2 个 peer且每个 peer 的 URI 均以https://开头并携带端口:6335内部 p2p 通信端口gRPC mTLS复用fullstorydev/grpcurlDocker 镜像挂载证书目录与 proto 目录lib/api/src/grpc/proto调用qdrant.Qdrant/HealthCheck验证node1.qdrant:6334的 gRPC 服务TLS 环境下的分片转移在两节点集群中创建带shard_number: 2的测试集合、写入 4 个点再发起replicate_shard快照转移最终校验远端副本出现。2.2 集群如何以 TLS 拉起该测试并不裸跑二进制而是通过 tests/e2e_tests/test_data/tls-compose.yaml 编排双节点 docker-compose 集群。关键点包括镜像取自环境变量${QDRANT_IMAGE:-qdrant/qdrant:dev}实际执行时由 conftest 注入构建好的e2e-tests镜像node1 以--uri https://node1.qdrant:6335启动node2 额外带--bootstrap https://node1.qdrant:6335表明节点间内网通信统一走 6335 端口的 HTTPS两个容器均把宿主机的./cert目录挂载为/qdrant/tls把 tests/e2e_tests/test_data/tls_config.yaml 以只读方式挂载为/qdrant/config/tls_config.yaml。2.3 TLS 配置参数全解集群运行时读取的 tls_config.yaml 是一份“注解齐全”的最小配置结合仓库配置结构逐项说明如下log_level: INFO service: # 对客户端HTTP/gRPC API通信启用 TLS enable_tls: true # 校验用户 HTTPS 客户端证书是否要求客户端提供由 tls.ca_cert 中 CA 签发的证书 verify_https_client_certificate: true cluster: # 分布式部署模式开关 enabled: true # 集群内部节点间通信配置 p2p: # 节点间通信p2p启用 mTLS enable_tls: true # TLS 证书配置 tls: # 证书链文件服务端证书 cert: ./tls/cert.pem # 私钥文件 key: ./tls/key.pem # 客户端证书校验用的 CA 证书 ca_cert: ./tls/cacert.pem值得注意的路径细节由于 tls_config.yaml 运行在容器内的/qdrant/config/而证书被挂载于/qdrant/tls/因此配置中写的是./tls/cert.pem这类相对路径相对于进程工作目录/qdrant与宿主机上“test_data内平铺 cert 与 yaml”的布局正好对应。该文件同时开启service.enable_tls与cluster.p2p.enable_tls使「对外 API」与「对内 p2p」均加密这正是测试中既检查 6333/6334 客户端入口、又检查 6335 peer URI 的原因。三、重新生成 TLS 证书证书属于长期资产默认有效期长达 3650 天约 10 年但一旦泄露、主机名规划调整或测试拓扑变化就需要按主文档给出的两步流程重签。3.1 第一步运行生成脚本在主文档指定的相对位置运行 tests/e2e_tests/test_data/gen.sh# 在仓库根目录PROJECT_ROOT执行 bash tests/e2e_tests/test_data/gen.sh脚本内部利用 OpenSSL 完成一个完整 PKI 基础设施的搭建可分三阶段理解生成根 CA 自签证书openssl req -new -newkey rsa:2048 -days 3650 -nodes -x509 \ -subj /CUS/STState/LCity/OQdrant \ -addext keyUsage critical, keyCertSign, cRLSign \ -addext basicConstraints critical, CA:TRUE \ -keyout cakey.pem -out cacert.pem产出cakey.pemCA 私钥与cacert.pemCA 证书对应配置中的ca_cert。注意basicConstraints CA:TRUE与keyCertSign扩展使它具备继续签发下级证书的资格。生成服务端/客户端私钥openssl genrsa -out key.pem 2048 chmod 644 key.pem单一key.pem同时充当服务端与客户端密钥——该测试使用同一套证书做双向 TLS证书内容须同时包含serverAuth与clientAuth用途见 3.2。用 CA 签发证书先用 tests/e2e_tests/test_data/cert.cfg 生成 CSR再以 CA 私钥签发cert.pem。3.2 证书主题与 SAN 配置签发时的-config与-extfile均指向 cert.cfg该文件同时定义了 DN 与扩展尤其重要的是subjectAltNameSAN它决定证书可被哪些主机名/地址信任[req] default_bits 2048 default_md sha256 prompt no distinguished_name req_distinguished_name req_extensions v3_req [req_distinguished_name] CN qdrant [v3_req] basicConstraints CA:FALSE keyUsage digitalSignature, keyEncipherment extendedKeyUsage clientAuth, serverAuth subjectAltName alt_names [alt_names] DNS.1 node1.qdrant DNS.2 node2.qdrant DNS.3 localhost IP.1 127.0.0.1解读关键字段extendedKeyUsage clientAuth, serverAuth一套证书同时支持服务端认证与客户端认证是 mTLS 得以成立的前提[alt_names]node1.qdrant、node2.qdrant恰好对应 compose 中两个容器的 hostname也对应 test_tls.py 中{node_name}.qdrant的 gRPC 主机名拼接逻辑localhost与127.0.0.1则保证从宿主机以 HTTPS 访问映射端口时证书校验可通过。这也解释了一个易踩的坑若修改了 compose 中节点 hostname或把集群节点数从 2 扩展到 3必须同步更新[alt_names]再重签证书否则对端证书校验会因 SAN 不匹配而失败。3.3 第二步替换旧证书脚本生成的cacert.pem、cert.pem、key.pem位于 tests/e2e_tests/test_data/cert将它们覆盖到 tests/e2e_tests/test_data/cert/ 目录即可注意脚本以仓库根为相对基准运行实际会先在仓库根生成cacert.pem、key.pem、cakey.pem、cert.csr、cert.pem等临时产物替换时应只拷贝三个目标 pem 文件避免把中间产物混入版本库。替换后可运行 TLS 相关用例自检例如# 在 tests/e2e_tests 目录下运行需要 Docker 守护进程 python -m pytest test_tls.py -v四、数据兼容性测试为“旧数据可读”兜底4.1 动机与机制主文档明确指出该测试的动机为了快速发现存储兼容性回归检查当前代码能否理解来自上一个稳定版的存储格式。向量数据库的存储演进段结构、payload 索引、量化格式等必须保证升级路径不被破坏于是仓库采用“参考数据 版本矩阵”的策略不把大体积二进制归档进 git而是推送到对象存储README 中给出 GCP bucketqdrant-backward-compatibilityCI 按版本矩阵下载对应归档分别做「目录级 storage」与「快照级 snapshot」两类兼容验证。版本矩阵与验证逻辑集中在 tests/e2e_tests/test_data_compatibility.py。当前矩阵包含最近的主线版本如v1.16.0~v1.18.1针对每个版本通过https://storage.googleapis.com/qdrant-backward-compatibility/compatibility-{version}.tar下载归档解出storage.tar.bz2storage 目录归档与full-snapshot.snapshot.gz快照归档Storage 子测试将storage目录以读写方式挂载为容器内/qdrant/storage直接启动新版本 QdrantSnapshot 子测试把快照文件挂载为/qdrant/snapshot.snapshot以./qdrant --storage-snapshot /qdrant/snapshot.snapshot启动恢复流程两种场景都先断言 12 个EXPECTED_COLLECTIONS全部出现且状态为ok再对每个集合执行稠密 / 稀疏 / 多向量搜索与覆盖各 payload 索引类型的 scroll 过滤查询确认数据真正可读、可查。也就是说兼容性不是“能启动就算过”而是要求旧格式下的数据在新版本里能完成真实检索。测试通过pytest-subtests在同一下载上并行跑两个子测试并对每个用例打上xdist_group(compatibility)标记以便并行隔离。4.2 兼容归档里装了什么从生成脚本与消费方测试可还原归档内部结构compatibility-version.tar ├── storage.tar.bz2 # 仓库根 storage/ 目录的压缩归档 └── full-snapshot.snapshot.gz # 通过 snapshots API 生成的全量快照其中storage.tar.bz2解压后是标准的storage/目录树测试正是把它整体挂进新版本容器的/qdrant/storage快照则用于验证--storage-snapshot恢复路径该启动参数在 test_data_compatibility.py 与 src/startup.rs 均有对应使用。当前仓库test_data目录中保留了storage.tar.xz一份存量数据而 CI 矩阵的归档均需从 GCP 获取因此本地验证前需要外网可访问该 bucket。五、重新生成存储兼容性数据存储格式一旦演进例如段文件、索引或量化元数据的持久化布局变化就必须按主文档流程刷新参考数据。5.1 执行生成脚本主文档给出三个步骤核心是运行 tests/e2e_tests/test_data/compatibility/gen_storage_compat_data.sh# 步骤 1在仓库根目录执行 bash tests/e2e_tests/test_data/compatibility/gen_storage_compat_data.sh # 步骤 2按提示输入生成数据的 Qdrant 版本号例如 v1.18.1 # 步骤 3把生成的 compatibility-version.tar 推送到 GCP bucket # 无凭证时需向维护者申请脚本通过环境变量提供高级控制缺省时走交互式询问环境变量默认值含义USE_DOCKER1为1时用qdrant/qdrant:$QDRANT_VERSION官方镜像生成数据为0时本地cargo build后用./target/debug/qdrantQDRANT_VERSION空交互询问用于生成数据的版本号最终写进归档文件名与提示信息5.2 脚本流水线拆解逐段解析脚本能清晰看出“参考数据为什么可信”准备阶段将QDRANT_HOST固定为localhost:6333容器模式下先用debian:12-slim清空./storage再以--networkhost启动qdrant/qdrant:$QDRANT_VERSION并把宿主./storage映射进容器/qdrant/storage。脚本还注册了trap teardown EXIT保证无论成功失败都会在退出时 kill 服务容器/进程。就绪探测循环调用curl ... /collections最多等待约 30 秒直至服务可用否则以退出码 2 失败——避免服务未就绪时就开始灌数据。灌数据调用 tests/e2e_tests/test_data/compatibility/populate_db.py。该脚本是数据多样性的核心保证见下一小节。生成并下载快照先POST /snapshots创建全量快照并用jq解析出快照名再GET /snapshots/$SNAPSHOT_NAME下载为full-snapshot.snapshot随后gzip压缩。归档 storage 目录sudo chown -R $(whoami) ./storage规避权限问题后以tar -cjvf把整个storage/打成storage.tar.bz2。打包外层归档将storage.tar.bz2与full-snapshot.snapshot.gz再封进compatibility-${QDRANT_VERSION}.tar并提示上传到qdrant-backward-compatibilitybucket。由此生成的每个版本归档恰好与 test_data_compatibility.py 期望解出的两个内部产物一一对应形成「生成方-消费方」的自洽闭环。5.3 populate_db.py参考数据为何“全面”为使兼容性验证覆盖真实世界的存储形态灌数据脚本刻意构造了高多样性的数据集这是理解“为什么兼容归档体积大、但值得”的关键。核心策略包括向量维度多样化稠密向量 256 维、多稠密向量 128 维含multivector_config、稀疏向量 1000 维密度 0.1三类向量同存单稠密、多稠密multi-image、稀疏text以及三者混合的点随机分布点 ID 混用整数与 UUID前一半点用整数 id后一半用uuid1payload 字段与索引类型全覆盖keyword_field、count_field、float_field、integer_field含lookup/range索引、boolean_field、geo_field、text_fieldword 分词、uuid_field、datetime_field且各字段约半数点为单值、半数点为多值——这与测试端「按字段类型逐一执行 scroll 过滤」的断言表严格对应多存储形态集合矩阵入口处main依次创建 12 个命名集合覆盖内存向量、on_disk向量、memmap_threshold阈值触发、标量 int8 / 乘积 x64/x32/x16/x8 / 二进制量化、mmap 字段索引、uint8与float16向量类型等组合且把indexing_threshold_kb压低以强制生成 HNSW 索引。正因为集合矩阵与 payload 矩阵互相交叉一个版本归档就能同时检验“向量存储/索引格式”“payload 索引格式”“量化配置持久化”三条兼容性主线——这与消费端EXPECTED_COLLECTIONS的 12 个集合名逐一对应。六、何时需要重新生成——触发条件与注意事项结合前述机制可以把主文档的“流程”落地为清晰的触发条件清单TLS 证书重签时机私钥泄露或证书过期默认 10 年但 CI 模板与集群生命周期常短于证书周期谨慎起见可随安全策略轮换集群拓扑变化节点数量/主机名/域名调整时必须同步更新 cert.cfg 的[alt_names]后重签重签后注意把三个*.pem放入 tests/e2e_tests/test_data/cert/确保 tls_config.yaml 引用的路径与挂载点依旧吻合。兼容性数据再生成时机任何会改变磁盘持久化格式的改动落地后例如段文件结构、HNSW 索引布局、payload 索引序列化、量化标量/乘积/二进制持久化、稀疏向量索引等。一个务实的判断方法是改动发生在 lib/segment、lib/collection、lib/quantization 等存储相关 crate并在代码评审中出现过“旧版本是否还能读”的疑问时就该刷新参考数据生成时务必回答正确的版本号新归档通常应基于“上一个已发布稳定版”生成使 CI 矩阵总能覆盖「旧格式 → 新代码」的方向若向前追加多个版本则相应扩展 test_data_compatibility.py 中的VERSIONS列表归档生成后需上传到qdrant-backward-compatibilitybucket需维护者授予的 GCS 凭证CI 才能下载到新数据。七、小结与自检清单从仓库证据看两套维护流程互为表里TLS 测试依赖「受控 PKI」模拟真实加密部署兼容性测试依赖「冻结的旧版本数据」守护存储演进安全。日常贡献可遵循如下检查单修改了集群拓扑/主机名 → 检查 cert.cfg SAN → 运行 gen.sh → 替换 cert 下三个 pem修改了持久化存储格式 → 用合适版本运行 gen_storage_compat_data.sh → 上传compatibility-version.tar到 bucket → 必要时扩展VERSIONS与EXPECTED_COLLECTIONS本地验证TLS 场景运行 test_tls.py兼容性场景运行 test_data_compatibility.py并确保 Docker 环境与 GCP bucket 可达。主文档给出的全部操作步骤均已在上文展开并补充了参数、原理与触发条件据此即可独立完成 Qdrant 仓库中这两类“再生成”维护任务。【免费下载链接】qdrantQdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/项目地址: https://gitcode.com/GitHub_Trending/qd/qdrant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →