Help us learn about your current experience with the documentation. Take the survey.

部署安全

  • Tier: Free, Premium, Ultimate
  • Offering: 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 任务开始运行。

更多信息,请参见 资源组文档

防止过时的部署任务

流水线任务的实际执行顺序可能因运行而异,这可能导致不期望的行为。例如,较新流水线中的 部署任务 可能比旧流水线中的部署任务先完成。这会产生一种竞态条件,即较旧的部署稍后完成,覆盖了"较新"的部署。

通过启用 防止过时的部署任务 功能,您可以在启动新的部署任务时防止旧的部署任务运行。

当旧的部署任务启动时,它会失败并标记为:

  • 在流水线视图中显示为 failed outdated deployment job(过时部署任务失败)。
  • 查看已完成任务时显示为 The deployment job is older than the latest deployment, and therefore failed.(部署任务比最新部署旧,因此失败)。

当旧的部署任务是手动任务时,Run play )按钮将被禁用,并显示消息 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.(此部署任务不会自动运行,必须手动启动,但它比最新部署旧,因此无法运行)。

任务年龄由任务启动时间决定,而不是提交时间,因此在某些情况下可能会阻止较新的提交。

回滚部署的任务重试

您可能需要快速回滚到一个稳定的、过时的部署。 默认情况下,部署回滚 的流水线任务重试已启用。

要禁用流水线重试,请清除 允许回滚部署的任务重试 复选框。您应该在敏感项目中禁用流水线重试。

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

示例

启用防止过时部署功能之前的有问题的流水线流程示例:

  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 任务失败,这样就不会覆盖来自较新流水线的部署。

在部署冻结窗口期间阻止部署

如果您想在特定时期内阻止部署,例如在大多数员工休假的有计划的假期期间,您可以设置 部署冻结。 在部署冻结期间,无法执行任何部署。这有助于确保部署不会意外发生。

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

保护生产环境密钥

成功部署需要生产环境密钥。例如,当部署到云平台时,云服务提供商需要这些密钥来连接到他们的服务。在项目设置中,您可以定义和保护这些密钥的 CI/CD 变量。受保护的变量 只会传递给在 受保护的分支受保护的标签 上运行的流水线。 其他流水线不会获得受保护的变量。您还可以 将变量限定到特定环境。 我们建议您在受保护的环境上使用受保护的变量,以确保密钥不会被意外暴露。您还可以在 runner 端 定义生产环境密钥。 这可以防止其他拥有 Maintainer 角色的用户读取密钥,并确保 runner 只在受保护的分支上运行。

更多信息,请参见 流水线安全性

为部署使用独立项目

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

保护 .gitlab-ci.yml 不被修改

.gitlab-ci.yml 可能包含将应用程序部署到生产服务器的规则。此部署通常在推送合并请求后自动运行。为了防止开发人员修改 .gitlab-ci.yml,您可以在不同的仓库中定义它。配置可以引用另一个项目中的文件,该文件具有完全不同的权限集(类似于 为部署使用独立项目)。 在这种情况下,.gitlab-ci.yml 是公开可访问的,但只能由具有另一个项目适当权限的用户编辑。

更多信息,请参见 自定义 CI/CD 配置路径

部署前需要审批

在将部署提升到生产环境之前,通过专门的测试组进行交叉验证是确保安全性的有效方法。更多信息,请参见 部署审批