拓冰建站拓冰建站
首页 / 资讯中心 / 正文

使用 Fleet GitOps 搭建 staging 与 production 双环境发布流程

使用 Fleet GitOps 搭建 staging 与 production 双环境发布流程【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet本文将围绕 Fleet 开源设备管理平台的 GitOps 工作流讲解如何在 GitHub 上搭建 staging 与 production 两套环境的配置仓库与密钥体系确保任何配置变更先经过 staging 实例验证、再晋升到生产环境。读完本文你将掌握双仓库与单仓库双分支两种仓库结构的取舍、GitHub 环境级密钥隔离的最佳实践、fork PR 中安全处理 API Token 的方法以及fleetctl gitops命令在 CI 中的正确用法。Fleet 的核心理念是把设备当作代码来管理所有组织设置org settings、标签labels、策略policies、软件software、MDM 配置都可以沉淀为 YAML 文件交给fleetctl gitops命令统一应用参考 GitOps 配置参考。但如果每一次配置变更都直接推送到生产 Fleet 实例风险不言而喻——一个拼写错误的策略查询、一个写错的配置 profile可能瞬间影响所有生产设备。因此搭建 staging 与 production 双环境的 GitOps 流水线是所有使用 Fleet 管理大规模设备团队的必修课。前置条件在动手之前你需要具备一套已有的 Fleet GitOps 仓库可先用fleetctl new生成一个 starter 仓库再逐步扩展。GitHub 仓库设置的 Admin 权限。一台 staging Fleet 实例和一台 production Fleet 实例各自独立的 API Token。Fleet 官方提供的 GitOps 模板本身并不内置 staging/production 的目录结构所以环境的拆分方式需要你自己决策。下面两种方案在实践中都验证有效。方案一两个独立仓库从fleet-gitops-production仓库 fork 出一个fleet-gitops-staging仓库每个仓库拥有自己独立的 secrets、协作者和工作流文件。在 GitHub 上通过 fork 仓库的 Contribute 按钮向 production 仓库发起 PR 来晋升变更如果 production 与 staging 出现漂移应当尽量避免正确的做法是始终先在 staging 上改再向上晋升可以通过同步 fork 的方式把 production 的变更拉回 staging。该方案的优势干净的密钥隔离。两个仓库各自维护 secrets不存在同一个工作流文件错误引用另一环境 secret的隐患。支持并行测试。可以在 fork 仓库中新建分支分别承载不同的待测变更逐个测试后再合并非常适合多人协作、同时推进多个变更的场景。代价也很直接双倍的仓库管理成本。需要维护两套分支保护规则、两个工作流文件随着 Fleet GitOps schema 的演进例如新增某个顶层配置键两个仓库的工作流文件需要同步更新。方案二单仓库双分支在同一个仓库内使用staging分支部署到 staging 实例、main分支部署到 production 实例。变更先在staging分支上验证验证通过后通过 PR 从staging合入main完成晋升。该方案的优势只需维护一套协作者、PR 模板和工作流文件。缺点是要求对环境级别的密钥作用域进行严格设计见下一节确保跑在staging分支上的工作流永远读不到 production 的 secrets。同时多个变更的 staged 测试会稍显复杂因为你需要持续保持两个分支与两台服务器之间的同步。建议如果不确定如何选择先使用双仓库方案如果你是唯一的维护者且对 git 操作有把握可以考虑单仓库双分支。单仓库双分支时如何作用域 secrets如果你选择了方案一密钥隔离已经天然完成每个仓库拥有独立的 secretsstaging 的 run 不可能看到 production 的 token。本节针对方案二staging 与 production 共用一个仓库展开。千万不要在两个分支上共用一套仓库级 secretsSettings Secrets and variables Actions Repository secrets。仓库级 secret 对该仓库内的每一次 workflow run 都可见无论触发它的分支是哪个——一旦分支条件写错staging 的 run 就可能拿到 production 的 API token。有两种规避方式。方式一GitHub environments推荐使用 GitHub environments 将 secrets 作用域限定到特定分支即使条件逻辑有 bug跑在错误分支上的工作流也根本无法读取对应环境的 secret。步骤如下进入Settings Environments创建两个环境例如staging和production。在每个环境的Deployment branches and tags设置中将环境限定到匹配的分支staging或main。将各自的FLEET_URL和FLEET_API_TOKEN作为环境级 secrets加入对应环境。在工作流文件中为每个 job 显式声明environment让它拉取正确的 secretsjobs: deploy: runs-on: ubuntu-latest environment: ${{ github.ref refs/heads/main production || staging }} steps: - uses: actions/checkoutv4 - name: Run fleetctl gitops env: FLEET_URL: ${{ secrets.FLEET_URL }} FLEET_API_TOKEN: ${{ secrets.FLEET_API_TOKEN }} run: fleetctl gitops --config ./default.yml这样从staging触发的 run 永远只能看到 staging 环境的 secrets即使工作流文件存在 bug 也不会越权。方式二仓库 secrets按分支条件选择为每个环境添加独立的 secrets例如STAGING_FLEET_API_TOKEN和PROD_FLEET_API_TOKEN在工作流中通过github.refcontext 依据触发分支选择env: FLEET_URL: ${{ github.ref refs/heads/main secrets.PROD_FLEET_URL || secrets.STAGING_FLEET_URL }} FLEET_API_TOKEN: ${{ github.ref refs/heads/main secrets.PROD_FLEET_API_TOKEN || secrets.STAGING_FLEET_API_TOKEN }}这种方式适用于任何 GitHub 套餐但安全性完全取决于每个 job 中条件表达式的正确性——分支判断里一个拼写错误就会静默地把 staging 的 run 指向 production 的 secret。相比 environments 的读不到这种方式是不该用但可能用错所以仅推荐在无法使用 environments 的场合采用。为 fork 仓库的 PR 开启 secrets 支持如果你采用方案一staging 仓库是 production 仓库的 fork。GitHub 默认将 fork 发起的 PR 视为外部贡献者提交——即使 fork 与主仓库同属一个 org 也是如此。此时Contribute 发起的 PR无法访问你的 Fleet API token工作流中的任何 dry-run 步骤都会因此失败。这个默认行为同时也是一道安全防线当存在真正的外部贡献者时它阻止有人通过篡改工作流文件来窃取你的 secrets。警告请务必理解风险后再开启相关选项。GitHub 会在工作流直接把 secret 值打印到日志时对其打码但这并不能阻止掌握工作流行为的人被修改的工作流步骤可以在打印前对 secret 做编码绕过打码或通过一次网络请求把 secret 发送到外部服务器——后者完全不经过日志。任何能访问你的 secrets、又会在 fork PR 代码上运行的工作流都存在这种风险因为 PR 发起者在那时掌控着该工作流。如果你确实需要让 fork PR 的工作流连接真实的 Fleet 实例例如在合并前对 GitOps 变更做 dry-run请记住一个关键事实fleetctl gitops --dry-run依然需要向 Fleet 实例认证因为它要拉取 Fleet 的当前状态并校验变更是否合法只是跳过了最后的应用apply步骤。它需要有效的 API token不存在无 secret的运行方式。与其把 production secrets 大范围暴露不如采用两个更安全的替代方案让 fork PR 的 dry-run 指向staging 实例的 token而非 production 的。即便 staging token 泄露其危害也远小于 production token 泄露。在Settings Environments中对环境开启Required reviewers必需审阅人。即使是 fork PR 发起的 run也必须经过维护者审批后才能访问该环境的 secrets。只有在万不得已时才考虑在Settings Actions General Fork pull request workflows from outside collaborators中开启 Send secrets and variables to workflows from fork pull requests。请把它等同于把 secrets 直接交给每一个 fork 贡献者来对待。此外需要注意该设置同时存在于仓库级与组织级组织级设置可以覆盖仓库级设置。如果组织层面已禁用该能力仅在仓库层面开启是不够的——组织 owner 还需要检查Organization settings Actions General。理解fleetctl gitops在 CI 中的行为上文工作流中的核心命令是fleetctl gitops。从 gitops.go 的源码可以看到它支持以下关键参数参数环境变量说明-f fileFILENAME必填。指定 GitOps 配置文件可多次使用no-team.yml/unassigned.yml二者只能出现一个--dry-runDRY_RUN只校验、不应用配置--delete-other-fleetsDELETE_OTHER_FLEETS删除 GitOps 配置中不存在的其他 fleet旧名--delete-other-teams/DELETE_OTHER_TEAMS已弃用--allow-unknown-keysALLOW_UNKNOWN_KEYS将未知键记录为警告而非直接报错--config—指定 fleetctl 的上下文配置文件--context—使用已保存的 fleetctl 上下文含 URL 与 tokendry-run 的语义在 gitops_test.go 中有直接体现测试先执行gitops -f file --dry-run随后断言AppConfig should be empty配置没有被应用再执行真实 run 才写入配置。也就是说dry-run 会完整走一遍解析、校验、与服务器当前状态比对的过程只是最终不落盘——这也正是它需要有效 API token 的原因。另一个测试 TestGitOpsDryRunRejectsInvalidLabelPlatform 进一步证明dry-run 阶段就会拒绝非法的 label platform 值让错误在进入生产之前就被拦截。在 CI 流水线中可以据此设计双阶段策略合并前的 PR 工作流执行fleetctl gitops -f ./default.yml --dry-run使用 staging token合并到main/staging分支后的部署工作流再执行不带--dry-run的真实应用。这样既能提前暴露配置错误又不至于把未经验证的配置直接推到生产。仓库结构建议结合 GitOps 配置参考 中规定的目录约定一个可供 staging/production 双环境复用的仓库大致如下fleet-gitops/ ├── default.yml # 全局设置org settings、custom_host_vitals、labels 等 ├── fleets/ │ ├── fleet-name.yml # 各团队fleet级配置 │ └── unassigned.yml # 未分配团队的 host 配置旧名 no-team.yml 已弃用 └── lib/ # 通过 path:/paths: 引用的标签、策略等独立文件该结构本身与环境无关——同一份 YAML 可以同时应用到 staging 与 production这正是 GitOps一份配置、多环境复用的价值所在环境差异URL、token全部由 CI 层的 secrets 与 environment 机制承担。只要在 staging 上验证通过后晋升到 production就能保证两套环境行为一致把变更风险控制在最小范围。小结无论选择双仓库还是单仓库双分支核心原则一致让 staging 成为 production 的唯一上游用 GitHub environments 或按分支选择的 secrets 做好密钥隔离用fleetctl gitops --dry-run在合并前完成校验并对 fork PR 的 secrets 访问保持最大限度的克制。这套流程既适合单人维护的小团队也能支撑多人协作、多变更并行的规模化场景。【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门