使用 extends 和 yaml anchors 可大幅减少 gitlab ci 配置重复,适合管理大量微服务;anchors 通过 & 定义、* 引用实现完全一致的配置块复用,如缓存策略、环境变量等。

用 extends 和 YAML anchors(锚点)能大幅减少重复配置,尤其适合管理数十甚至上百个微服务的 GitLab CI 流水线。核心思路是:把通用逻辑抽成可复用的模板,再按需继承或引用,避免每个 .gitlab-ci.yml 写满构建、测试、镜像推送等雷同步骤。
用 anchors 定义可复用的作业片段
anchors 是 YAML 原生语法,配合 &(定义)和 *(引用),适合提取**完全一致**的配置块,比如统一的缓存策略、基础环境变量或 before_script 脚本:
.cache-template: &cache-definition
cache:
key: "$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME"
paths:
- node_modules/
- .m2/repository/
- ~/.gradle/caches/
<p>build:
</p>注意: 是 YAML 合并语法(不是 GitLab 特有),必须确保目标作业未定义同名字段,否则会覆盖;多个 anchor 可叠加使用,但不支持条件分支或动态参数。
用 extends 实现带差异的继承式复用
extends 比 anchor 更灵活,支持跨作业继承 + 局部覆盖,适合微服务间「大同小异」的场景(如 Java 服务用 Maven、Go 服务用 Go mod,但都需镜像构建+安全扫描):
.base-build:
image: alpine:latest
before_script:
- apk add curl jq
variables:
REGISTRY_URL: registry.example.com
tags:
- k8s-runner
<p>java-build:
extends: .base-build
image: maven:3.9-openjdk-17
script:</p>
- mvn clean package -DskipTests artifacts:
- target/*.jar
go-build: extends: .base-build image: golang:1.22 script:
- go build -o app . artifacts:
- app
关键点:extends 支持多级继承(A → B → C),且子作业可精准覆盖父作业任意字段(包括 script、variables、rules 等),还能组合多个 extends(用列表形式)。
组合 anchors + extends 构建分层模板库
真实微服务流水线通常需分层抽象:语言层(Java/Python/Go)、框架层(Spring Boot/FastAPI)、部署层(K8s/Helm)。推荐结构:
- 顶层 anchor 定义全局基础(如日志格式、超时、runner 标签)
- 中间
extends模板按语言/框架分类(如.spring-boot-test、.python-pytest) - 具体服务作业只写差异化部分(如模块路径、端口、Helm chart 名)
示例:一个 Spring Boot 微服务只需 10 行内完成完整流水线:
stages:
- build
- test
- deploy
<p>build:
extends: .spring-boot-build
variables: { MODULE_PATH: "auth-service" }</p><p>test:
extends: .spring-boot-test
variables: { TEST_PROFILE: "ci" }</p><p>deploy:
extends: .k8s-helm-deploy
variables: { CHART_PATH: "charts/auth" }
</p>避坑与提效技巧
- 避免在 anchor 或 extends 模板里硬编码服务名、分支名——改用
$CI_PROJECT_NAME、$CI_DEFAULT_BRANCH等预设变量 - 敏感配置(如密钥)不要塞进模板,通过
variables+ CI/CD 变量或include外部文件注入 - 用
include将模板拆到单独文件(如templates/java.yml),便于跨项目共享和版本管理 - 启用
only: changes或rules配合模板,让不同服务对各自代码变更触发对应阶段(例如只改前端不跑后端测试)
不复杂但容易忽略:GitLab CI 的模板复用本质是 YAML 合并 + 静态解析,所有逻辑都在 pipeline 创建前展开。调试时用 GitLab UI 的「CI Lint」工具验证最终展开效果,比盲猜更可靠。











