Backstage完全指南:从入门到服务接入实战
在现代微服务架构中,一个典型的企业可能有数百甚至上千个服务。开发者每天都在问:这个API文档在哪?这个服务谁负责?部署到哪个环境了?Backstage就是为解决这些问题而生的开发者门户平台。
一、Backstage是什么?
Backstage是Spotify开源的开发者门户平台,2020年捐赠给CNCF,现已毕业为CNCF孵化项目。它提供了一个统一的入口,让开发团队能够:

▲ Backstage 主界面 - 软件目录首页
- 管理所有服务和软件目录 - 统一查看所有微服务的状态、文档和依赖关系
- 统一访问文档、API定义和依赖关系 - 不再需要在多个系统间切换
- 标准化开发流程和工具链 - 通过模板快速创建新项目
- 创建服务模板,加速新项目启动 - 预定义的项目骨架和CI/CD配置
1.1 为什么需要Backstage?
在没有统一门户之前,开发团队面临的问题:
| 痛点 | Backstage解决方案 |
|---|---|
| 服务文档分散在Confluence、Git README、Notion等 | 统一的技术文档入口 |
| 不知道某个服务是谁负责的 | 每个服务都有明确的owner字段 |
| 不知道服务部署到哪个环境 | Kubernetes插件显示部署状态 |
| CI/CD状态需要去Jenkins/GitHub Actions查看 | 集成CI状态显示 |
| 新项目创建没有标准流程 | 服务模板标准化创建流程 |
二、核心概念详解
2.1 软件目录(Software Catalog)
软件目录是Backstage的核心,它使用实体(Entity)的概念来描述所有软件组件。每个实体都有一个YAML文件来定义其元数据。

