平台工程: 用Backstage构建开发者门户 - 1

本文介绍了如何使用开源Backstage构建自己的开发者门户,并基于此实践平台工程。本系列共两篇文章,这是第一篇。原文: Platform Engineering: Building Your Developer Portal with Backstage --- Part 1

在上一篇文章(平台工程与安全)中,我们介绍了什么是平台工程,为何如此重要,和DevOps做了比较,以及介绍了平台工程如何帮助提高安全性。

今天我们来动手从头开始构建一个开发者门户。

1. 当我们谈论开发者门户时,我们在谈论什么

由于平台工程都是自助服务的,内部开发者门户在新范式中至关重要,在该范式中实现了所有自助服务功能和集成。

考虑到开发者门户的重要性,在构建之前,需要弄清楚我们对它的期望到底是什么。通常,为了最大限度利用平台工程,开发者门户将包含一些关键功能,例如:

  • 服务目录: 让开发人员可以鸟瞰所有项目、服务、部署状态、文档、所有权,甚至是值班计划和事件等;
  • 某种资源库脚手架/项目生成工具: 例如 Cookiecutter 这样的工具,能让开发人员从门户网站直接启动新服务;
  • 定制: 也许你希望将使用的任何工具链集成到开发者门户中,使其成为真正统一的一站式体验,可能的集成包括 Kubernetes、CI/CD 状态、值班计划、事件管理系统、secrets管理器等。

此时,门户网站可以处理一切事务,如获取服务信息、待命计划、触发事件、部署工作以及处理事件管理。有了这些功能,开发人员就能获得真正统一的体验,在一个地方创建服务,随后跟踪和操作/维护这些服务,最大限度的发挥开发者门户的潜力。

2. 选择工具:Backstage

既然知道了开发者门户网站的真正需求,那就来构建吧。

由于它将具有多种功能,设计/编码部分本身就是一个庞大的项目,不是所有团队都能承担得起。因此需要一个工具来快速构建门户网站,幸运的是,我们已经有了这样的工具--Backstage

Backstage 是用于构建开发者门户网站的开放平台。Backstage 本身并不是开发者门户,而是用于构建开发者门户的工具。想想"create-react-app"和用它创建的实际 react 应用的区别就知道了。开箱即用的 Backstage 包括:

  • 软件目录: 用于管理所有软件,如微服务、库、数据管道、网站和 ML 模型;
  • 软件模板: 用于快速启动新项目,并根据组织的最佳实践对工具进行标准化;
  • 文档: 采用"像编写代码一样编写文档"的方法,轻松创建、维护、查找和使用技术文档;
  • 不断发展的开源插件生态系统,进一步扩展了 Backstage 的可定制性和功能。

Backstage的架构非常灵活: 前端使用 React/TypeScript 编写,后端使用 Node.js,还可以通过添加插件来扩展功能。

更重要的是,Backstage(由 Spotify 创建)现在由云原生计算基金会(CNCF)作为孵化级项目托管,这意味着我们可以获得想要的所有社区支持。它还设有办公时间,可以在每周四参加互动,准确了解开源平台如何提高开发人员的效率和体验。

说得够多了。今天我们将从头开始,自己构建一个开发者门户。完成本教程后,可以使用带有内置安全 CI 工作流的模板来引导一个新服务,检查 CI 状态,并在同一个地方查看该服务的文档。

废话少说,开始吧。

3. 构建门户网站

3.1. 前提条件

不多,可能所有 DevOps 工程师都已经具备:

  • 基于 Unix 的操作系统。例如,可以在 macOS、Linux 或 Windows Subsystem for Linux (WSL) 上运行。
  • curl、git、Docker
  • Node.js, yarn
3.2. 创建门户网站

运行:

bash 复制代码
npx @backstage/create-app@0.5.2-next.3

作者注:

我们之所以使用 backstage/create-app@0.5.2-next.3 而不是 backstage/create-app@latest,是因为我们需要这项功能在 GitHub 中创建secrets,以便在 GitHub Actions 工作流中使用。该功能已经开发完成,但截至目前(2023 年 6 月 18 日),尚未集成到最新版本的 backstage/create-app 中。

如果稍后阅读本文时,最新版本已指向 2023 年 6 月(或更晚)发布的版本,就可以安全的运行 npx @backstage/create-app@latest 而无需指定奇怪的版本。

该命令提供互动模式,只需要输入名称,例如 "my-portal",回车,然后等待应用程序完成。

进入目录并运行:

bash 复制代码
yarn dev

