如何为 Gitlab 运行器启用通过 SSH 克隆?
Posted
技术标签:
【中文标题】如何为 Gitlab 运行器启用通过 SSH 克隆?【英文标题】:How do I enable cloning over SSH for a Gitlab runner? 【发布时间】:2017-01-05 14:42:30 【问题描述】:我在我的 Windows Gitlab 运行器上通过 HTTP 克隆大型存储库时遇到了一些问题。我尝试了几种方法来进行浅克隆或禁用克隆压缩。还是没有运气。
通过 SSH 克隆相同的存储库作为一种临时解决方案非常有效,我想让它在我们的 Gitlab CI 流程中运行。
现在的问题是我不知道如何使用 SSH 作为 gitlab-multi-runner 的克隆方法。它似乎只是默认使用 HTTP,而我关于克隆的唯一选择是它是否会进行完整克隆或获取。
谁能解释我如何让克隆/获取通过 SSH 而不是 HTTP 在运行器上工作?
Gitlab 版本:GitLab 社区版 8.10.7
谢谢!
【问题讨论】:
此功能似乎确实存在一个问题 (233),但它似乎已在未实施的情况下关闭... 【参考方案1】:作为 gitlab 的新手,我已经设法解决了这个问题,因为我还没有找到改变默认克隆过程的内置方法(尽管here is a recent comment about how it can be done)。
通过disabling the automatic cloning process,您可以通过在before_script
中简单地编写自己的克隆过程来有效地完全覆盖其行为。仅出于示例目的,以下显示了如何为 HTTP 克隆完成此操作,但可以适用于 ssh
克隆 (if you're trying to use HTTP cloning you should use the built-in cloning process and the config.toml):
创建一个名为“gitlab-runner”的新用户并生成他们的用户身份验证令牌以供以后使用(或者在您的情况下,您将生成 ssh 密钥)。
通过在您的项目或组设置中添加以下变量来禁用运行器的克隆过程:.../settings/ci_cd
键:GIT_STRATEGY
值:无
在before_script
中克隆您的存储库,例如:
注意:这里是我在第 2 步中也配置的相关变量,而不是在脚本中硬编码它们:
RUNNER_TOKEN
:管理员“跑步者”菜单中列出了您尝试跑步的特定跑步者的“跑步者令牌”值。
GITLABRUNNER_USER_AUTH_TOKEN
:这是您在步骤 1 中生成的身份验证令牌。
进一步阅读:
您可以通过发出Deploy Keys 来避免上述假帐户 方法。或者,如果访问任何项目的安全隐患是一个问题,Deploy Tokens 是具有更多安全控制的替代方案。作为比较,see the docs:
部署密钥可在不相关或不属于同一组的项目之间共享。部署令牌属于项目或组。
部署密钥是您需要在自己的计算机上生成的 SSH 密钥。部署令牌由您的 GitLab 实例生成,并且仅提供给用户一次(在创建时)。
只要注册并启用部署密钥,它就有效。部署令牌可能具有时间敏感性,因为您可以通过为其设置过期日期来控制其有效性。
您无法使用部署密钥登录注册表,或对其执行读/写操作,但使用部署令牌可以做到这一点。 您需要一个 SSH 密钥对才能使用部署密钥,但不需要部署令牌。
【讨论】:
【参考方案2】:根据:
https://docs.gitlab.com/ee/ci/ssh_keys/README.html
你需要:
-
使用 ssh-keygen 创建新的 SSH 密钥对
将私钥作为秘密变量添加到项目中
在作业期间运行 ssh-agent 以加载私钥。
示例 gitlab_ci.yml:
before_script:
# Install ssh-agent if not already installed, it is required by Docker.
# (change apt-get to yum if you use a CentOS-based image)
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
# Run ssh-agent (inside the build environment)
- eval $(ssh-agent -s)
# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
- ssh-add <(echo "$SSH_PRIVATE_KEY")
# For Docker builds disable host key checking. Be aware that by adding that
# you are suspectible to man-in-the-middle attacks.
# WARNING: Use this only with the Docker executor, if you use it with shell
# you will overwrite your user's SSH config.
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
# In order to properly check the server's host key, assuming you created the
# SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines
# instead.
# - mkdir -p ~/.ssh
# - '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts'
【讨论】:
这并不能解决gitlab-runner
仍然试图通过 https 克隆 repo 的问题,即使配置了密钥也是如此。请参阅@ecoe answer 了解如何做到这一点。【参考方案3】:
我有一个类似的问题,需要通过 ssh 使用克隆:在非常旧的客户 linux 操作系统中使用 virtualbox
执行程序。我可以通过一些小的配置更改来解决它:
创建一个deploy key 以访问该项目。
强制执行克隆的用户帐户使用部署密钥。在我的virtualbox
案例中,我修改了在/etc/gitlab-runnner/config.toml
中为virtualbox
配置的用户的ssh 配置。
~/.ssh/config
Host gitlab.example.com
Preferredauthentications publickey
IdentityFile ~/.ssh/deploy-key
-
将运行器配置为通过
/etc/config.toml
中的ssh 执行克隆。
/etc/config.toml
[[runners]]
# [...]
environment = ["GIT_STRATEGY=none"]
pre_build_script = '''
# Fetching using ssh (via pre_build_script in config.toml)
if [ -d "$CI_PROJECT_DIR" ]; then rm -rf "$CI_PROJECT_DIR"; fi
mkdir -p "$CI_PROJECT_DIR"
cd "$CI_PROJECT_DIR"
git init
git remote add origin "ssh://git@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
git fetch origin "$CI_COMMIT_SHA"
git reset --hard FETCH_HEAD
'''
# [...]
以下是对 config.toml
的新增内容的细分:
GIT_STRATEGY=none
环境变量禁用运行器的内部 git 克隆机制。 (参见 CI/CD 参考的Git Strategy 部分)
pre_build_script
使用predefined CI/CD environment variables 执行实际克隆。就我而言,这是一个 bash 脚本,用于执行类似于 GIT_STRATEGY=fetch
可能执行的操作。
如果pre_build_script
是多行,则运行器的输出将只显示第一行。将注释作为第一行有助于增加运行器输出的清晰度。
pre_clone_script
此处未使用。它已被禁用,因为环境设置了 GIT_STRATEGY=none
。
【讨论】:
这很酷,几个月前我实际上一直在寻找这个解决方案,在你真正写之前:) 谢谢,@aledpardo!希望它对那里的一些人有用。 :)【参考方案4】:这对我有用,将其添加到您的 .gitlab-ci.yml 中
script:
- git remote set-url --push origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
这将在 .git/config 文件中设置您的推送 url,并且运行程序将在将代码推送回您的 git 存储库而不是使用 ci-token 的 url 时使用它。
【讨论】:
【参考方案5】:我在使用非常旧版本的 git 克隆 https 时遇到问题。我最终制作了一个模板,如果需要,它会克隆 repo,否则会获取最新的更改并将 repo 清理到裸露的干净状态。
您需要为所有涉及的 repos 设置部署密钥,包括同一 gitlab 服务器上的子模块。根据 Using SSH keys 文档设置 SSH 密钥,并将其添加为 Deploy Key 用于所有需要克隆的存储库。
这是可以随时扩展的模板:
.ssh_cloning:
variables:
GIT_STRATEGY: none
before_script:
# set up ssh keys for cloning
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
# clean the working directory
- |
if [ ! -d "$CI_PROJECT_DIR/.git" ]
then
mkdir -p "$CI_PROJECT_DIR"
cd "$CI_PROJECT_DIR"
git init
git remote add origin "ssh://git@$CI_SERVER_HOST/$CI_PROJECT_PATH.git"
fi
- cd "$CI_PROJECT_DIR"
# clone the project
- git fetch origin
- git checkout "$CI_COMMIT_SHA"
- git reset --hard HEAD
- git submodule update --init --recursive
# clean up files from the last build
- git clean -ffdx
您可以将它包含在其他工作中,类似这样(未经测试):
include:
- 'ssh_cloning.yml'
stages:
- build
do_git_stuff:
stage: build
extends: .ssh_cloning
script:
- git status
【讨论】:
以上是关于如何为 Gitlab 运行器启用通过 SSH 克隆?的主要内容,如果未能解决你的问题,请参考以下文章
具有私有 IP 的 AWS Gitlab Autoscale 运行器,不想启用公共 IP