GitLab部署安全

GitLab部署安全

适用套餐:Free、Premium、Ultimate。提供方式:GitLab.com、GitLab Self-Managed、GitLab Dedicated。

部署作业是一类特殊的CI/CD作业,可能比流水线中的其他作业更敏感,需要额外谨慎处理。GitLab提供多项功能,帮助维持部署的安全与稳定。

你可以:

使用持续部署工作流,希望确保同一环境不会出现并发部署时,应:

概览视频:如何保护CD流水线和工作流。

限制关键环境的写入权限

默认情况下,至少拥有Developer角色的团队成员都可以修改环境。要限制关键环境,例如production环境的写入权限,可以设置受保护环境。

确保同一时刻只运行一个部署作业

GitLab CI/CD流水线作业并行运行,因此两个不同流水线中的部署作业可能同时尝试部署到同一环境。部署应顺序进行,所以这种行为并不理想。

在.gitlab-ci.yml中使用resource_group关键字,可以确保同一时刻只运行一个部署作业,例如:

deploy:
 script: deploy-to-prod
 resource_group: prod

未使用资源组时,可能出现以下问题流程:

  1. Pipeline-A中的deploy开始运行。
  2. Pipeline-B中的deploy开始运行。这属于并发部署,可能产生意外结果。
  3. Pipeline-A中的deploy完成。
  4. Pipeline-B中的deploy完成。

使用资源组后的改进流程:

  1. Pipeline-A中的deploy开始运行。
  2. Pipeline-B中的deploy尝试启动,但等待第一个deploy完成。
  3. Pipeline-A中的deploy完成。
  4. Pipeline-B中的deploy开始运行。

更多信息参见资源组文档。

阻止过时部署作业

流水线作业的实际执行顺序可能每次不同,引发意外行为。例如较新流水线的部署作业可能先于较旧流水线中的部署作业完成。这样会产生竞态:旧部署后来完成,覆盖“较新”的部署。

通过Prevent outdated deployment jobs设置,可以在较新的部署作业启动时阻止较旧的作业运行。

旧部署作业启动时会失败,并显示:

  • 流水线视图中的failed outdated deployment job。
  • 查看已完成作业时显示The deployment job is older than the latest deployment, and therefore failed.

如果旧部署作业为手动作业,Run按钮会被禁用,并显示This deployment job does not run automatically and must be started manually, but it's older than the latest deployment, and therefore can't run.

作业的新旧由作业启动时间决定,而非提交时间,因此有时较新的提交也可能被阻止。例如流水线A对应旧提交,流水线B对应新提交,两者都有手动部署作业。如果创建流水线B后才启动流水线A的作业,B的手动部署作业会被当作过时作业阻止,尽管流水线本身更新。

回滚部署的作业重试

有时需要迅速回滚到较旧但稳定的部署。默认允许为部署回滚重试流水线作业。

要禁用流水线重试,清除Allow job retries for rollback deployments复选框。敏感项目应禁用流水线重试。

需要回滚时,必须使用之前的提交运行新流水线。

示例

禁用Prevent outdated deployment jobs时,可能出现以下问题流程:

  1. 在默认分支创建Pipeline-A。
  2. 之后在默认分支创建Pipeline-B,包含较新的提交SHA。
  3. Pipeline-B的deploy先完成,部署较新代码。
  4. Pipeline-A的deploy稍后完成,部署旧代码,覆盖最新部署。

启用设置后的改进流程:

  1. 在默认分支创建Pipeline-A。
  2. 之后在默认分支创建Pipeline-B,包含较新的SHA。
  3. Pipeline-B的deploy先完成,部署较新代码。
  4. Pipeline-A的deploy失败,因此不会覆盖新流水线的部署。

在部署冻结窗口阻止部署

要在特定期间阻止部署,例如多数员工休假的计划假期,可以设置Deploy Freeze。在部署冻结期间,GitLab阻止部署,以免意外发生。

下一个已配置的部署冻结窗口,会显示在环境部署列表页面顶部。

保护生产机密

成功部署需要生产机密。例如部署到云时,云提供商要求这些机密才能连接其服务。可以在项目设置中定义并保护存储机密的CI/CD变量。受保护变量只传递给运行在受保护分支或受保护标签上的流水线,其他流水线不会获得这些变量。也可以将变量限定到特定环境。

在受保护环境中使用受保护变量,确保机密不会意外暴露。还可以在Runner端定义生产机密,防止其他Maintainer读取机密,并确保Runner仅在受保护分支上运行。

更多信息参见流水线安全。

使用独立部署项目

项目中所有Maintainer都能访问生产机密。如果需要限制可部署到生产环境的用户数量,可以创建独立项目,配置新的权限模型,将CD权限从原项目中隔离,并防止原项目Maintainer访问生产机密与CD配置。可以通过多项目流水线将CD项目连接到开发项目。

保护.gitlab-ci.yml免遭修改

.gitlab-ci.yml可能包含将应用部署到生产服务器的规则,部署通常在推送合并请求后自动运行。要防止开发者修改它,可以把它定义在其他仓库。配置可以引用权限完全不同的另一项目中的文件,类似于独立部署项目。

此时.gitlab-ci.yml公开可访问,但只有在另一项目中拥有相应权限的用户才能编辑。更多信息参见自定义CI/CD配置路径。

部署前要求批准

在将部署提升到生产环境前,由专门的测试团队交叉验证,是确保安全的有效方法。更多信息参见部署批准。

来源与署名

来源:GitLab Docs:Deployment safety,GitLab文档贡献者。本版为中文翻译,保留原文功能范围及示例。Copyright (c) 2011-present GitLab Inc. 文档及本译稿采用CC BY-SA 4.0,许可依据见官方仓库LICENSE。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容