▲ 软件目录界面 - 可以按类型、生命周期、所有者筛选组件
实体类型说明
| 实体类型 | 说明 | 示例 |
|---|---|---|
| Component | 软件组件,最常用的类型 | 微服务、库、网站、API |
| API | API定义 | OpenAPI、GraphQL、gRPC定义 |
| Resource | 基础设施资源 | 数据库、S3存储桶、Redis集群 |
| System | 由多个组件组成的系统 | 支付系统(包含多个微服务) |
| Domain | 业务领域 | 电商领域、支付领域 |
| User/Group | 用户和组织 | 开发团队、负责人 |
2.2 catalog-info.yaml 文件详解
每个服务需要在代码仓库根目录放置一个 catalog-info.yaml 文件。这是接入Backstage的关键文件。
文件位置要求
- 推荐位置:代码仓库根目录
/catalog-info.yaml - 备选位置:
/.backstage/catalog-info.yaml或/backstage/catalog-info.yaml - 注意:文件必须在默认分支(通常是main或master)上
最简示例
# 最简单的 catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-service
description: 我的服务
spec:
type: service
lifecycle: experimental
owner: my-team
三、服务接入方式详解
将服务接入Backstage有两种主要方式,下面详细对比:
3.1 方式一:命令行接入(推荐)
这是最常用的方式,适合批量注册和CI/CD集成。
步骤1:安装Backstage CLI
# 方式一:全局安装(需要Node.js环境)
npm install -g @backstage/cli
# 方式二:使用npx(推荐,无需全局安装)
npx @backstage/cli --help
# 验证安装成功
npx @backstage/cli --version
# 输出: 0.x.x
步骤2:创建 catalog-info.yaml
方法A:手动创建文件
# 在项目根目录创建文件
cd /path/to/your/project
touch catalog-info.yaml
# 使用编辑器打开
vim catalog-info.yaml
# 或
code catalog-info.yaml
方法B:使用命令生成
# 使用heredoc语法创建
cat > catalog-info.yaml << 'EOF'
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: my-service
description: 我的服务描述
annotations:
backstage.io/techdocs-ref: dir:.
github.com/project-slug: myorg/my-service
spec:
type: service
lifecycle: experimental
owner: my-team
EOF
# 验证文件创建成功
cat catalog-info.yaml
步骤3:验证YAML格式
# 使用 Backstage CLI 验证
npx @backstage/cli catalog-info validate catalog-info.yaml
# 成功输出示例:
# ✓ Valid YAML format
# ✓ Required fields present
# ✓ Entity kind is valid
# 失败输出示例:
# ✗ Error: Missing required field "name" in metadata
# ✗ Error: Invalid lifecycle value, must be one of: experimental, production, deprecated
步骤4:提交到Git仓库
# 添加文件到Git
git add catalog-info.yaml
# 提交更改
git commit -m "Add Backstage catalog info for my-service"
# 推送到远程仓库
git push origin main
# 验证提交成功
git log --oneline -1
# 输出: abc1234 Add Backstage catalog info for my-service
步骤5:配置Backstage自动发现
在Backstage的配置文件中添加Git集成,让它自动发现新服务:
# 在 app-config.yaml 中添加
catalog:
locations:
# 方式一:组织级别的catalog文件
- type: url
target: https://github.com/myorg/backstage-catalog/blob/main/catalog-info.yaml
# 方式二:单个仓库的catalog文件
- type: url
target: https://github.com/myorg/my-service/blob/main/catalog-info.yaml
# 方式三:使用GitHub集成自动发现(推荐)
- type: github-discovery
target: https://github.com/myorg
rules:
- allow: [Component, System, API, Resource, Location]
3.2 方式二:界面操作接入
适合快速体验或手动注册少量服务。
步骤1:登录Backstage
- 打开浏览器,访问你的Backstage实例URL(如
https://backstage.example.com) - 使用SSO(如GitHub、Google)或用户名密码登录
- 登录成功后会看到Backstage首页
步骤2:进入注册页面
详细操作步骤:
- 点击页面右上角的 "Create" 按钮
- 在下拉菜单中选择 "Register Existing Component"
- 在输入框中粘贴你的catalog-info.yaml文件的URL:
- GitHub格式:
https://github.com/组织名/仓库名/blob/main/catalog-info.yaml - GitLab格式:
https://gitlab.com/组织名/仓库名/-/blob/main/catalog-info.yaml
- GitHub格式:
- 点击 "Import" 挽钮
- 预览实体信息,确认无误后点击 "Save"
四、catalog-info.yaml 完整字段详解
这是接入Backstage最关键的文件,下面详细解释每个字段的含义和用法:
# ===========================================
# API版本和实体类型
# ===========================================
apiVersion: backstage.io/v1alpha1 # 固定值,目前只有v1alpha1版本
kind: Component # 实体类型:Component/API/Resource/System/Domain/Location
# ===========================================
# 元数据(必填部分)
# ===========================================
metadata:
# === 必填字段 ===
name: payment-service # 唯一标识符,只能包含小写字母、数字和连字符
description: 支付处理服务 # 简短描述,显示在目录列表中
# === 推荐字段 ===
namespace: default # 命名空间,用于分组,默认是default
title: 支付服务 # 显示名称,可以使用中文
labels:
tier: backend # 标签,用于分类和筛选
tags:
- java # 技术栈标签
- spring-boot
- payment
# === 注解(连接外部系统)===
annotations:
# 文档位置(TechDocs插件)
backstage.io/techdocs-ref: dir:.
# Git仓库(GitHub插件)
github.com/project-slug: myorg/payment-service
# GitLab仓库
gitlab.com/project-slug: myorg/payment-service
# CI/CD集成
circleci.com/project-slug: github/myorg/payment-service
jenkins.io/job-full-name: myorg/payment-service
# Kubernetes部署
backstage.io/kubernetes-id: payment-service
backstage.io/kubernetes-namespace: production
# 监控集成
datadoghq.com/dashboard-url: https://app.datadoghq.com/dashboard/xxx
grafana/dashboard-selector: app=payment-service
# 告警集成
pagerduty.com/service-id: PXXXXXX
# 错误追踪
sentry.io/project-slug: myorg/payment-service
# ===========================================
# 规格说明
# ===========================================
spec:
# === 必填字段 ===
type: service # 组件类型
lifecycle: production # 生命周期:experimental/production/deprecated
owner: team-payment # 负责团队(引用Group实体的name)
# === 可选字段 ===
system: payment-system # 所属系统(引用System实体的name)
subcomponentOf: payment-platform # 父组件(引用Component实体的name)
# 提供的API(其他服务可以消费)
providesApis:
- payment-api # 引用API实体的name
- webhook-api
# 依赖的其他组件
dependsOn:
- component:default/database # 格式:component:命名空间/组件名
- resource:default/redis-cache # 格式:resource:命名空间/资源名
- api:default/stripe-api # 格式:api:命名空间/API名
# 消费的API
consumesApis:
- notification-api # 引用API实体的name
五、批量注册服务
对于已有大量服务的组织,手动注册效率太低。以下是批量注册的几种方法:
5.1 使用Python脚本批量生成
创建一个Python脚本来自动生成所有服务的catalog-info.yaml文件:
#!/usr/bin/env python3
"""
批量生成 catalog-info.yaml 文件
使用方法: python3 generate_catalog.py
"""
import os
import yaml
# 定义所有服务的信息
services = [
{
"name": "user-service",
"description": "用户管理服务",
"team": "team-user",
"type": "service",
"lifecycle": "production",
"tags": ["java", "spring-boot"],
"system": "user-system"
},
{
"name": "order-service",
"description": "订单处理服务",
"team": "team-order",
"type": "service",
"lifecycle": "production",
"tags": ["java", "spring-boot"],
"system": "order-system"
},
{
"name": "payment-service",
"description": "支付处理服务",
"team": "team-payment",
"type": "service",
"lifecycle": "production",
"tags": ["java", "spring-boot"],
"system": "payment-system"
},
]
# 为每个服务生成 catalog-info.yaml
for svc in services:
# 构建catalog内容
catalog = {
"apiVersion": "backstage.io/v1alpha1",
"kind": "Component",
"metadata": {
"name": svc["name"],
"description": svc["description"],
"annotations": {
"github.com/project-slug": f"myorg/{svc['name']}"
},
"tags": svc.get("tags", [])
},
"spec": {
"type": svc["type"],
"lifecycle": svc["lifecycle"],
"owner": svc["team"],
"system": svc.get("system", "default")
}
}
# 创建目录
output_dir = f"services/{svc['name']}"
os.makedirs(output_dir, exist_ok=True)
# 写入文件
output_file = os.path.join(output_dir, "catalog-info.yaml")
with open(output_file, "w", encoding="utf-8") as f:
yaml.dump(catalog, f, default_flow_style=False, allow_unicode=True)
print(f"✓ 已生成: {output_file}")
print(f"\n完成! 共生成 {len(services)} 个 catalog-info.yaml 文件")
5.2 配置GitHub自动发现
在Backstage配置中启用GitHub自动发现,自动扫描组织下所有仓库:
# app-config.yaml
catalog:
rules:
- allow: [Component, System, API, Resource, Location]
locations:
# GitHub组织自动发现 - 自动扫描 myorg 组织下所有仓库
- type: github-discovery
target: https://github.com/myorg
rules:
- path: "/catalog-info.yaml"
parser: "yaml"
# GitHub文件发现 - 扫描特定文件
- type: github-file-discovery
target: https://github.com/myorg
rules:
- path: "/catalog-info.yaml"
parser: "yaml"
integrations:
github:
- host: github.com
token: ${GITHUB_TOKEN} # 从环境变量读取Token
5.3 使用脚本从代码仓库提取信息
#!/usr/bin/env python3
"""
从Git仓库自动提取信息生成 catalog-info.yaml
使用方法: python3 extract_from_git.py /path/to/repos
"""
import os
import subprocess
import yaml
from pathlib import Path
def get_git_info(repo_path):
"""从Git仓库提取信息"""
result = {}
# 获取仓库名称
result["name"] = Path(repo_path).name.lower().replace("_", "-")
# 获取远程URL
try:
remote_url = subprocess.check_output(
["git", "-C", repo_path, "remote", "get-url", "origin"],
text=True
).strip()
# 解析GitHub URL
if "github.com" in remote_url:
parts = remote_url.replace(".git", "").split("/")
result["github_org"] = parts[-2]
result["github_repo"] = parts[-1]
except:
result["github_org"] = "unknown"
result["github_repo"] = result["name"]
# 尝试从README或package.json获取描述
readme_path = os.path.join(repo_path, "README.md")
package_json_path = os.path.join(repo_path, "package.json")
if os.path.exists(package_json_path):
with open(package_json_path) as f:
pkg = json.load(f)
result["description"] = pkg.get("description", f"{result['name']} service")
result["language"] = "node" if "engines" not in pkg else "unknown"
elif os.path.exists(readme_path):
with open(readme_path) as f:
first_line = f.readline().strip("# ")
result["description"] = first_line or f"{result['name']} service"
return result
def generate_catalog_yaml(info):
"""生成catalog-info.yaml内容"""
return {
"apiVersion": "backstage.io/v1alpha1",
"kind": "Component",
"metadata": {
"name": info["name"],
"description": info.get("description", f"{info['name']} service"),
"annotations": {
"github.com/project-slug": f"{info.get('github_org', 'myorg')}/{info.get('github_repo', info['name'])}"
}
},
"spec": {
"type": "service",
"lifecycle": "experimental",
"owner": "team-platform"
}
}
# 使用示例
if __name__ == "__main__":
import sys
repo_path = sys.argv[1] if len(sys.argv) > 1 else "."
info = get_git_info(repo_path)
catalog = generate_catalog_yaml(info)
output_path = os.path.join(repo_path, "catalog-info.yaml")
with open(output_path, "w") as f:
yaml.dump(catalog, f, default_flow_style=False)
print(f"✓ 已生成: {output_path}")
六、服务模板(Software Templates)
Backstage的服务模板功能可以标准化新服务的创建流程,包含代码骨架、CI/CD配置等。
6.1 如何使用服务模板

▲ Spring Boot 服务模板示例
在Backstage界面中:
- 点击左侧菜单的 "Create..."
- 选择一个模板(如 "Spring Boot Service")
- 填写表单:
- name: 服务唯一标识符(小写、连字符)
- owner: 选择负责团队
- description: 服务描述
- 点击 "Create"
- 系统会自动:
- 创建Git仓库
- 生成项目骨架代码
- 添加CI/CD配置
- 注册到Backstage目录
6.2 自定义服务模板
创建自定义模板文件 template.yaml:
# template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: my-custom-template
title: 我的自定义服务模板
description: 创建一个标准化的微服务
tags:
- recommended
- microservice
spec:
owner: team-platform
type: service
parameters:
- title: 服务基本信息
required:
- name
- owner
properties:
name:
title: 服务名称
type: string
description: 服务的唯一标识符
pattern: "^[a-z][a-z0-9-]*$"
ui:field: StringField
owner:
title: 负责团队
type: string
description: 选择负责此服务的团队
ui:field: EntityPicker
ui:options:
allowedKinds:
- Group
- title: 技术栈选择
properties:
language:
title: 编程语言
type: string
default: java
enum:
- java
- python
- nodejs
- go
ui:field: Select
framework:
title: 框架
type: string
ui:field: Select
ui:options:
java:
- spring-boot
- quarkus
python:
- fastapi
- django
nodejs:
- express
- nestjs
go:
- gin
- echo
steps:
- id: create-repo
name: Create Repository
action: publish:github:create
input:
repoUrl: "https://github.com/${{ parameters.owner }}/${{ parameters.name }}"
description: ${{ parameters.description }}
- id: register-catalog
name: Register to Catalog
action: catalog:register
input:
catalogInfoUrl: "https://github.com/${{ parameters.owner }}/${{ parameters.name }}/blob/main/catalog-info.yaml"
七、插件集成详解
Backstage的强大之处在于其丰富的插件生态。以下是常用插件的配置方法:
7.1 Kubernetes插件
# app-config.yaml
kubernetes:
serviceLocatorMethod:
type: multiTenant
clusterLocatorMethods:
- type: config
clusters:
- name: production
url: https://k8s-production.example.com
authProvider: serviceAccount
serviceAccountToken: ${K8S_TOKEN}
- name: staging
url: https://k8s-staging.example.com
authProvider: serviceAccount
serviceAccountToken: ${K8S_STAGING_TOKEN}
7.2 GitHub Actions插件
# app-config.yaml
integrations:
github:
- host: github.com
token: ${GITHUB_TOKEN}
# catalog-info.yaml 中添加
annotations:
github.com/project-slug: myorg/my-service
7.3 Jenkins插件
# app-config.yaml
jenkins:
instances:
- name: default
baseUrl: https://jenkins.example.com
username: backstage
apiKey: ${JENKINS_API_TOKEN}
# catalog-info.yaml 中添加
annotations:
jenkins.io/job-full-name: myorg/my-service
7.4 常用插件一览

▲ 搜索平台 - 全局搜索服务和文档

▲ Backstage 插件生态 - 丰富的集成能力
| 插件名称 | 功能 | 配置复杂度 | 必需的Token/凭据 |
|---|---|---|---|
| @backstage/plugin-kubernetes | 显示K8s部署状态 | 中等 | kubeconfig或ServiceAccount Token |
| @backstage/plugin-github-actions | 显示GitHub Actions CI状态 | 低 | GitHub Personal Access Token |
| @backstage/plugin-circleci | 显示CircleCI构建状态 | 低 | CircleCI API Token |
| @backstage/plugin-jenkins | 显示Jenkins任务状态 | 中等 | Jenkins API Token |
| @backstage/plugin-techdocs | 技术文档管理 | 低 | 无 |
| @backstage/plugin-sentry | Sentry错误追踪 | 低 | Sentry Auth Token |
| @backstage/plugin-pagerduty | PagerDuty告警集成 | 低 | PagerDuty API Token |
| @backstage/plugin-datadog | Datadog监控集成 | 中等 | Datadog API Key + App Key |
| @backstage/plugin-grafana | Grafana仪表板集成 | 低 | Grafana API Token |
八、最佳实践
8.1 命名规范
# ✅ 推荐
metadata:
name: payment-service # 小写、连字符分隔
title: 支付服务 # 中文显示名
# ❌ 不推荐
metadata:
name: PaymentService # 驼峰命名
name: payment_service # 下划线
name: PAYMENT-SERVICE # 大写
8.2 层级结构设计
推荐按照业务领域 → 系统 → 服务的层级组织:
8.3 自动化建议
- CI/CD验证:在CI流水线中添加catalog-info.yaml格式验证步骤
- 自动发现:配置GitHub集成自动发现新服务
- 服务模板:使用模板标准化新项目创建
- 定期清理:定期清理已删除仓库的实体
8.4 CI/CD集成示例
# .github/workflows/ci.yml
name: CI
on: [push]
jobs:
validate-catalog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Validate catalog-info.yaml
run: |
npm install -g @backstage/cli
npx @backstage/cli catalog-info validate catalog-info.yaml
- name: Check required fields
run: |
# 确保必填字段存在
if ! grep -q "name:" catalog-info.yaml; then
echo "Error: 'name' field is required"
exit 1
fi
if ! grep -q "owner:" catalog-info.yaml; then
echo "Error: 'owner' field is required"
exit 1
fi
九、常见问题解决
Q1: 如何更新已注册的服务信息?
答案:直接修改仓库中的catalog-info.yaml文件并推送,Backstage会自动同步(默认每10分钟刷新一次)。
# 修改catalog-info.yaml
vim catalog-info.yaml
# 提交更改
git add catalog-info.yaml
git commit -m "Update service metadata"
git push
# 等待约10分钟,或手动刷新
# Backstage会在下一个同步周期自动更新
Q2: 如何删除已注册的服务?
方法一:设置生命周期为deprecated
spec:
lifecycle: deprecated # 标记为已废弃
# ... 其他字段
方法二:删除catalog-info.yaml文件
# 删除文件
git rm catalog-info.yaml
git commit -m "Remove service from catalog"
git push
# 注意:实体会在下一个同步周期被标记为删除
# 如需永久删除,需要在Backstage管理界面手动清理
Q3: 如何处理多环境配置?
使用不同的annotations区分不同环境的部署:
annotations:
# 开发环境
backstage.io/kubernetes-id-dev: my-service-dev
backstage.io/kubernetes-namespace-dev: development
# 测试环境
backstage.io/kubernetes-id-staging: my-service-staging
backstage.io/kubernetes-namespace-staging: staging
# 生产环境
backstage.io/kubernetes-id-prod: my-service-prod
backstage.io/kubernetes-namespace-prod: production
Q4: 服务之间如何建立依赖关系?
# 支付服务依赖用户服务和订单服务
spec:
dependsOn:
- component:default/user-service
- component:default/order-service
- resource:default/redis-cache
# 同时提供API给其他服务使用
providesApis:
- payment-api
Q5: 如何调试catalog-info.yaml问题?
# 1. 验证YAML格式
npx @backstage/cli catalog-info validate catalog-info.yaml
# 2. 查看Backstage日志
kubectl logs -f deployment/backstage -n backstage
# 3. 使用Backstage API查询实体
curl -H "Authorization: Bearer $TOKEN" \
https://backstage.example.com/api/catalog/entities/by-name/component/default/my-service
# 4. 检查实体处理状态
curl -H "Authorization: Bearer $TOKEN" \
https://backstage.example.com/api/catalog/entity-annotations
十、总结
Backstage作为开发者门户,能够有效解决微服务架构下的服务治理问题。通过标准化的catalog-info.yaml文件,团队可以:
- 统一管理所有服务元数据 - 不再需要在多个系统中查找服务信息
- 建立服务间的依赖关系 - 清晰了解服务拓扑
- 集成各类工具和平台 - CI/CD、监控、告警一站式查看
- 标准化开发流程 - 通过模板快速创建新项目
接入Backstage的核心步骤:
- 创建catalog-info.yaml文件(必填字段:name, description, type, lifecycle, owner)
- 验证YAML格式正确
- 提交到Git仓库
- 配置Backstage自动发现或手动注册
- 添加annotations集成外部系统
建议从简单开始,逐步添加更多元数据和集成。先让服务出现在目录中,再逐步完善依赖关系、文档链接、CI/CD集成等。
参考资料
📜 版权声明
本文作者:王梓 | 原文链接:https://www.bthlt.com/note/369551265-TegBackstage完全指南:从入门到服务接入实战
出处:葫芦的运维日志 | 转载请注明出处并保留原文链接


📜 留言板
留言提交后需管理员审核通过才会显示