Post

GitLab Runner 与流水线实践:本地 SSH 克隆代码

从安装配置到编写 .gitlab-ci.yml,并用本地 SSH 访问私有仓库。含 PlantUML 流程图与常见问题。

GitLab Runner 与流水线实践:本地 SSH 克隆代码

概览

这篇文章带你完成以下目标:

  • 安装并注册 GitLab Runner(Shell/Docker executor)。
  • 编写 .gitlab-ci.yml 运行基本流水线(构建/测试/部署)。
  • 使用本机 SSH 私钥让 Runner 克隆私有仓库。
  • 常见问题与排查清单。

流程图(PlantUML)

GitLab CI Pipeline OverviewDeveloperDeveloperGitLab ServerGitLab ServerRunnerRunnerRepo (SSH)Repo (SSH)Push/PR triggersAssign jobgit clone via SSHbuild / test / packagejob status & artifactspipeline result

安装与注册 Runner

以下以 Linux 为例,Docker 方式最通用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1) 安装 Docker(略)并拉取官方镜像
docker pull gitlab/gitlab-runner:latest

# 2) 启动 Runner 容器(挂载配置与缓存目录)
docker run -d --name gitlab-runner \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  -v /srv/gitlab-runner/cache:/cache \
  --restart always gitlab/gitlab-runner:latest

# 3) 注册(拿到 GitLab 项目或实例提供的 URL 和 Token)
docker exec -it gitlab-runner gitlab-runner register \
  --url https://gitlab.example.com/ \
  --registration-token REG_TOKEN \
  --executor docker \
  --description "qqqqiang-runner" \
  --tag-list "docker,ci" \
  --docker-image alpine:3.20

如果使用 Shell executor(直接在主机执行),可以:

1
2
3
4
5
6
7
8
sudo curl -L --output /usr/local/bin/gitlab-runner \
  https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner register --url https://gitlab.example.com/ --registration-token REG_TOKEN \
  --executor shell --description "qqqqiang-shell"
sudo gitlab-runner start

基本 .gitlab-ci.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
stages: [prepare, build, test]

variables:
  GIT_SUBMODULE_STRATEGY: recursive

default:
  tags: [docker]
  image: alpine:3.20

prepare:
  stage: prepare
  script:
    - echo "Preparing..."

build:
  stage: build
  script:
    - echo "Building..."

test:
  stage: test
  script:
    - echo "Running tests..."

让 Runner 使用本地 SSH 克隆代码

目标:在 Runner 执行 git clone git@gitlab.example.com:group/project.git 时,复用主机已有的私钥与 known_hosts

Docker executor 方案

  • 将主机的 ~/.ssh 映射到 Runner 容器配置中,使作业内可用。
  • 或者在 config.toml 中使用 volumes 映射,或在 before_script 里注入密钥。

示例:编辑 /srv/gitlab-runner/config/config.toml(容器挂载的配置路径),为对应的 runner 添加:

1
2
3
4
5
6
7
8
9
10
11
[[runners]]
  name = "qqqqiang-runner"
  executor = "docker"
  [runners.docker]
    image = "alpine:3.20"
    tls_verify = false
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    shm_size = 0
    volumes = ["/cache", "/home/qiang/.ssh:/root/.ssh:ro"]

注意:

  • 容器默认以 root 执行,挂载到 /root/.ssh;若使用自定义用户,请对应调整路径。
  • 需要保证私钥权限为 600,known_hosts 中已存在 GitLab 域名的指纹:
1
2
ssh-keyscan -H gitlab.example.com >> ~/.ssh/known_hosts
chmod 600 ~/.ssh/id_rsa ~/.ssh/id_ed25519

.gitlab-ci.yml 中,确保仓库地址为 SSH 形式并禁用凭证清理:

1
2
3
4
5
6
variables:
  GIT_STRATEGY: fetch
  GIT_CHECKOUT: "true"

before_script:
  - echo "Using SSH to clone..."

Shell executor 方案

  • Shell 直接使用主机环境,确保运行用户可访问 ~/.ssh
  • 将项目的 origin 改为 SSH 地址,并在 Runner 机器上能无密码 ssh git@gitlab.example.com

Windows 环境(系统服务用户)

在 Windows 上,GitLab Runner 作为服务运行时使用的是 SYSTEM(systemprofile)用户,其默认家目录位于:

  • C:\Windows\System32\config\systemprofile

为了让 Runner 能使用你的本地 SSH 配置与私钥,请将 .ssh 目录复制到上述路径,例如:

1
2
3
4
5
6
# 假设你当前用户的 .ssh 位于 C:\Users\<YourUser>\.ssh
Copy-Item -Path "C:\Users\<YourUser>\.ssh" -Destination "C:\Windows\System32\config\systemprofile" -Recurse

# 确认权限(至少 key 文件仅系统/管理员可读)
icacls "C:\Windows\System32\config\systemprofile\.ssh" /inheritance:r
icacls "C:\Windows\System32\config\systemprofile\.ssh\id_rsa" /grant SYSTEM:R

如果 Runner 服务配置为以某个特定用户运行(非 SYSTEM),则应将 .ssh 放置在该用户的家目录下(如 C:\Users\runner_user\.ssh),并确保权限正确。

常见问题

  • 权限问题:Permission denied (publickey) → 检查私钥类型是否匹配 GitLab 公钥、文件权限是否为 600。
  • known_hosts 缺失:首次连接需 ssh-keyscan,或手动交互添加(CI 内建议静默添加)。
  • 子模块拉取失败:子模块也要使用 SSH 地址,或在 GIT_SUBMODULE_STRATEGY 设为 recursive
  • 多 Runner 标签:确保 .gitlab-ci.ymltags 与注册时配置一致。

一个更完整的流水线例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
stages: [prepare, lint, build, test, package]

default:
  image: alpine:3.20
  tags: [docker]

variables:
  GIT_SUBMODULE_STRATEGY: recursive

before_script:
  - apk add --no-cache git openssh
  - git --version

lint:
  stage: lint
  script:
    - echo "lint pass"

build:
  stage: build
  script:
    - echo "do build"

test:
  stage: test
  script:
    - echo "run tests"

package:
  stage: package
  script:
    - echo "make artifacts"
  artifacts:
    paths:
      - dist/
    expire_in: 1 week

小结

通过在 Runner 中映射或配置 ~/.ssh,即可安全地使用本地 SSH 凭据克隆私有仓库;同时合理设计 .gitlab-ci.yml 的阶段、变量与镜像,能让流水线更稳定可靠。

欢迎在评论区反馈你的场景与问题,我会持续补充案例与排查指南。

This post is licensed under CC BY 4.0 by the author.