现在应该已经建立并运行了门户网站!就这么简单!现在可以浏览一下,感受一下软件目录、模板、文档和其他东西:

不过目前还没什么用。我们继续配置。

4. GitHub 认证与集成

由于开发者门户将负责引导新仓库,因此需要 GitHub 的操作权限,这也是我们需要进行 GitHub 认证和集成的原因。

4.1. 用于集成的个人访问令牌

虽然使用 GitHub 应用程序可能是设置集成的最佳方式,因为它的权限设置非常精细,但在本教程中,我们将使用个人访问令牌,以便更快开始使用:

  • 打开 GitHub 令牌创建页面,创建个人访问令牌。
  • 使用一个名称来标识此令牌,并将其写入备注栏,选择过期天数。
  • 如果很难选择特定数字,建议选择 7 天,这是一个幸运数字:)。(我们将只在本地进行测试,不会在生产环境中运行)。
  • 在本教程中,我们先将范围设置为最大,这样就不会因为纠结于 GitHub 权限而影响体验。不过请注意,千万不要在生产环境中这样做!

然后,将令牌作为环境变量导出:

bash 复制代码
export GITHUB_TOKEN=xxx

app-config.yaml 文件中,将 integrations 部分更改为以下内容:

yaml 复制代码
integrations:
  github:
    - host: github.com
      token: ${GITHUB_TOKEN} # leave it like this, read values from env var
4.2. 创建 GitHub OAuth 应用程序

访问 github.com/settings/ap... 创建 OAuth 应用程序。主页 URL 应指向 Backstage 的前台,在本教程中是 http://localhost:3000。授权回调 URL 将指向授权后台,很可能是 http://localhost:7007/api/auth/github/handler/frame。

然后,再次打开 app-config.yaml 文件,将 auth 部分更新为以下内容,配置身份验证:

yaml 复制代码
auth:
  environment: development
  providers:
    github:
      development:
        clientId: YOUR CLIENT ID # put your values here
        clientSecret: YOUR CLIENT SECRET # put your values here

请注意,将客户端secrets作为硬编码secrets存储在配置文件中有违安全最佳实践,只能用于本地开发。对于生产使用,我们可以按照 12 要素应用规则,从环境变量中读取。

更改配置后,必须停止 yarn dev 服务器并重新运行 yarn dev

5. 创建模板

接下来准备软件模板,用于快速启动一项新服务。

模板应包含以下内容:

  • 服务通用的基本源代码/目录结构
  • 一些文档
  • 测试/构建/部署服务的 CI 工作流

本教程将以我创建的模板 github.com/IronCore864... 为例。

目录结构相对简单,只有两个部分:

  • 一个 skeleton 文件夹
  • 一个 template.yaml 文件
5.1. skeleton 文件夹

skeleton文件夹包含使用此模板创建新服务时将呈现的所有模板,变量的格式为 ${{ values.varName }}

如果你熟悉 Helm、YAML 或 Go 模板(或几乎所有模板工具),你会发现这种格式很容易阅读和理解,而且没有额外开销。

唯一值得一提的是 Backstage 使用的名为 catalog-info.yaml 的文件,该文件必须存在,否则就无法将创建的服务注册为门户中的组件。

如你所见,在模板中已经内置了一些 GitHub Actions 工作流,其中一个将测试拉取请求并推送到主分支,另一个将使用 ggshield 扫描软件仓库中的硬编码secrets。

这样我们就可以将所有的 CI/CD 最佳实践放入模板中,当其他人启动新服务时,就已经拥有了所需的一切,并默认启用了安全功能。

5.2. template.yaml 文件

template.yaml 文件定义了模板在门户界面中的外观和实际操作。

文件很长,乍一看似乎让人不知所措,但一旦仔细阅读,就会发现它非常简单明了:

  • 语法类似于 Kubernetes 的自定义资源;
  • 有两大部分,一部分是参数,另一部分是步骤;
  • 参数定义了使用该模板时所需的输入及其类型;
  • 步骤定义了执行该模板时实际发生的情况,看起来非常像 GitHub 的 Actions 工作流。

参数示例:

yaml 复制代码
parameters:
  - title: Provide some simple information
    required:
      - service_name
      - owner
    properties:
      service_name:
        title: Name
        type: string
        description: Unique name of the service.
        ui:field: EntityNamePicker
      description:
        title: Description
        type: string
        description: Help others understand what this service is for; optional.
      owner:
        title: Owner
        type: string
        description: Owner of the component
        ui:field: OwnerPicker
        ui:options:
          allowedKinds:
            - Group
  ...

