如何在DigitalOcean上使用GitLabRunner自动扩展GitLab持续部署
介绍
GitLab 是软件团队用来管理其完整开发和交付生命周期的开源工具。 GitLab 提供了广泛的功能集:问题跟踪、git 存储库、持续集成、容器注册、部署和监控。 这些功能都是作为一个应用程序从头开始构建的。 您可以在自己的服务器上托管 GitLab 或使用 GitLab.com,这是一种云服务,开源项目可以免费获得所有顶级功能。
GitLab 的持续集成/持续交付 (CI/CD) 功能是建立在部署之前测试所有代码的习惯的有效方法。 GitLab CI/CD 还具有高度可扩展性,这要归功于一个额外的工具 GitLab Runner,它可以自动扩展您的构建队列,以避免开发团队尝试发布代码的长时间等待。
在本指南中,我们将演示如何配置一个高度可扩展的 GitLab 基础架构,该基础架构可以管理自己的成本,并通过增加和减少可用服务器容量来自动响应负载。
目标
我们将在 DigitalOcean 上构建一个可扩展的 CI/CD 流程,通过在平台上创建新服务器并在队列为空时销毁它们来自动响应需求。
这些可重复使用的服务器由 GitLab Runner 进程生成,并在没有作业运行时自动删除,从而为您的团队降低成本和管理开销。
正如我们将在本教程中解释的那样,您可以控制在任何给定时间创建多少机器,以及它们在被销毁之前保留的时间长度。
我们将使用三个独立的服务器来构建这个项目,所以让我们先回顾一下术语:
- GitLab:您托管的 GitLab 实例或存储代码存储库的自托管实例。
- GitLab Bastion:bastion 服务器或 Droplet 是我们将要配置的核心。 它是用于与 DigitalOcean API 交互以创建 Droplet 并在必要时销毁它们的控件实例。 此服务器上未执行任何作业。
- GitLab Runners:您的 runners 是由 bastion 服务器动态创建的临时服务器或 Droplet,当需要在您的构建中执行 CI/CD 作业时队列。 这些服务器是一次性的,并且是在您的构建被标记为通过或失败之前执行或测试您的代码的地方。
通过利用每个 GitLab 组件,CI/CD 流程将使您能够根据需求进行响应式扩展。 考虑到这些目标,我们准备开始使用 GitLab 和 DigitalOcean 设置我们的持续部署。
先决条件
本教程将假设您已经在自己的服务器上或通过托管服务配置了 GitLab,并且您有一个现有的 DigitalOcean 帐户。
要在 Ubuntu 16.04 Droplet 上进行设置,您可以使用 DigitalOcean 一键式图像,或遵循我们的指南:“如何在 Ubuntu 16.04 上安装和配置 GitLab。”
出于本教程的目的,我们假设您在此 Droplet 上启用了专用网络,您可以按照我们关于“如何在现有 Droplet 上启用 DigitalOcean 专用网络”的指南来实现,但这不是强制性的.
在本教程中,我们将在我们的 Droplets 上使用具有管理员权限的非 root 用户。
第 1 步 — 导入 JavaScript 项目
首先,我们将在您现有的 GitLab 实例中创建一个新的示例项目,其中包含一个示例 Node.js 应用程序。
登录到您的 GitLab 实例并单击 加号图标 ,然后从下拉菜单中选择 New project。
在新项目屏幕上,选择 Import project 标签,然后单击 Repo by URL 直接从 GitHub 导入我们的示例项目。
将以下克隆 URL 粘贴到 Git 存储库 URL 中:
https://github.com/do-community/hello_hapi.git
这个存储库是一个用于演示的基本 JavaScript 应用程序,我们不会在生产环境中运行它。 要完成导入,请单击 New Project 按钮。
您的新项目现在将在 GitLab 中,我们可以开始设置 CI 管道。
第 2 步 — 设置基础架构
我们的 GitLab Code Runner 需要特定的配置,因为我们计划以编程方式创建 Droplet 来处理 CI 负载,因为它的增长和缩小。
我们将在本教程中创建两种类型的机器:bastion 实例,它控制和生成新机器,以及我们的 runner 实例,它们是由堡垒 Droplet 生成的临时服务器,用于构建需要时编码。 堡垒实例使用 Docker 创建您的跑步者。
以下是我们将使用的 DigitalOcean 产品,以及每个组件的用途:
- Flexible Droplets - 我们将为 GitLab Runners 创建内存优化的 Droplet,因为它是一个内存密集型进程,将使用 Docker 运行以进行容器化。 您可以在未来根据需要缩小或扩大此 Droplet,但是我们建议您以灵活的 Droplet 选项作为起点,以了解您的管道在负载下的性能。
- DigitalOcean Spaces (Object Storage) — 我们将使用 DigitalOcean Spaces 在创建和销毁运行器时将缓存的构建组件保留在它们之间。 这减少了在 CI 管道繁忙时设置新运行器所需的时间,并允许新运行器从其他运行器立即停止的地方继续。
- 私有网络 - 我们将为您的堡垒 Droplet 和 GitLab 运行器创建一个私有网络,以确保安全的代码编译并减少所需的防火墙配置。
首先,我们将创建堡垒 Droplet。 创建一个新Droplet,然后在下选择一个图像,选择一键应用选项卡。 从那里,选择Docker 17.12.0-ce on 16.04(注意这个版本在撰写本文时是最新的),然后选择可用的最小Droplet大小,因为我们的堡垒Droplet将管理其他液滴而不是实际执行测试。
建议您在包含 DigitalOcean Spaces 的数据中心中创建服务器,以便使用前面提到的对象存储缓存功能。
选择 Private networking 和 Monitoring 选项,然后单击 Create Droplet。
我们还需要设置将用于缓存的存储空间。 按照“如何创建 DigitalOcean 空间和 API 密钥”中的步骤,在与您托管的 GitLab 实例相同或最近的数据中心中创建一个新空间,以及一个 API 密钥。
记下这个键,因为我们稍后会在教程中用到它。
现在是时候开始我们的 CI 了!
第 3 步 — 配置 GitLab Runner Bastion 服务器
准备好新的 Droplet 后,我们现在可以配置 GitLab Runner。 我们将从 GitLab 和 GitHub 存储库安装脚本。
作为最佳实践,请务必在运行以下完整命令之前检查脚本以确认您将安装的内容。
使用 SSH 连接到 Droplet,进入 /tmp
目录,然后将 官方 GitLab Runner 存储库 添加到 Ubuntu 的包管理器中:
cd /tmp curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
添加后,安装 GitLab Runner 应用程序:
sudo apt-get install gitlab-runner
我们还需要安装 Docker Machine,这是一个额外的 Docker 工具,可以帮助在云提供商上自动部署容器:
curl -L https://github.com/docker/machine/releases/download/v0.14.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && \ sudo install /tmp/docker-machine /usr/local/bin/docker-machine
完成这些安装后,我们可以继续将 GitLab Runner 连接到 GitLab 安装。
第 4 步 — 获取 Runner 注册令牌
要将 GitLab Runner 链接到您现有的 GitLab 安装,我们需要通过获取将您的 runner 验证到您的代码存储库的令牌来将两个实例链接在一起。
以管理员用户身份登录到您现有的 GitLab 实例,然后单击扳手图标进入管理员设置区域。
在屏幕左侧,将鼠标悬停在 Overview 上,然后从出现的列表中选择 Runners。
在 How to setup a shared Runner for a new project 部分下的 Runners 页面上,复制步骤 3 中显示的令牌,并将其与步骤中 GitLab 实例的可公开访问 URL 一起记下2. 如果你为 Gitlab 使用 HTTPS,请确保它不是自签名证书,否则 GitLab Runner 将无法启动。
第 5 步 — 在 Bastion Droplet 上配置 GitLab
回到与堡垒 Droplet 的 SSH 连接,运行以下命令:
sudo gitlab-runner register
这将启动链接过程,您将被问到一系列问题。
在下一步中,输入上一步中的 GitLab 实例 URL:
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com) https://example.digitalocean.com
输入您从 GitLab 实例获得的令牌:
Please enter the gitlab-ci token for this runner sample-gitlab-ci-token
输入有助于您在 GitLab Web 界面中识别它的描述。 为了清楚起见,我们建议将此实例命名为独特的名称,例如 runner-bastion
。
Please enter the gitlab-ci description for this runner [yourhostname] runner-bastion
如果相关,您可以输入您将使用跑步者构建的代码的标签。 但是,我们建议在此阶段将其留空。 这可以在以后从 GitLab 界面轻松更改。
Please enter the gitlab-ci tags for this runner (comma separated): code-tag
选择您的跑步者是否应该能够运行未标记的作业。 此设置允许您选择运行程序是应该构建完全没有标签的存储库,还是需要特定标签。 在这种情况下选择 true,以便您的运行器可以执行所有存储库。
Whether to run untagged jobs [true/false]: true
选择是否应该在您的项目之间共享此运行器,或者锁定到当前运行器,这会阻止它构建除指定代码之外的任何代码。 暂时选择 false,因为稍后可以在 GitLab 的界面中更改:
Whether to lock Runner to current project [true/false]: false
选择将构建您的机器的执行器。 因为我们将使用 Docker 创建新的 Droplet,所以我们将在此处选择 docker+machine
,但您可以在此 兼容性图表 中阅读有关每种方法的优势的更多信息:
Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell: docker+machine
系统会询问您将哪个图像用于未明确定义的项目。 我们将选择一个基本的、安全的默认值:
Please enter the Docker image (e.g. ruby:2.1): alpine:latest
现在您已经完成了核心堡垒运行器的配置! 此时,它应该出现在 GitLab 管理设置的 GitLab Runner 页面中,我们访问该页面以获取令牌。
如果您在这些步骤中遇到任何问题,GitLab Runner 文档 包含用于故障排除的选项。
第 6 步 — 配置 Docker 缓存和 Docker 机器
为了在构建队列繁忙时加快 Droplet 的创建,我们将利用 Docker 在 Bastion Droplet 上的缓存工具来存储您在 DigitalOcean Spaces 上常用容器的图像。
为此,请使用以下命令在 SSH shell 上升级 Docker Machine:
curl -L https://github.com/docker/machine/releases/download/v0.14.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && sudo install /tmp/docker-machine /usr/local/bin/docker-machine
随着 Docker Machine 的升级,我们可以继续设置我们的访问令牌以供 GitLab Runner 使用。
第 7 步 — 收集 DigitalOcean 凭证
现在我们需要创建 GitLab Runner 将用于使用您的 DigitalOcean 帐户创建新 Droplets 的凭据。
访问您的 DigitalOcean dashboard 并单击 API。 在下一个屏幕上,查找 个人访问令牌,然后单击 生成新令牌。
为新令牌命名一个您能识别的名称,例如 GitLab Runner Access
并确保读取和写入范围都已启用,因为我们需要 Droplet 在没有人工干预的情况下创建新机器。
将令牌复制到安全的地方,因为我们将在下一步中使用它。 如果不重新生成它,您将无法再次检索此令牌,因此请确保它已安全存储。
第 8 步 — 编辑 GitLab Runner 配置文件
要将所有这些组件组合在一起,我们需要完成对堡垒 Droplet 的配置,以便与您的 DigitalOcean 帐户进行通信。
在您与堡垒 Droplet 的 SSH 连接中,使用您喜欢的文本编辑器(例如 nano)打开 GitLab Runner 配置文件进行编辑:
nano /etc/gitlab-runner/config.toml
此配置文件负责您的 CI 设置用于按需扩展和缩减的规则。 要将堡垒配置为按需自动扩展,您需要添加以下行:
/etc/gitlab-runner/config.toml
concurrent = 50 # All registered Runners can run up to 50 concurrent builds [[runners]] url = "https://example.digitalocean.com" token = "existinggitlabtoken" # Note this is different from the registration token used by `gitlab-runner register` name = "example-runner" executor = "docker+machine" # This Runner is using the 'docker+machine' executor limit = 10 # This Runner can execute up to 10 builds (created machines) [runners.docker] image = "alpine:latest" # Our secure image [runners.machine] IdleCount = 1 # The amount of idle machines we require for CI if build queue is empty IdleTime = 600 # Each machine can be idle for up to 600 seconds, then destroyed MachineName = "gitlab-runner-autoscale-%s" # Each machine will have a unique name ('%s' is required and generates a random number) MachineDriver = "digitalocean" # Docker Machine is using the 'digitalocean' driver MachineOptions = [ "digitalocean-image=coreos-stable", # The DigitalOcean system image to use by default "digitalocean-ssh-user=core", # The default SSH user "digitalocean-access-token=DO_ACCESS_TOKEN", # Access token from Step 7 "digitalocean-region=nyc3", # The data center to spawn runners in "digitalocean-size=1gb", # The size (and price category) of your spawned runners "digitalocean-private-networking" # Enable private networking on runners ] [runners.cache] Type = "s3" # The Runner is using a distributed cache with the S3-compatible Spaces service ServerAddress = "nyc3.spaces.digitaloceanspaces.com" AccessKey = "YOUR_SPACES_KEY" SecretKey = "YOUR_SPACES_SECRET" BucketName = "your_bucket_name" Insecure = true # We do not have a SSL certificate, as we are only running locally
添加新行后,根据您的设置自定义访问令牌、区域和 Droplet 大小。 出于本教程的目的,我们使用了 1GB 的最小 Droplet,并在 NYC3 中创建了我们的 Droplet。 请务必使用与您的案例相关的信息。
您还需要自定义缓存组件,并在基础设施配置步骤中输入您的 Space 的服务器地址、访问密钥、密钥和您创建的 Space 的名称。
完成后,重新启动 GitLab Runner 以确保正在使用配置:
gitlab-runner restart
如果您想了解更多所有可用选项,包括非高峰时间,您可以阅读 GitLab 的高级文档。
第 9 步 — 测试您的 GitLab Runner
此时,我们的 GitLab Runner 堡垒 Droplet 已配置完毕,并且能够在 CI 队列填满时按需创建 DigitalOcean Droplet。 我们需要通过前往您的 GitLab 实例和我们在步骤 1 中导入的项目来对其进行测试,以确保它可以正常工作。
要触发构建,请通过单击编辑 readme.md
文件,然后单击 edit,并将任何相关的测试文本添加到文件中,然后单击 Commit changes。
现在将自动触发构建,可以在左侧导航中项目的 CI/CD 选项下找到。
在此页面上,您应该看到一个状态为 running 的管道条目。 在您的 DigitalOcean 帐户中,您将看到 GitLab Runner 自动创建的许多 Droplet 以构建此更改。
恭喜! 您的 CI 管道是云可扩展的,现在可以管理自己的资源使用。 在指定的空闲时间之后,机器应该会自动销毁,但我们建议您手动验证这一点,以确保您不会被意外计费。
故障排除
在某些情况下,GitLab 可能会报告运行器无法访问,因此不执行任何操作,包括部署新运行器。 您可以通过停止 GitLab Runner 来解决此问题,然后在调试模式下再次启动它:
gitlab-runner stop gitlab-runner --debug start
输出应该会引发错误,这将有助于确定导致问题的配置。
如果您的配置创建了太多机器,并且您希望同时删除它们,您可以运行以下命令将它们全部销毁:
docker-machine rm $(docker-machine ls -q)
更多故障排除步骤和额外配置选项,可以参考GitLab的文档。
结论
您已使用 GitLab Runner 和 Docker 成功设置了自动化 CI/CD 管道。 从这里,您可以使用 Docker Registry 配置更高级别的缓存以优化性能或探索将代码构建标记为特定 GitLab 代码运行器的使用。
有关 GitLab Runner 的更多信息,请参阅详细文档,或者要了解更多信息,您可以阅读 GitLab 的系列博文,了解如何充分利用您的持续集成管道。
这篇文章也出现在 GitLab 博客 上。