Platform Engineering 平台工程:IDP 内部开发者门户从 0 到 1 建设实战
2024 年初我们团队开始推行 Platform Engineering,目标只有一个:让开发者不需要找运维就能完成部署。半年后回头看,做对了三件事,踩了五个坑。这篇把过程和教训都摊开讲。
核心理念:平台是产品,不是工具
平台工程最核心的思维转变是:把平台当作产品来建设,把开发者当作用户来服务。
传统模式:开发者提需求 → 运维建环境 → 开发者部署 → 出问题找运维。全程人工、慢、易出错。
平台工程模式:开发者自己通过自助平台完成全部流程,运维只做平台能力的开发和迭代。
开发者视角 运维视角
─────────────────────────────────────────────
我要部署一个服务 我要提供部署能力
↓ ↓
打开 IDP 选择 golden path 设计并维护 golden path
填写必要参数 参数校验 + 模板渲染
提交 自动化构建 + 部署
等通知(5 分钟) 等待平台反馈
(无需人工介入)
关键指标:平台成功的标准不是"建了多少功能",而是"开发者完成一次标准部署需要多少步、多长时间"。我们的目标是从 3 天(提工单 → 等审批 → 手动部署)降到 5 分钟(自助选择 → 自动部署)。
架构设计:三层模型
┌─────────────────────────────────────────────┐
│ Developer Experience Layer │
│ IDP (Backstage) + CLI + Web UI │
├─────────────────────────────────────────────┤
│ Platform Capability Layer │
│ CI/CD Pipeline + GitOps + Secret Mgmt │
├─────────────────────────────────────────────┐
│ Infrastructure Layer │
│ Kubernetes + DNS + Certificate + Registry │
└─────────────────────────────────────────────┘
每一层的职责: - DevEx 层:统一的入口,开发者在这里感知到平台的存在 - 能力层:把基础设施能力封装成可复用的组件(CI/CD 模板、证书自动签发、DNS 自动配置) - 基础设施层:现有的 K8s 集群、CI/CD 系统、镜像仓库等
Golden Path 设计:三步走
Golden Path 是平台给开发者的"最简成功路径"——开发者不需要思考,照做就能部署。
第一步:服务模板
# template/service-template.yaml
apiVersion: backstage.io/v1alpha1
kind: Template
metadata:
name: create-service
description: 创建一个标准微服务
spec:
parameters:
- id: serviceName
title: 服务名称
description: 小写字母+数字,不含连字符
type: string
ui:validateField: /^[a-z0-9-]+$/
- id: port
title: 端口
default: 8080
type: number
- id: replicas
title: 副本数
default: 2
type: number
- id: runtime
title: 运行时
type: string
enum: [go, python, java, node]
default: go
steps:
- id: render
name: 渲染模板
action: render:tmpl:v1
input:
url: ./template/service
values:
serviceName: ${{ parameters.serviceName }}
port: ${{ parameters.port }}
- id: push
name: 推送代码
action: github:create-pull-request:v4
input:
repo: myorg/${{ parameters.serviceName }}
branch: platform/new-service
第二步:基础设施即代码
# infrastructure/k8s-base.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ${{ parameters.serviceName }}
spec:
destination:
namespace: apps
server: https://kubernetes.default.svc
source:
path: deployments/${{ parameters.serviceName }}
repoURL: [email protected]:myorg/platform-infrastructure.git
targetRevision: main
syncPolicy:
automated:
prune: true
selfHeal: true
踩坑:一开始我们用 Helm chart 做模板,结果每个团队都要学 Helm 语法。改成纯 YAML 模板 + 变量渲染后,学习曲线几乎归零。这个决策是团队投票的结果——大部分开发者不愿意学 Helm。
第三步:自动 DNS 和证书
# 部署成功后自动执行
# 1. DNS 自动注册(通过 ExternalDNS)
# 2. TLS 证书自动签发(通过 cert-manager)
# 3. 服务发现自动注入(通过 K8s Service)
# 开发者只需要:curl https://${serviceName}.example.com
# 不需要:申请 DNS、申请证书、配置 Ingress
Backstage 搭建:最小可用版本
# app-config.yaml
app:
title: Internal Developer Portal
baseUrl: https://idp.example.com
backend:
auth:
providers:
oauth2:
clientId: ${IDP_OAUTH_CLIENT_ID}
clientSecret: ${IDP_OAUTH_CLIENT_SECRET}
authorizationUrl: https://oauth.example.com/authorize
tokenUrl: https://oauth.example.com/token
catalog:
locations:
- type: url
target: https://github.com/myorg/catalog/blob/main/entities.yaml
integrations:
github:
- host: github.com
token: ${GITHUB_TOKEN}
# entities.yaml
---
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: user-service
annotations:
github.com/project-slug: myorg/user-service
backstage.io/techdocs-ref: dir:.
spec:
type: service
lifecycle: production
owner: platform-team
---
apiVersion: backstage.io/v1alpha1
kind: System
metadata:
name: user-platform
spec:
owner: platform-team
关键决策:Catalog 用 GitHub 托管(不用数据库),Entity 定义用 YAML(不用 JSON Schema)。这降低了维护成本,但牺牲了强类型校验——早期出现过不少 entity 格式错误,靠 GitHub PR review 解决了。
失败复盘:我们曾经搞砸过的地方
失败一:功能做了一堆,开发者不用
2024 年 Q1 我们花了两个月做了"服务迁移助手"——把老系统的服务迁移到新平台。功能齐全,文档完善,结果只有 2 个团队用了,剩下 15 个团队原地不动。
根因:我们站在运维视角想功能,而不是开发者视角。开发者真正需要的是:少改代码、少改配置、少开会。迁移助手解决的"运维的痛点"不是"开发者的痛点"。
修正:砍掉迁移助手,转而做"一键创建服务"——开发者想要的就是"别让我写部署配置"。
失败二:权限系统太复杂
原方案:RBAC + ABAC + 自定义 Policy Engine,三层权限控制。
# 权限策略(过于复杂)
apiVersion: iam.example.com/v1
kind: AccessPolicy
spec:
subjects:
- kind: Team
name: user-service-team
resources:
- kind: Deployment
name: user-service-*
permissions:
- get
- list
- create
- update
- delete
conditions:
- key: env
op: in
values: [staging, production]
- key: time
op: between
values: ["09:00", "18:00"]
结果:开发者看不懂自己的权限,运维维护政策维护到崩溃。
修正:砍掉条件判断,简化为"按团队 + 环境"两层模型:
- team-A → staging 全权限,production 只读
- team-B → staging + production 全权限(因为他们有 SRE oncall)
简单了很多,虽然不够细粒度,但可维护性大幅提升。
失败三:SLO 只监控平台,不监控开发者体验
我们最初定义了平台的 SLO: - API 可用性 99.9% - 部署成功率 99.5%
但开发者抱怨的还是多——因为部署成功率 99.5% 意味着每 200 次部署有 1 次失败,而失败的那次往往是最紧急的生产事故。
修正:加了"首次部署时间"和"部署后首次 P0 事故率"两个指标。这才真正反映了开发者体验。
度量:怎么判断平台做得好不好
| 指标 | 目标 | 采集方式 |
|---|---|---|
| 首次部署时间(从代码提交到线上) | <10 分钟 | CI/CD pipeline 日志 |
| 自助部署占比 | >80% | IDP audit log |
| 平均等待时间(提工单 → 完成) | <1 小时 | 工单系统统计 |
| 开发者满意度(季度调查) | >4/5 | 问卷 |
| 平台功能使用率 | >60% | 平台埋点 |
我的判断:最重要的指标是"自助部署占比"。如果这个数字低于 50%,说明平台还没有真正解决问题,还需要继续迭代。
FAQ
Q:平台工程适合什么规模的团队?
阈值:团队超过 10 个、服务超过 20 个时,Platform Engineering 开始显现价值。少于这个规模,人工流程足够高效,建平台的 ROI 为负。我们团队 8 个人、5 个服务时试过,花了一个月搭建,结果没人用——直接砍了。
Q:平台团队和开发团队的关系怎么处理?
这是个组织问题,不是技术问题。最佳实践:平台团队是开发者的一部分,不是独立部门。每个平台功能都由"平台工程师 + 1-2 个开发者"组成 feature team 来开发,这样既懂平台又懂业务,做出来的东西才有人用。
Q:自建平台 vs 用 Backstage vs 买 SaaS?
- 自建:适合有特殊合规要求(金融、政务)或深度定制需求的团队
- Backstage:适合大多数中型团队,社区活跃、插件丰富
- SaaS(如 Harness、CloudBees):适合不想维护平台本身的团队,但价格昂贵且锁定风险高
我们的建议:先从 Backstage 起步,遇到问题再决定是自研还是购买。