用Docker部署自我托管的GitLab CI运行器的详细教程

330 阅读4分钟

在本教程中,我们将详细介绍如何用Docker将自我托管的GitLab CI/CD运行程序部署到DigitalOcean

GitLab CI/CD

GitLab CI/CD是一个持续集成和交付(CI/CD)解决方案,与GitLab完全集成。来自GitLab CI/CD管道的工作在称为运行者的进程中运行。你可以使用GitLab托管的共享运行器,也可以在你自己的基础设施上运行你自己的自我托管的运行器

范围

运行者可以提供给GitLab实例中的所有项目和组,也可以提供给特定的组或特定的项目(存储库)。我们将使用第一种方法,这样我们就可以用同一个运行器处理来自多个仓库的作业。

你也可以使用标签来控制一个运行器可以运行哪些作业。

关于运行器范围的更多信息,请查看官方文档中的《运行器的范围》。

由于你可能想在作业中运行docker ,以构建和测试在Docker容器内运行的应用程序,你需要从以下三种方法中选择一种。

我们将使用套接字绑定的方法(Docker-out-of-Docker?),将Docker套接字绑定到一个有卷的容器上。然后,运行GitLab runner的容器将能够与Docker守护程序进行通信,从而产生同级别的容器。

虽然我对这些方法都没有什么强烈的意见,但我还是推荐你阅读《在CI或测试环境中使用Docker-in-Docker?Jérôme Petazzoni,Docker-in-Docker的创造者,三思而行。

如果你对Docker-in-Docker的方法感到好奇,请查看《自定义Gitlab CI/CD运行器,用Docker-in-Docker缓存速度》。

DigitalOcean设置

首先,如果你还没有一个DigitalOcean账户,请注册一个DigitalOcean账户,然后生成一个访问令牌,以便你可以访问DigitalOcean的API。

将该令牌添加到你的环境中。

$ export DIGITAL_OCEAN_ACCESS_TOKEN=[your_digital_ocean_token]

如果你的本地机器上还没有Docker Machine,请安装它。

启动一个名为runner-node 的单一液滴。

$ docker-machine create \
    --driver digitalocean \
    --digitalocean-access-token $DIGITAL_OCEAN_ACCESS_TOKEN \
    --digitalocean-region "nyc1" \
    --digitalocean-image "debian-10-x64" \
    --digitalocean-size "s-4vcpu-8gb" \
    --engine-install-url "https://releases.rancher.com/install-docker/19.03.9.sh" \
    runner-node;

Docker部署

用SSH登录到dropplet。

$ docker-machine ssh runner-node

创建以下文件和文件夹。

├── config
│   └── config.toml
└── docker-compose.yml

docker-compose.yml文件中添加以下内容。

在这里,我们

  1. 使用了官方的GitLab Runner Docker镜像
  2. 为Docker套接字和 "config "文件夹添加卷。
  3. 将9252端口暴露给Docker主机。稍后会有更多内容。

按照官方的安装指南,下载并安装Docker Compose到droplet上,然后启动容器。

如果你遇到Docker Compose挂起的问题,请查看这个Stack Overflow问题

接下来,你需要获得一个注册令牌和URL。在你的小组的 "CI/CD设置 "中,展开 "运行者 "部分。请确保也禁用共享运行程序。

运行下面的命令来注册一个新的运行器,确保用你的组的注册令牌和URL替换 和 。

$ docker-compose exec gitlab-runner-container \
    gitlab-runner register \
    --non-interactive \
    --url  \
    --registration-token  \
    --executor docker \
    --description "Sample Runner 1" \
    --docker-image "docker:stable" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

docker-compose exec gitlab-runner-container \
    gitlab-runner register \
    --non-interactive \
    --url https://gitlab.com/ \
    --registration-token hvdSfcc1EmHLpK1Qds7s \
    --executor docker \
    --description "Sample Runner 1" \
    --docker-image "docker:stable" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

你应该看到类似的东西。

Runtime platform
arch=amd64 os=linux pid=18 revision=e0218c92 version=14.3.2

Running in system-mode.

