布流程全解:從 bundle 生成到 OperatorHub 上架)
Loki Operator 發(fā)布流程全解從 bundle 生成到 OperatorHub 上架【免費(fèi)下載鏈接】lokiLike Prometheus, but for logs.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/lok/loki本指南系統(tǒng)講解 Grafana Loki Operator位于 operator/ 目錄的社區(qū)版本發(fā)布機(jī)制如何通過make bundle-all生成 OLM bundle、如何借助 release-please 自動(dòng)化版本號(hào)提升與 CHANGELOG 生成、如何將鏡像發(fā)布到制品倉庫以及如何自動(dòng)向兩個(gè) OperatorHub 社區(qū)倉庫提交上架 PR。讀完本文你將完整掌握 Loki Operator 從一次代碼合并到在 Kubernetes 生態(tài)中可被 OLM 安裝的端到端發(fā)布鏈路并理解每一環(huán)背后的工作流設(shè)計(jì)與配置細(xì)節(jié)。發(fā)布流程總體設(shè)計(jì)發(fā)布一個(gè) Loki Operator 社區(qū)版本需要依次完成以下四件事對(duì)應(yīng) release.md 中 Design 一節(jié)的描述提升 Loki Operator 版本號(hào)并生成 bundle 清單執(zhí)行make bundle-all更新 CHANGELOG.md到新版本創(chuàng)建 release tag 與 GitHub release向 [k8s-operatorhub/community-operators] 與 [redhat-openshift-ecosystem/community-operators-prod] 兩個(gè)倉庫各開一個(gè) PR提交新版本 bundle 的內(nèi)容。其中第 2、3 步由 GitHub 官方維護(hù)的release-pleaseaction 自動(dòng)化完成第 4 步則由一個(gè)在 release tag 創(chuàng)建時(shí)觸發(fā)的 workflow 自動(dòng)執(zhí)行。第 1 步bundle 生成目前仍是人工操作是整條鏈路中唯一沒有自動(dòng)化的環(huán)節(jié)。值得強(qiáng)調(diào)的是Loki Operator 與 Loki 主項(xiàng)目共享同一個(gè)倉庫但Operator 的 release-please 流程與 Loki 自身的發(fā)布流程是相互獨(dú)立的Operator 的配置單獨(dú)存放在 operator/release-please-config.json且 workflow 只監(jiān)聽operator/**路徑的變更。第 1 步用 make bundle-all 生成 bundle 清單bundle 是什么bundle 是 OLMOperator Lifecycle Manager生態(tài)中 Operator 的標(biāo)準(zhǔn)打包格式包含 ClusterServiceVersionCSV清單、CustomResourceDefinitionCRD以及元數(shù)據(jù)注解。Loki Operator 針對(duì)不同發(fā)行渠道維護(hù)了三個(gè) bundle 變體見 operator/Makefile 中的VARIANT變量變體鏡像倉庫通道適用場(chǎng)景communitydocker.io/grafanaalpha通用社區(qū)分發(fā)默認(rèn)community-openshiftdocker.io/grafanaalpha帶 OpenShift 兼容注解的社區(qū)包openshiftquay.io/openshift-loggingstableOpenShift 官方渠道隨 OpenShift Logging 發(fā)行bundle-all目標(biāo)會(huì)依次生成以上三個(gè)變體operator/Makefile.PHONY: bundle-all bundle-all: ## Generate both bundles. $(MAKE) bundle $(MAKE) bundle VARIANTcommunity-openshift $(MAKE) bundle VARIANTopenshiftbundle 生成的具體動(dòng)作單個(gè)bundle目標(biāo)operator/Makefile做三件事.PHONY: bundle bundle: manifests $(KUSTOMIZE) $(OPERATOR_SDK) ## Generate variant bundle manifests and metadata, then validate generated files. cd config/manager $(KUSTOMIZE) edit set image controller$(IMG) cd $(BUNDLE_DIR) cp ../../PROJECT . $(KUSTOMIZE) build ../../$(MANIFESTS_DIR) | $(OPERATOR_SDK) generate bundle $(BUNDLE_BUILD_GEN_FLAGS) rm PROJECT $(OPERATOR_SDK) bundle validate $(BUNDLE_DIR)通過kustomize edit set image controller$(IMG)把 CSV 中的控制器鏡像地址替換為當(dāng)前版本鏡像用operator-sdk generate bundle從config/manifests/variant生成 bundle 清單輸出到./bundle/variant目錄如 operator/bundle/community/用operator-sdk bundle validate校驗(yàn)生成的 bundle 是否符合 OLM 規(guī)范。版本號(hào)由VERSION變量控制當(dāng)前倉庫默認(rèn)值為0.11.0見 operator/Makefile。發(fā)布前需要先在 PR 中把該版本號(hào)提升為目標(biāo)版本例如升級(jí)到0.11.1或0.12.0同時(shí)保證提交信息規(guī)范見下文 Releasing 一節(jié)這也是原文檔強(qiáng)調(diào) be careful with the commit message 的原因。第 2、3 步release-please 自動(dòng)化版本發(fā)布release-please 的工作原理release-please 通過解析 git 歷史中的Conventional Commit提交信息來驅(qū)動(dòng)整個(gè)發(fā)布流程掃描到可發(fā)布單元releasable unit即以feat、fix、deps為前綴的提交后自動(dòng)創(chuàng)建 release PR其中包含版本號(hào)提升與 CHANGELOG 生成release PR 被合并后release-please 自動(dòng)創(chuàng)建 GitHub release隨后繼續(xù)等待下一個(gè)可發(fā)布單元再開啟下一輪 release PR。Operator 的 release-please workflow 位于 .github/workflows/operator-release-please.yml其觸發(fā)條件與關(guān)鍵參數(shù)如下on: push: paths: - operator/** branches: - main即只有當(dāng)operator/**路徑下有合并到main的提交時(shí)才會(huì)運(yùn)行使用 GitHub Apploki-gh-app簽發(fā)的 token 調(diào)用googleapis/release-please-actionv5.0.0并指定path: operator只關(guān)注operator子目錄config-file: operator/release-please-config.json使用獨(dú)立的 manifest 配置。operator/release-please-config.json 詳解operator/release-please-config.json 是理解整個(gè)發(fā)布策略的關(guān)鍵其完整內(nèi)容如下{ bump-minor-pre-major: true, bump-patch-for-minor-pre-major: true, include-component-in-tag: true, draft: true, tag-separator: /, packages: { operator: { component: operator, release-type: go, pull-request-title-pattern: chore(${component}): Community release ${version}, changelog-path: CHANGELOG.md } } }結(jié)合原文檔的說明各配置項(xiàng)的含義如下include-component-in-tagtag-separator: /release tag 采用operator/vX.Y.Z格式組件名 斜杠 版本號(hào)。這個(gè) tag 前綴也是后續(xù) OperatorHub 發(fā)布 workflow 的觸發(fā)過濾器release-type: go按 Go 模塊語義處理版本提升作用于 operator/ 目錄pull-request-title-patternrelease PR 的標(biāo)題固定為chore(operator): Community release version格式——注意這個(gè)標(biāo)題格式正是下一節(jié) 防止未更新 manifests 就合并 檢查工作流的匹配依據(jù)changelog-path: CHANGELOG.md生成的變更日志寫入 operator/CHANGELOG.md。從該文件可以看到 release-please 的實(shí)際輸出風(fēng)格每個(gè)版本一節(jié)包含? BREAKING CHANGES、Features、Bug Fixes分組且 security/deps 類提交也會(huì)被歸類記錄。為什么使用 bump-minor-pre-major 與 bump-patch-for-minor-pre-major由于 Operator 目前仍處于v1.0.0之前的階段pre-major配置開啟了bump-minor-pre-major與bump-patch-for-minor-pre-major效果是合并feat、fix、deps提交 → 只提升patch版本如v0.10.1→v0.10.2合并feat!、fix!帶感嘆號(hào)的破壞性變更提交→ 提升minor版本如v0.10.x→v0.11.0。由此在未引入破壞性變更的前提下當(dāng)前僅監(jiān)聽main分支的 release-please 可以支撐兩種發(fā)布場(chǎng)景Case 1patch 發(fā)布從v0.Y.x的 diff 發(fā)布v0.Y.x1。該場(chǎng)景在破壞性特性合并進(jìn)main之前一直有效Case 2minor 發(fā)布從v0.Y.x的 diff 發(fā)布新版本v0.Y1.0。為什么啟用 draftOperator 與 Loki 主項(xiàng)目共享同一個(gè) GitHub 倉庫直接由 release-please 創(chuàng)建的 release 會(huì)被標(biāo)記為倉庫的latest導(dǎo)致 Loki 最新版本 被誤顯示為 Operator 的版本。release-please 本身沒有提供關(guān)閉latest標(biāo)記的選項(xiàng)因此配置了draft: true讓 release-please 只創(chuàng)建草稿 release再由后續(xù)步驟發(fā)布.github/workflows/operator-release-please.yml 中的publishReleasejob 在鏡像構(gòu)建完成后執(zhí)行g(shù)h release edit $RELEASE_NAME --draftfalse --latestfalse即把草稿轉(zhuǎn)為正式 release同時(shí)明確不設(shè)為 latest從而與 Loki 主項(xiàng)目的發(fā)布記錄區(qū)分開。publishImages構(gòu)建并推送 Operator 鏡像當(dāng) release-please 判定需要發(fā)布release_created輸出為 true時(shí)publishImagesjob 通過復(fù)用工作流 .github/workflows/operator-reusable-image-build.yml 構(gòu)建并推送 Operator 鏡像傳入?yún)?shù)包括dockerfile: operator/Dockerfile見 operator/Dockerfileregistry: us-docker.pkg.dev、organization: grafanalabs-global/dockerhub-loki-prod-mirror、image_name: loki-operatortag由 release-please 輸出的major.minor.patch三部分拼接而成。鏡像最終推送到 Google Artifact RegistryGAR的地址為us-docker.pkg.dev/grafanalabs-global/dockerhub-loki-prod-mirror/loki-operator:version之后由gar-image-mirror服務(wù)將其鏡像同步到 Docker Hub 的docker.io/grafana/loki-operator。從復(fù)用工作流源碼可以看到構(gòu)建細(xì)節(jié).github/workflows/operator-reusable-image-build.yml使用 QEMU Docker Buildx 進(jìn)行多架構(gòu)構(gòu)建platforms: linux/amd64,linux/arm64,linux/arm構(gòu)建上下文按鏡像名推斷l(xiāng)oki-operator-bundle使用operator/bundle/openshift其余含loki-operator使用operator目錄該復(fù)用工作流同時(shí)支持兩套倉庫體系登錄 GARus-docker.pkg.dev或從 Vault 拉取憑據(jù)登錄quay.ioOpenShift 渠道使用。第 4 步向 OperatorHub 社區(qū)倉庫發(fā)布觸發(fā)機(jī)制發(fā)布工作流 .github/workflows/operator-publish-operator-hub.yml 監(jiān)聽 GitHubrelease 發(fā)布事件并校驗(yàn) tag 前綴on: release: types: [published] jobs: operator-hub-prod-release: if: startsWith(github.event.release.tag_name, operator/) ...當(dāng) tag 以operator/開頭即 release-please 創(chuàng)建的operator/vX.Y.Z時(shí)會(huì)并發(fā)調(diào)用兩次復(fù)用工作流 .github/workflows/operator-reusable-hub-release.yml分別面向redhat-openshift-ecosystem/community-operators-prodOpenShift 生產(chǎn)渠道k8s-operatorhub/community-operators通用社區(qū)渠道。復(fù)用工作流做了哪些事.github/workflows/operator-reusable-hub-release.yml 依次完成以下動(dòng)作簽發(fā) GitHub App token使用loki-operator-hub-publisher這個(gè)專用 GitHub App保證后續(xù)以受信任的 bot 身份操作提取版本號(hào)從 tagoperator/vX.Y.Z中通過${TAG:10}切片去掉operator/v前綴得到純版本號(hào)寫入環(huán)境變量同步 fork用gh repo sync grafanabot/$INPUTS_REPO --source org/repo --force先把 grafanabot 名下的 fork 同步到最新避免拉取完整上游倉庫淺克隆會(huì)導(dǎo)致 push 報(bào) shallow update not allowed檢出兩個(gè)倉庫分別 checkout grafanabot fork 的 operatorhub 倉庫工作目錄與grafana/loki主倉庫tmp/目錄復(fù)制 bundle 清單將新版本目錄創(chuàng)建到 operatorhub 倉庫的operators/loki-operator/version/下內(nèi)容來自./tmp/operator/bundle/community${OCP_DIR}/*mkdir operators/loki-operator/${VERSION} cp -R ./tmp/operator/bundle/community${OCP_DIR}/* operators/loki-operator/${VERSION} rm -f operators/loki-operator/${VERSION}/bundle.Dockerfile注意這里同時(shí)做了兩件重要的適配一是按目標(biāo)渠道選擇community或community-openshift變體二是刪除 bundle.DockerfileOperatorHub 社區(qū)目錄不需要它添加 OpenShift 支持版本注解僅 OpenShift 倉庫使用fjogeleit/yaml-update-action在operators/loki-operator/version/metadata/annotations.yaml中寫入annotations[com.redhat.openshift.versions]當(dāng)前值為v4.12。這正是原文檔所說 Adding the ocp supported version annotation to the metadata.yaml 的實(shí)現(xiàn)創(chuàng)建 PR以 grafanabot 身份CLA 已批準(zhǔn)新建分支update-loki-operator-to-version提交并gh pr create --repo org/repo --base mainPR 標(biāo)題為Update the loki-operator to version。防止未更新 manifests 就合并 release-please PR由于第 1 步make bundle-all生成 bundle尚未自動(dòng)化、與 release-please 相互獨(dú)立存在release-please PR 先合并、bundle 后補(bǔ)的時(shí)序風(fēng)險(xiǎn)。為此倉庫設(shè)置了專門的守衛(wèi)工作流 .github/workflows/operator-check-prepare-release-commit.yml。該工作流只針對(duì) release-please PR 運(yùn)行通過兩個(gè)條件限定if: | github.event.pull_request.head.ref release-please--branches--main--components--operator contains(github.event.pull_request.title, chore( operator): Community release)其邏輯是先從 PR 標(biāo)題chore( operator): Community release semver中提取目標(biāo)版本號(hào)再用gh search commits在main分支搜索提交信息為chore(operator): Prepare community release vsemver的提交若找不到則以退出碼 1 使檢查失敗阻止 PR 合并。也就是說人工提交的版本提升 bundle 生成準(zhǔn)備提交必須先于 release-please PR 存在。原文檔也指出一旦第 1 步實(shí)現(xiàn)自動(dòng)化這個(gè)守衛(wèi)工作流就可以移除。Releasing一次完整發(fā)布的操作清單綜合以上設(shè)計(jì)一次真實(shí)的 Loki Operator 社區(qū)發(fā)布按以下步驟執(zhí)行對(duì)應(yīng)原文檔 Releasing 一節(jié)創(chuàng)建版本提升 PR先手動(dòng)提交一次包含版本號(hào)提升與 bundle 生成的變更提交信息務(wù)必為chore(operator): Prepare community release vversion例如 v0.6.1 的準(zhǔn)備工作并合并到main在 release-please PR 上重新觸發(fā)operator-publish-operator-hub檢查確保守衛(wèi)工作流通過合并 release-please PR合并后 release-please 自動(dòng)創(chuàng)建 release草稿態(tài)標(biāo)題形如chore(operator): Community release vversion鏡像發(fā)布publishImagesjob 構(gòu)建多架構(gòu)鏡像并推送到 GAR隨后由gar-image-mirror同步到 Docker Hub 的docker.io/grafana/loki-operatorOperatorHub PR 自動(dòng)創(chuàng)建operator-publish-operator-hubworkflow 檢測(cè)到operator/前綴的正式 release 后自動(dòng)向k8s-operatorhub/community-operators與redhat-openshift-ecosystem/community-operators-prod兩個(gè)倉庫各開一個(gè)包含新版本 bundle 的 PR。全鏈路小結(jié)把整條發(fā)布流水線串起來看Loki Operator 的發(fā)布由四類 GitHub Actions 工作流協(xié)同完成工作流觸發(fā)時(shí)機(jī)職責(zé)operator-release-please.ymloperator/**合并到main生成 CHANGELOG、創(chuàng)建草稿 release、調(diào)度鏡像構(gòu)建與正式發(fā)布o(jì)perator-reusable-image-build.yml被 release workflow 調(diào)用多架構(gòu)構(gòu)建并推送 Operator 鏡像到 GAR / quay.iooperator-check-prepare-release-commit.ymlrelease-please PR 上校驗(yàn) Prepare community release 準(zhǔn)備提交已存在operator-publish-operator-hub.ymltag 以operator/開頭的 release 發(fā)布觸發(fā)向兩個(gè) OperatorHub 社區(qū)倉庫的上架 PR其中唯一的人工環(huán)節(jié)是第 1 步更新 operator/Makefile 中的VERSION并執(zhí)行make bundle-all重新生成 operator/bundle/ 下的清單隨后以約定的提交信息合入main。其余版本號(hào)計(jì)算、CHANGELOG 生成、release 創(chuàng)建、鏡像發(fā)布與 OperatorHub 上架全部由自動(dòng)化流水線接管既保證了與 Loki 主項(xiàng)目發(fā)布記錄的清晰隔離operator/tag 前綴 draft --latestfalse也保證了每次上架內(nèi)容的規(guī)范性與可追溯性。【免費(fèi)下載鏈接】lokiLike Prometheus, but for logs.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/lok/loki創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考