用 GKE 和 GitHub Actions 搭建 PR 预览环境

本文介绍如何利用 GKE、GitHub Actions 和 Ingress 为每个 Pull Request 自动创建隔离的预览环境,实现按需部署、自动清理和 TLS 证书签发,解决共享测试环境混乱的问题。
为什么需要 PR 级预览环境
每个软件团队都会经历同一个困境:共享测试环境最终会变得不可用。一个人部署了半成品功能,另一个人又覆盖部署,第三个人跑了数据库迁移。到周四下午,没人能说清当前跑的是哪个分支的哪个版本,"在测试环境上能跑"这句话已经毫无意义。
常见的权宜之计包括:用 Slack 频道"预约"测试环境、轮转部署排期,或者再加一个测试环境——但每个新环境都离生产配置越来越远。平台团队在 Vercel、Netlify、Shopify 等公司已经确立了一个更好的模式:给每个 Pull Request 一个独立环境。
整体架构概览
最终系统的工作流程如下:
- 打开 PR → GitHub Actions 自动触发,构建针对该 PR 打标签的容器镜像
- 推送镜像 → 镜像推送到 Google Artifact Registry
- 创建命名空间 → 在 GKE 集群中创建专用命名空间(如
pr-42、pr-43),并预先设置资源配额 - 部署应用 → 应用完全隔离地部署在该命名空间中
- 路由与 TLS → 共享 Ingress 控制器将
pr-42.preview.yourdomain.com路由到对应命名空间,自动签发有效 TLS 证书 - 通知评审者 → 机器人在 PR 中评论实时预览 URL,每次 push 后更新同一条评论
- 自动清理 → PR 合并或关闭时删除命名空间;定时任务兜底清理残留环境
三个关键设计决策
1. 无服务账号密钥:使用 Workload Identity Federation
GitHub Actions 通过 Workload Identity Federation 认证到 Google Cloud,使用短期 OIDC 令牌并验证仓库声明。服务账号 JSON 密钥存放在 GitHub Secrets 中是 CI/CD 管道中最常见的安全问题之一——用这个方案可以完全避免。
2. 一个负载均衡器,而非每个 PR 一个
采用单个共享 Ingress 控制器按主机名路由所有环境,一条通配符 DNS 记录覆盖所有可能的域名。朴素方案会为每个环境创建云负载均衡器,成本会迅速攀升。
3. 假设清理会失败的兜底机制
PR 关闭时触发拆除流程,但定时清理任务会额外删除 PR 已不存在或超过最大存活时间的命名空间。即使自动化清理有 95% 的成功率,残留资源也会体现在账单上。
对谁有价值
- 平台工程团队:可以直接复用这套架构搭建内部开发者平台
- 中小团队:用通配符 DNS + 共享 Ingress 的方案避免了按环境创建负载均衡器的成本
- 安全敏感场景:Workload Identity Federation 消除了长期密钥泄露风险
- 使用 Terraform 的团队:所有基础设施即代码,便于审计和回滚
实践要点
- 资源配额要在部署前设置,防止单个 PR 耗尽集群资源
- 机器人评论要更新同一条而非追加新评论,避免 PR 评论区被刷爆
- 定时清理任务建议每 15-30 分钟运行一次,兼顾及时性与 API 调用成本
- 通配符 DNS 记录指向共享 Ingress 的外部 IP,新增环境无需额外 DNS 配置






本文目录(8 节)
本文基于 freeCodeCamp 的公开内容,由 AI 辅助整理改写后发布。
原标题:How to Build Ephemeral PR Preview Environments on GKE with GitHub Actions, Ingress, and Automatic TLS
阅读原文