最后更新于
在 PVE 中配置基于 Docker 的 GitLab Runner
环境准备
为了更好的隔离性,我在 PVE 中创建了一个新的 LXC 容器专门运行 GitLab Runner。这里使用了一个预装 Docker 的 LXC 模板,创建完成后把容器重命名为 gitlab-runner-1
:
pct set <VMID> --hostname gitlab-runner-1
GitLab Runner 配置
1. 注册 Runner
进入 https://yourgitlabhost/admin/runners , 点击 “New instance runner”
- 标签随意,比如 linux, shared
- 如果希望这个runner 可以被所有gitlab job 使用,勾选“Run untagged jobs”
- 点击 Create runner
之后会进入一个注册 runner 页面
- 点击1 复制脚本进入lxc 安装gitlab runner
- 安装完成1之后,复制2的命令注册服务
2. 选择 Executor 类型
在注册过程中需要选择 executor 类型。这里我选择了 docker而不是默认的shell,因为它可以确保每次构建环境的独立性,而且部署也比较方便。反过来如果是shell就不能用pipeline里面的image 字段,而且需要确保script里面的调用命令都在机器上安装过,太麻烦了。GitLab Runner 支持的 executor 的详细说明可以查看官方文档。
Docker 构建方案对比
在 Docker 环境中构建 Docker 镜像时,GitLab 提供了几种方案:
名称 | 说明 | 安全性 | 方便程度 | 性能 | 已知问题 |
---|---|---|---|---|---|
Docker-in-Docker | 在容器内运行完整的 Docker 环境,通过 TCP 通信 | 高(完全隔离) | 中等(需要配置特权模式和证书) | 低(需要额外的 Docker daemon) | 已知问题 |
Docker socket binding | 直接使用宿主机的 Docker daemon | 低(可以访问宿主机 Docker) | 高(只需挂载 socket) | 高(直接使用宿主机资源) | 已知问题 |
Daemon-less 方案 (Kaniko/Buildah) | 不需要 Docker daemon 的容器构建工具 | 高(无需特权) | 中等(需要配置凭证和缓存) | 中等(构建性能取决于配置) | - |
方案选择说明
最终我选择了 Docker socket binding 方案,主要基于以下考虑:
- 代码可信度:GitLab 仓库中的代码都是自己信任且熟悉的,运行恶意容器的风险较低
- 环境隔离:Runner 本身运行在无特权的 LXC 容器中,提供了额外的安全层面
3. Runner 配置
Runner 的完整配置说明可以参考官方文档,Docker 相关的具体配置在这里。
配置文件示例
配置文件位置:/etc/gitlab-runner/config.toml
concurrent = 1check_interval = 0connection_max_age = "15m0s"shutdown_timeout = 0
[session_server] session_timeout = 1800
[[runners]] name = "lxc docker" url = "https://yourgitlaburl/" id = 11 token = "yoyrgitlabtoken" token_obtained_at = 2024-11-25T13:57:14Z token_expires_at = 0001-01-01T00:00:00Z executor = "docker" [runners.custom_build_dir] [runners.cache] MaxUploadedArchiveSize = 0 [runners.cache.s3] [runners.cache.gcs] [runners.cache.azure] [runners.docker] image = "docker:24.0.5" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false volumes = ["/cache","/var/run/docker.sock:/var/run/docker.sock"] shm_size = 0 network_mtu = 0
主要修改:
- volumes 增加了
/var/run/docker.sock
修改完成后,重启 Runner:
sudo gitlab-runner restart
4. CI/CD 配置
Docker 认证配置
GitLab 提供了三种认证方式,最简单的是使用环境变量:
$DOCKER_REGISTRY_PASS
:Docker 密码$DOCKER_REGISTRY
:Docker 仓库$DOCKER_REGISTRY_USER
:Docker 账号
CI/CD 配置示例
variables: # GitLab 容器仓库的地址 IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
stages: - build
build_image: image: docker:latest # 只在这个任务中使用 docker image stage: build script: - docker info # 测试 docker 连接 - echo "Testing Docker build..." - echo "CI_REGISTRY=$CI_REGISTRY" - echo "CI_REGISTRY_IMAGE=$CI_REGISTRY_IMAGE" - echo "CI_COMMIT_SHA=$CI_COMMIT_SHA" - echo "IMAGE_TAG=$IMAGE_TAG" # 登录到 GitLab 容器仓库 - echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin # 使用缓存和多个标签来优化构建过程 - >- docker build --cache-from "$CI_REGISTRY_IMAGE:latest" --build-arg BUILDKIT_INLINE_CACHE=1 -t "$IMAGE_TAG" -t "$CI_REGISTRY_IMAGE:latest" . # 推送镜像 - docker push "$IMAGE_TAG" - docker push "$CI_REGISTRY_IMAGE:latest" - echo "Docker build and push successful!" only: - main
后续
- 增加定期清理硬盘的任务。docker 构建出来的image在runner上面并不会自动删除,可以增加一个定期删除docker image的脚本,具体可以参考这里