Registering runner... succeeded
runner=hvdSfcc1

Runner registered successfully. Feel free to start it, but if it's running already
the config should be automatically reloaded!

同样,我们使用了docker套接字绑定的方法,这样docker 命令就可以在运行在运行器上的作业内运行。

查看GitLab运行器命令,了解更多关于register 命令以及注册和管理运行器的其他命令。

回到GitLab,你应该在你的组的 "CI/CD设置 "中看到注册的运行器。

通过为你的一个仓库运行CI/CD管道来测试它。

回到你的终端,看一下容器日志。

$ docker logs gitlab-runner-container -f

你应该看到作业的状态。

Checking for jobs... received
job=1721313345 repo_url=https://gitlab.com/testdriven/testing-gitlab-ci.git runner=yK2DqWMQ

Job succeeded
duration_s=32.174537956 job=1721313345 project=30721568 runner=yK2DqWMQ

配置

注意配置文件,config/config.toml

$ cat config/config.toml

concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "Sample Runner 1"
  url = "https://gitlab.com/"
  token = "yK2DqWMQB1CqPsRx6gwn"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0

看一下高级配置,了解更多可用的选项。你可以配置一些东西,如日志和缓存选项、内存限制和CPU数量,仅举几例。

由于我们没有利用外部缓存,如Amazon S3或Google云存储,删除[runners.cache] 部分。然后,重新启动运行器。

$ docker-compose exec gitlab-runner-container gitlab-runner restart

试着同时运行两个作业。由于并发性被设置为1 --concurrent = 1 -- 在运行器上一次只能运行一个作业。所以,其中一个作业会一直处于 "待定 "状态,直到第一个作业运行完毕。如果你只是在为一个小团队设置运行器,你可能可以在同一时间只允许一个作业运行。随着团队的壮大,你会想尝试使用并发性配置选项。

  1. concurrent - 限制全局范围内有多少作业可以在所有运行器上并发运行。
  2. limit - 适用于单个运行器,限制可以并发处理的作业数量。默认值是 ,这意味着不应用限制。0
  3. request_concurrency - 适用于单个运行者,限制新作业的并发请求数。默认值是 。1

在我们更新并发选项之前,添加一个新的运行器。

$ docker-compose exec gitlab-runner-container \
    gitlab-runner register \
    --non-interactive \
    --url  \
    --registration-token  \
    --executor docker \
    --description "Sample Runner 2" \
    --docker-image "docker:stable" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

docker-compose exec gitlab-runner-container \
    gitlab-runner register \
    --non-interactive \
    --url https://gitlab.com/ \
    --registration-token hvdSfcc1EmHLpK1Qds7s \
    --executor docker \
    --description "Sample Runner 2" \
    --docker-image "docker:stable" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

然后,像这样更新config/config.toml

concurrent = 4                # NEW
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "Sample Runner 1"
  url = "https://gitlab.com/"
  token = "yK2DqWMQB1CqPsRx6gwn"
  executor = "docker"
  limit = 2                   # NEW
  request_concurrency = 2     # NEW
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0

[[runners]]
  name = "Sample Runner 2"
  url = "https://gitlab.com/"
  token = "qi-b3gFzVaX3jRRskJbz"
  limit = 2                 # NEW
  request_concurrency = 2   # NEW
  executor = "docker"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
    [runners.cache.azure]
  [runners.docker]
    tls_verify = false
    image = "docker:stable"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0

现在,我们可以在两个运行器上并发运行四个作业,每个运行器有两个子进程。

重新启动。

$ docker-compose exec gitlab-runner-container gitlab-runner restart

通过运行四个作业来测试它。

请记住,如果你正在构建和测试Docker镜像,你最终会耗尽磁盘空间。因此,定期删除Docker主机上所有未使用的镜像和容器是个好主意。

示例crontab。

@weekly /usr/bin/docker system prune -f

--

这就是了!

不要忘了取消运行器的注册。

$ docker-compose exec gitlab-runner-container gitlab-runner unregister --all-runners

然后,回到你的本地机器上,把机器/液滴关闭。

$ docker-machine rm runner-node