步骤示例:

yaml 复制代码
steps:

- id: template
  name: Fetch Skeleton + Template
  action: fetch:template
  input:
  url: ./skeleton
  copyWithoutTemplating: - .github/workflows/\*
  values:
  serviceName: ${{ parameters.service_name }}
  description: ${{ parameters.description }}
  destination: ${{ parameters.repoUrl | parseRepoUrl }}
  owner: ${{ parameters.owner }}
  ...

我们可以从上述文件中推断出它究竟定义了什么:

  • 首先需要输入两个输入参数: 服务名称(service_name)和所有者(owner);
  • 需要选择一个带有额外参数(GITGUARDIAN_API_KEY,用于 CI 流水线)的版本库位置;
  • 然后,它会获取模板、渲染模板、将模板发布到 GitHub 并在我们的门户网站上注册。
5.3. 注册模板

最后,把模板添加到门户目录中,这样其他人就可以使用这个模板了。

目录最直接的配置是声明添加指向 YAML 文件的位置,并进行静态位置配置。位置会添加到 app-config.yaml 文件的 catalog.locations 关键字下的目录中:

yaml 复制代码
catalog:
  locations:
    - type: url
      target: https://github.com/IronCore864/backstage-test-template/blob/main/template.yaml
      rules:
        - allow: [Template]

上述规则允许我们从指定的 URL 添加模板。

记得重启 yarn dev服务器。

6. 把所有东西放在一起

现在,我们已经准备好了一切,是时候一睹魔法的风采了。

访问 http://localhost:3000,点击 "Create" 按钮,选择我们的模板:

输入必要信息。关于 GitGuardian API 密钥,请在此处创建:dashboard.gitguardian.com/api/persona...

一切就绪后,点击 "下一步",神奇的事情就会发生:

现在一切都应该创建好了。

我们可以在目录中查看:

我们还创建并提供了文档:

最后看看 CI 的状态:

流水线似乎已经成功完成,我们可以点击查看更多细节,包括详细步骤和日志。如果你更喜欢在 CI 软件(这里是 GitHub Actions)中查看,可以点击相应链接跳转。

上述示例完整源码可以参考Github仓库

这意味着无论团队使用什么工具链,团队成员都不必记住 10 个不同工具的 10 个不同 URL,也不必一直打开这 10 个标签页。当他们需要某些信息时,只要进入开发者门户,就能获得所有信息,这正是内部开发者门户的强大之处。

7. 小结

在教程的第一部分,我们介绍了开发者门户网站的功能,学习如何使用开源 Backstage 工具创建自己的门户网站,使用 GitHub 配置门户网站,创建软件模板,并从中启动一项服务。

如果集成越来越多,开发者门户的功能可能远不止于此。想象一下,如果你在 Kubernetes 中部署服务,使用 Argo CD 进行 GitOps 部署,使用 HashiCorp Vault 进行secrets管理,而所有都集成在门户中。当你需要检查部署状态时,当你想查看 K8s 中的实际资源时,不必访问 Vault、Argo CD 和 K8s Dashboard。你甚至不必记住它们的 URL,甚至不知道这些东西的存在,因为有一个工具可以统治它们,那就是开发者门户。

本教程仅适用于本地快速启动,在生产中使用时有许多问题需要考虑。例如,我们现在使用的是静态配置,没有什么是持久化的,如果重新启动开发服务器,目录信息就会丢失。为此,我们需要为门户配置 Postgres。再比如,我们使用 "yarn dev"来启动前端和后端,对于生产应用,可能希望将前端和后端分开,将它们作为容器部署在 K8s 中,并为它们创建 Ingress 等。

在本教程的下一部分,我们将了解 Backstage 插件的机制,看看如何将其功能扩展到更高水平。


你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。为了方便大家以后能第一时间看到文章,请朋友们关注公众号"DeepNoMind",并设个星标吧,如果能一键三连(转发、点赞、在看),则能给我带来更多的支持和动力,激励我持续写下去,和大家共同成长进步!

本文由mdnice多平台发布

相关推荐
程序员爱钓鱼1 小时前
Go语言实战案例-创建模型并自动迁移
后端·google·go
javachen__1 小时前
SpringBoot整合P6Spy实现全链路SQL监控
spring boot·后端·sql
uzong6 小时前
技术故障复盘模版
后端
GetcharZp7 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程7 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研7 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi8 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国9 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy9 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack9 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt