Online Boutique 版本发布全流程指南:从语义化版本号到生产部署的自动化实践
【免费下载链接】microservices-demoSample cloud-first application with 10 microservices showcasing Kubernetes, Istio, and gRPC.项目地址: https://gitcode.com/GitHub_Trending/mi/microservices-demo
导读
本文基于 microservices-demo(Online Boutique)官方发布流程文档,完整梳理该项目从选择版本号、构建镜像、生成清单、打包 Helm Chart、打 git 标签、开 PR 评审、写 Release Notes 到更新生产环境的端到端发布链路。读者将掌握两种发布方式(GitHub Actions 的 Manual Release Builder 工作流与本地make-release.sh脚本)、发布产物在仓库中的落盘位置(release/、kustomize/base/、helm-chart/),以及发布后运维生产集群与更新 major tag 的标准操作,并看到每个环节背后脚本的源码级实现细节。
一、发布前准备:版本号与本地工具链
1.1 选择下一个版本号:遵循语义化版本(SemVer)
Online Boutique 的每个正式版本都使用语义化版本号vX.Y.Z,具体选择规则如下:
- 包含重要功能变更:升级 minor 版本号
Y(例如从v0.10.6升到v0.11.0); - 仅修 bug 或常规季度发布:升级 patch 版本号
Z(例如从v0.10.6升到v0.10.7)。
从脚本的强校验逻辑看,版本号格式是被强制约束的。make-release.sh 中有一段显式检查:
if [[ "$TAG" != v* ]]; then fail "\$TAG must start with 'v', e.g. v0.1.0 (got: $TAG)" fi也就是说,TAG环境变量必须以v开头,v0.10.6这样的格式才能通过校验。当前仓库的 Chart.yaml 中appVersion: "v0.10.6"、version: 0.10.6正是这种规范的落地体现:应用版本保留v前缀,Helm Chart 版本则去掉v前缀。
1.2 确保发布工具在 PATH 中
开始发布前,需要确保以下命令可用:
| 命令 | 用途 | 安装说明 |
|---|---|---|
gsed | GNU sed,用于批量替换 YAML 中的镜像 tag | macOS 通过gnu-sedBrew 包安装;Linux 可直接用sed或符号链接 |
gcloud | 构建镜像、推送镜像、连接 GKE 集群 | Google Cloud SDK 自带 |
helm | 打包并推送 Helm Chart | 官方 Helm 客户端 |
其中gsed的可移植性值得注意:make-release-artifacts.sh 中专门做了兼容处理,在 Linux 上把gsed定义为sed的别名函数:
# define gsed as a function on Linux for compatibility [ "$(uname -s)" == "Linux" ] && gsed() { sed "$@" }1.3 认证 gcloud
发布过程中需要向 Google Cloud 推送镜像与 Chart,因此必须提前完成登录与 Docker 仓库认证:
gcloud auth login gcloud auth configure-docker us-central1-docker.pkg.dev第二条命令为us-central1-docker.pkg.dev区域的 Artifact Registry 配置 Docker 凭据,这是后续gcloud builds submit与helm push能够成功的前提。
二、创建发布分支与 PR:推荐走 GitHub Actions 工作流
2.1 触发 Manual Release Builder 工作流
官方推荐的第一种方式是使用仓库内的Manual Release BuilderGitHub Actions 工作流,操作步骤为:
- 打开仓库的Actions标签页;
- 在左侧边栏选择Manual Release Builder工作流;
- 点击Run workflow下拉按钮;
- 填写参数:
- The release version (e.g., v0.3.5):填
vX.Y.Z格式的版本字符串; - The repository prefix for container images:默认
us-central1-docker.pkg.dev/online-boutique-ci/microservices-demo,即镜像最终推送到的 Artifact Registry 仓库地址; - The Google Cloud Project ID for the release CI:默认
online-boutique-ci;
- The release version (e.g., v0.3.5):填
- 点击Run workflow开始执行。
该工作流会自动完成以下五件事:
- 构建并推送所有服务的容器镜像;
- 重新生成 YAML 清单与 Kustomize base;
- 打包并推送 Helm Chart;
- 创建并推送新分支
release/vX.Y.Z与 git tagvX.Y.Z; - 自动打开一个指向
main的 PR,并在 PR 中包含发布检查清单(release checklist)。
2.2 备选方案:本地执行 make-release.sh
如果需要在本地手动执行整个发布流程,在完成上文「1.2」「1.3」的前置准备后,在仓库根目录运行:
# assuming you are inside the root path of the microservices-demo repository export TAG=vX.Y.Z # This is the new version (e.g. `v0.3.5`) export REPO_PREFIX=us-central1-docker.pkg.dev/online-boutique-ci/microservices-demo # This is the Docker repository for tagged images export PROJECT_ID=online-boutique-ci # This is the Google Cloud project for the release CI ./docs/releasing/make-release.sh脚本执行完毕后,前往 GitHub 的分支列表页面手动创建一个指向main的 Pull Request。之后 CI 会触发多轮检查,并将发布内容暂存到一个临时集群上进行验证。PR 被批准且所有检查通过后,即可合并分支;合并时务必在 PR 描述中附上发布草稿(release draft),方便评审者审阅变更内容。合并过程中不要删除 release 分支,也不要删除相关 tag。
make-release.sh 的源码执行顺序
从 make-release.sh 的实现可以看出,整个流程被严格编排为四个阶段(set -euo pipefail保证任何一步失败都会立即中断):
TAG="${TAG:?TAG env variable must be specified}" REPO_PREFIX="${REPO_PREFIX:?REPO_PREFIX env variable must be specified e.g. us-central1-docker.pkg.dev\/online-boutique-ci\/microservices-demo}" PROJECT_ID="${PROJECT_ID:?PROJECT_ID env variable must be specified e.g. online-boutique-ci}"- 三个环境变量缺失时脚本会直接报错退出(
${VAR:?message}语法); - 首先检查工作区是否有未提交的改动(
git status -s非空则拒绝执行),避免把本地脏状态带入发布; - 然后
git checkout main && git pull确保基于最新主干开始发布; - 依次调用:
make-docker-images.sh—— 构建并推送所有镜像;make-release-artifacts.sh—— 生成release/下的清单并更新kustomize/base/;make-helm-chart.sh—— 打包并推送 Helm Chart;- 最后创建
release/${TAG}分支、提交(允许空提交--allow-empty)、打 tag、推送分支与 tag:
git checkout -b "release/${TAG}" git add "${REPO_ROOT}/release/" git add "${REPO_ROOT}/kustomize/base/" git add "${REPO_ROOT}/helm-chart/" git commit --allow-empty -m "Release $TAG" git tag "$TAG" git push --set-upstream origin "release/${TAG}" git push --tags注意git add的三个路径:release/、kustomize/base/、helm-chart/正是本仓库中全部「发布产物」的所在位置,这从侧面印证了这些目录是每次发布时会被自动更新、提交并随 tag 一起发布的内容。
三、发布链路的三个核心脚本拆解
3.1 make-docker-images.sh:遍历 src 目录逐个构建镜像
make-docker-images.sh 负责为每个微服务构建并推送 Docker 镜像,核心逻辑是遍历src/下的每个服务目录:
while IFS= read -d $'\0' -r dir; do svcname="$(basename "${dir}")" builddir="${dir}" #PR 516 moved cartservice build artifacts one level down to src if [ $svcname == "cartservice" ] then builddir="${dir}/src" fi image="${REPO_PREFIX}/$svcname:$TAG" ... done < <(find "${REPO_ROOT}/src" -mindepth 1 -maxdepth 1 -type d -print0)几个值得注意的实现细节:
- 特殊处理 cartservice:由于 cartservice 的构建产物(Dockerfile 等)位于 src/cartservice/src(比其它服务多一层目录),脚本为它单独把
builddir指向${dir}/src; - 使用 Cloud Build 异步构建:通过
gcloud builds submit --async提交构建任务并轮询状态,直到SUCCESS才继续;遇到FAILURE、INTERNAL_ERROR、TIMEOUT、CANCELLED任一状态则中止整个发布; - 追加 sample 镜像 tag:每个镜像在构建完成后,还会通过
gcloud artifacts docker tags add打上一个sample-public-image-${TAG}的额外 tag,供公开示例部署引用。
镜像命名规则统一为<REPO_PREFIX>/<服务名>:<TAG>,例如 release/kubernetes-manifests.yaml 中 frontend 的镜像地址为:
image: us-central1-docker.pkg.dev/online-boutique-ci/microservices-demo/frontend:v0.10.63.2 make-release-artifacts.sh:生成三份发布产物
make-release-artifacts.sh 负责把「开发态」的清单加工成「发布态」的产物,主要产出如下:
产物一:release/kubernetes-manifests.yaml
将 kubernetes-manifests 目录下除kustomization.yaml之外的所有 YAML 拼接(每个文件之间插入---分隔符),然后用gsed正则把每个服务的image:行替换成$REPO_PREFIX/$svcname:$TAG的发布镜像地址。文件开头会写入:
- license 头(来自 docs/releasing/license_header.txt);
- 「Autogenerated. Do not manually edit.」自动生成警告;
# [START gke_release_kubernetes_manifests_microservices_demo]/# [END ...]标记,方便文档工具定位该代码段。
生成的 release/kubernetes-manifests.yaml 是生产部署用的完整清单(当前仓库中约 980 行,包含全部 11 个服务的 Deployment、Service 等资源)。
产物二:release/istio-manifests.yaml
将 kustomize/components/service-mesh-istio 组件目录下的 YAML(同样排除kustomization.yaml)直接拼接生成,供 Istio 服务网格部署场景使用。当前仓库的 release/istio-manifests.yaml 中可以看到 VirtualService、Gateway、HTTPRoute 等 Istio/Gateway API 资源。
产物三:更新 kustomize/base/
把 kubernetes-manifests 下的每个服务 YAML 复制到 kustomize/base,并做同样的镜像 tag 替换。有一个例外:redis.yaml不替换镜像,因为 redis 使用官方redis:alpine镜像,不属于us-central1-docker.pkg.dev/online-boutique-ci/microservices-demo仓库。替换后的 kustomize/base/kustomization.yaml 引用 11 个服务清单,构成可被上层环境直接使用的 Kustomize base。
3.3 make-helm-chart.sh:打包并推送 Helm Chart
make-helm-chart.sh 负责发布 Helm Chart,它会先改写 helm-chart/Chart.yaml 中的两个版本字段,再执行打包与推送:
gsed -i "s/^appVersion:.*/appVersion: \"${TAG}\"/" Chart.yaml gsed -i "s/^version:.*/version: ${TAG:1}/" Chart.yaml helm package . helm push onlineboutique-${TAG:1}.tgz oci://us-docker.pkg.dev/online-boutique-ci/charts rm ./onlineboutique-${TAG:1}.tgz要点说明:
- 版本字段的差异:
appVersion保留v前缀(如"v0.10.6"),而 Chart 的version通过${TAG:1}去掉v(如0.10.6),这正是 Chart.yaml 中appVersion: "v0.10.6"与version: 0.10.6并存的原因; - 推送目标固定:Chart 被
helm push到 OCI 仓库us-docker.pkg.dev/online-boutique-ci/charts(与镜像仓库位于不同区域); - 打包完成后立即删除本地
.tgz文件,避免污染工作区。
Helm Chart 的用户侧可配置项集中在 helm-chart/values.yaml,例如images.repository(默认即镜像仓库地址)、images.tag(留空时默认使用 Chart 的appVersion)、serviceAccounts.create、networkPolicies.create等,发布后用户可通过这些参数定制部署。
四、发布 Notes:为 tag 编写发布说明
PR 合并完成后,需要为新建的 git tag 创建 Release:
- 在仓库Tags页面找到最新 tag 所在行,点击面包屑进入详情;
- 选择Create release选项;
- 在 release notes 中简要描述自上一个版本以来的变更(如修复的 bug、新增的功能),可参考历史 releases 的写法。
注意:无需上传任何 assets。发布产物(镜像、清单、Chart)都会在 tag 对应的修订版本上自动就绪,不需要手动附加二进制附件。
五、更新生产环境:部署到 online-boutique-release 集群
发布说明公开后,需要将生产环境升级到新版本:
5.1 连接生产集群
gcloud container clusters get-credentials online-boutique-release \ --zone us-central1-c --project online-boutique-ci5.2 应用发布清单
kubectl apply -f ./release/kubernetes-manifests.yaml这里部署的正是make-release-artifacts.sh生成的、已注入新版本镜像 tag 的 release/kubernetes-manifests.yaml。
5.3 删除不必要的对象
生产环境拓扑与默认演示部署略有差异,需要移除两个资源:
kubectl delete service frontend-external kubectl delete deployment loadgeneratorfrontend-externalService:生产环境改用 Ingress / Gateway 暴露前端,不再需要这个 LoadBalancer 类型的 Service(其定义位于 kubernetes-manifests/frontend.yaml);loadgeneratorDeployment:生产环境不应运行压测流量发生器。
5.4 验证
访问生产站点,确认新版本可用。从仓库的 README.md 描述看,Online Boutique 生产站点的域名验证流程已集成在发布检查清单中,运维人员应确认页面、商品浏览、购物车、结算等核心链路均正常。
六、更新 major tag
日常发布采用vX.Y.Z三段式 tag,同时仓库还会维护一个浮动的major tag(如v0、v1),始终指向最新 release,方便用户引用「最新版」。更新 major tag 的操作如下:
export MAJOR_TAG=v0 # Edit this as needed (to v1/v2/v3/etc) git checkout release/${TAG} git pull git push --delete origin ${MAJOR_TAG} # Delete the remote tag (if it exists) git tag --delete ${MAJOR_TAG} # Delete the local tag (if it exists) git tag -a ${MAJOR_TAG} -m "Updating ${MAJOR_TAG} to its most recent release: ${TAG}" git push origin ${MAJOR_TAG} # Push the new tag to origin流程要点:切到已发布的release/${TAG}分支 → 删除远端与本地旧 major tag → 用带注释(-a)的方式重新打 major tag 并推送。由于git push --delete会先删除远端 tag,若该 major tag 已存在会被重建并指向最新版本。
七、发布后的内部通告
新版本发布完成后,可在 Google Groupg/online-boutique-announce上发布内部通告,同步版本内容、变更要点与升级注意事项,完成整个发布流程的最后一环。
八、发布流程全景回顾
一次完整的 Online Boutique 发布可以概括为以下流水线:
选定 TAG (vX.Y.Z) ↓ Manual Release Builder (GitHub Actions) └─ 构建并推送全部容器镜像(make-docker-images.sh 逻辑) └─ 生成 release/kubernetes-manifests.yaml、release/istio-manifests.yaml(make-release-artifacts.sh 逻辑) └─ 更新 kustomize/base/ 镜像 tag └─ 打包推送 Helm Chart(make-helm-chart.sh 逻辑) └─ 创建 release/vX.Y.Z 分支 + 打 vX.Y.Z tag + 自动开 PR ↓ PR 评审与 CI 检查通过后合并(勿删分支与 tag) ↓ 为 tag 编写 Release Notes(无需上传 assets) ↓ 更新生产集群:kubectl apply release/kubernetes-manifests.yaml,删除 frontend-external 与 loadgenerator ↓ 更新 major tag(如 v0)→ 内部通告整个流程的自动化脚本均位于 docs/releasing 目录,发布产物统一沉淀在 release、kustomize/base 与 helm-chart 三个目录中。理解这套「镜像构建 → 清单生成 → Chart 打包 → 分支与 tag 管理 → 生产部署」的链路,即可将此模式复用到其它云原生微服务项目的版本管理实践中。
【免费下载链接】microservices-demoSample cloud-first application with 10 microservices showcasing Kubernetes, Istio, and gRPC.项目地址: https://gitcode.com/GitHub_Trending/mi/microservices-demo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考