2. 服务目录基础:定义、组成要素与治理
服务目录(Service Catalog)是微服务与 DevOps 治理的“数据平面”。它并非简单的服务列表,而是承载了服务元数据、部署拓扑、技术栈归属与负责人信息的权威注册中心。在 Pipeline 设计中,服务目录是触发构建、执行部署策略、控制环境权限的核心数据源。
核心观点:没有服务目录的 Pipeline 是“盲人摸象”;有了服务目录,每一次构建、部署、回滚都能基于准确的元数据做出决策。
2.1 服务目录的定义
服务目录是一个集中式、版本化的元数据仓库,记录每个服务从开发到生产全生命周期所需的属性。它区别于 CMDB(配置管理数据库)之处在于:服务目录更关注“服务”本身的运行态与交付态属性,而非基础设施资源。
| 维度 | 服务目录 | 传统 CMDB |
|---|---|---|
| 核心对象 | 服务(微服务、API、后端应用) | CI(配置项:服务器、网络设备) |
| 生命周期 | 从代码提交到生产部署 | 从采购到报废 |
| Pipeline 关联 | 直接驱动构建、测试、部署策略 | 间接关联,通常用于资产盘点 |
| 变更频率 | 高(每次代码合并都可能更新) | 低(物理设备变更少) |
实践建议:服务目录应存储在 Git 仓库中(如 YAML 文件),与代码库同源,通过 Pull Request 流程变更,确保元数据变更可审计、可回滚。
2.2 服务目录的组成要素
一个标准服务目录条目至少包含以下四大核心要素。缺少任何一项,Pipeline 都无法自动做出正确的部署决策。
2.2.1 服务名称
服务名称是目录的唯一标识符。命名规范直接影响 Pipeline 的自动化能力:
- 全局唯一性:避免与其它服务、配置项冲突。
- 可解析性:名称应能映射到 Git 仓库路径、Docker 镜像名、K8s Service 名称。
- 命名规范示例:
team-name/service-name或domain-context-service。
2.2.2 负责人
负责人字段是“谁对服务负责”的权威来源。在 Pipeline 中,它用于:
- 自动分配 Code Review 审批人。
- 生产部署前发送审批通知。
- 故障告警的 On-Call 路由。
2.2.3 技术栈
技术栈决定了 Pipeline 的构建策略。不同技术栈需要不同的编译环境、依赖管理和测试框架。
| 技术栈 | 构建工具 | 基础镜像 | 缓存策略 |
|---|---|---|---|
| Java 17 + Spring Boot | Maven / Gradle | eclipse-temurin:17-jre | ~/.m2/repository |
| Go 1.21 | Go Modules | golang:1.21-alpine | GOPATH/pkg/mod |
| Node.js 20 | npm / pnpm | node:20-alpine | node_modules/.cache |
| Python 3.12 | pip / poetry | python:3.12-slim | ~/.cache/pip |
2.2.4 部署环境
部署环境字段定义了服务在哪些环境中运行,以及各环境的配置差异。典型环境包括:
- dev:开发自测环境,自动部署最新代码。
- staging:预发布环境,模拟生产配置,执行集成测试。
- prod:生产环境,受严格审批控制,部署频率最低。
2.3 服务目录的维护与治理
服务目录不是一次性产物,需要持续治理。治理的核心目标是:保证目录数据的准确性、及时性和可消费性。
2.3.1 注册与变更流程
服务目录的变更应遵循 GitOps 原则:
- 开发者提交 Pull Request 修改服务目录 YAML 文件。
- CI 自动校验元数据格式(如服务名是否重复、技术栈是否在允许列表中)。
- 负责人或平台团队审核后合并。
- 合并后触发 Webhook,同步到 CI/CD 系统、监控平台、成本中心。
常见陷阱:服务目录与真实运行环境“脱节”。例如,目录中记录的技术栈是 Java 11,但实际已升级到 Java 17。治理流程必须包含周期性自动校验,或强制 Pipeline 在部署时校验目录元数据与实际镜像的一致性。
2.3.2 自动化校验规则
在 Pipeline 中集成服务目录校验,确保元数据始终有效:
# 示例:服务目录校验脚本片段(伪代码)
def validate_service_catalog(service_name):
catalog = load_catalog("service-catalog.yaml")
entry = catalog.get(service_name)
if not entry:
raise Exception(f"服务 {service_name} 未在目录中注册")
if entry.tech_stack not in ALLOWED_STACKS:
raise Exception(f"技术栈 {entry.tech_stack} 不在允许列表中")
if entry.owner not in ACTIVE_TEAMS:
raise Exception(f"负责人 {entry.owner} 不是有效团队")
return entry
2.3.3 治理指标
通过以下指标衡量服务目录的健康度:
| 指标 | 定义 | 目标值 |
|---|---|---|
| 目录覆盖率 | 已注册服务数 / 实际运行服务数 | ≥ 95% |
| 元数据准确率 | 元数据与实际配置一致的服务比例 | ≥ 90% |
| 变更延迟 | 从服务变更到目录更新的平均时间 | < 1 小时 |
| 僵尸服务率 | 超过 30 天无部署记录的服务占比 | < 5% |
治理自动化:建议每周运行一次“目录健康扫描”Pipeline,自动生成治理报告,标记异常条目并通知负责人。将治理融入日常开发流程,而非季度人工盘点。