2. 服务目录基础:定义、组成要素与治理

服务目录(Service Catalog)是微服务与 DevOps 治理的“数据平面”。它并非简单的服务列表,而是承载了服务元数据、部署拓扑、技术栈归属与负责人信息的权威注册中心。在 Pipeline 设计中,服务目录是触发构建、执行部署策略、控制环境权限的核心数据源。

核心观点:没有服务目录的 Pipeline 是“盲人摸象”;有了服务目录,每一次构建、部署、回滚都能基于准确的元数据做出决策。

2.1 服务目录的定义

服务目录是一个集中式、版本化的元数据仓库,记录每个服务从开发到生产全生命周期所需的属性。它区别于 CMDB(配置管理数据库)之处在于:服务目录更关注“服务”本身的运行态与交付态属性,而非基础设施资源。

维度 服务目录 传统 CMDB
核心对象 服务(微服务、API、后端应用) CI(配置项:服务器、网络设备)
生命周期 从代码提交到生产部署 从采购到报废
Pipeline 关联 直接驱动构建、测试、部署策略 间接关联,通常用于资产盘点
变更频率 高(每次代码合并都可能更新) 低(物理设备变更少)
实践建议:服务目录应存储在 Git 仓库中(如 YAML 文件),与代码库同源,通过 Pull Request 流程变更,确保元数据变更可审计、可回滚。

2.2 服务目录的组成要素

一个标准服务目录条目至少包含以下四大核心要素。缺少任何一项,Pipeline 都无法自动做出正确的部署决策。

服务目录核心组成要素 服务目录条目 服务名称 user-service / payment-api 负责人 团队 / 个人 / 值班组 技术栈 Java 17 / Go 1.21 / Node 20 部署环境 dev / staging / prod 要素说明 • 服务名称:全局唯一,通常与 Git 仓库名、K8s Service 名保持一致 • 负责人:明确 On-Call 团队或个人,用于告警路由与审批流 • 技术栈:决定构建镜像的基础镜像、编译参数、依赖缓存策略 • 部署环境:控制部署流水线的环境准入与配置覆盖

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 服务目录的维护与治理

服务目录不是一次性产物,需要持续治理。治理的核心目标是:保证目录数据的准确性、及时性和可消费性。

服务目录治理流程 1. 注册 2. 审核 3. 同步 4. 审计 治理要点 1. 注册:新服务创建时,必须提交服务目录 PR,包含完整元数据。 2. 审核:由平台工程团队或架构师审核元数据合规性。 3. 同步:目录变更自动触发 Pipeline 配置更新(如 CI 变量、K8s 命名空间)。 4. 审计:定期扫描目录与实际运行服务的一致性,标记“僵尸服务”或过期元数据。

2.3.1 注册与变更流程

服务目录的变更应遵循 GitOps 原则:

  1. 开发者提交 Pull Request 修改服务目录 YAML 文件。
  2. CI 自动校验元数据格式(如服务名是否重复、技术栈是否在允许列表中)。
  3. 负责人或平台团队审核后合并。
  4. 合并后触发 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,自动生成治理报告,标记异常条目并通知负责人。将治理融入日常开发流程,而非季度人工盘点。