使用代理运行极狐GitLab Runner
这个指南的目的是让带有 Docker 执行器的极狐GitLab Runner 通过代理工作。
开始前请确保您已经在同一台机器上安装了 Docker 和极狐GitLab Runner。
配置 CNTLM
CNTLM 是一个 Linux 代理,可以用作本地代理,并且与手动到处添加代理详情相比,有两个主要的优势:
- 只有一个需要更改证书的来源。
- 从 Docker Runner 无法访问证书。
假设您已经安装了 CNTLM, 您需要首先对其进行配置。
使 CNTLM 侦听 docker0
接口
为了额外的安全并且保护服务器不受外部影响,您可以绑定 CNTLM,使其在 docker0
接口上侦听,这个接口拥有从容器内部可以访问的 IP。
如果您让 Docker 主机上的 CNTLM 仅绑定到这个地址,Docker 容器就能够进行访问,但是外部则无法访问。
-
找到 Docker 使用的 IP:
ip -4 -oneline addr show dev docker0
一般是
172.17.0.1
,我们将它称为docker0_interface_ip
。 -
打开 CNTLM (
/etc/cntlm.conf
) 的配置文件。输入您的用户名、密码、域和代理主机,并配置您从上一步骤中获取到的Listen
IP 地址。 应如下所示:Username testuser Domain corp-uk Password password Proxy 10.0.0.41:8080 Proxy 10.0.0.42:8080 Listen 172.17.0.1:3128 # Change to your docker0 interface IP
-
保存更改并重启服务:
sudo systemctl restart cntlm
为下载镜像配置 Docker
根据 Docker 文档中的指示了解如何使用代理。
服务文件应如下所示:
[Service]
Environment="HTTP_PROXY=http://docker0_interface_ip:3128/"
Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
向极狐GitLab Runner 配置中添加代理变量
代理变量同样也需要添加到极狐GitLab Runner 配置中,这样它才能够获取使用代理的极狐GitLab 所分配的构建。
基本和上面所述的向 Docker 服务添加代理一样:
-
为
gitlab-runner
服务创建 systemd drop-in 目录:mkdir /etc/systemd/system/gitlab-runner.service.d
-
创建名为
/etc/systemd/system/gitlab-runner.service.d/http-proxy.conf
的文件,该文件添加HTTP_PROXY
环境变量:[Service] Environment="HTTP_PROXY=http://docker0_interface_ip:3128/" Environment="HTTPS_PROXY=http://docker0_interface_ip:3128/"
-
保存文件并刷新更改:
systemctl daemon-reload
-
重启极狐GitLab Runner:
sudo systemctl restart gitlab-runner
-
验证配置已加载:
systemctl show --property=Environment gitlab-runner
您应该能看到:
Environment=HTTP_PROXY=http://docker0_interface_ip:3128/ HTTPS_PROXY=http://docker0_interface_ip:3128/
向 Docker 容器中添加代理
您在注册 Runner 后,您或许会想将您的代理设置传播到 Docker 容器(例如,git clone
)。
为此,您需要编辑 /etc/gitlab-runner/config.toml
并向 [[runners]]
部分添加以下内容:
pre_clone_script = "git config --global http.proxy $HTTP_PROXY; git config --global https.proxy $HTTPS_PROXY"
environment = ["https_proxy=http://docker0_interface_ip:3128", "http_proxy=http://docker0_interface_ip:3128", "HTTPS_PROXY=docker0_interface_ip:3128", "HTTP_PROXY=docker0_interface_ip:3128"]
其中 docker0_interface_ip
是 docker0
接口的 IP 地址。
使用 dind 服务时的代理设置
当使用 Docker-in-Docker 执行器 (dind) 时,或许有必要在 NO_PROXY
环境变量中指定 docker:2375,docker:2376
。端口是必须的,否则会禁用 docker push
。
dind 的 dockerd
和本地 docker
客户端(https://hub.docker.com/_/docker/ 中所描述的)
之间的通信使用根的 Docker 配置中的代理变量。
为进行此配置,您需要编辑 /root/.docker/config.json
,包含完整的代理配置,例如:
{
"proxies": {
"default": {
"httpProxy": "http://proxy:8080",
"httpsProxy": "http://proxy:8080",
"noProxy": "docker:2375,docker:2376"
}
}
}
为将设置传递到 Docker 执行器的容器中,您还需要在容器中创建 $HOME/.docker/config.json
。它可能会被创建为 .gitlab-ci.yml
中的 before_script
脚本,例如:
before_script:
- mkdir -p $HOME/.docker/
- 'echo "{ \"proxies\": { \"default\": { \"httpProxy\": \"$HTTP_PROXY\", \"httpsProxy\": \"$HTTPS_PROXY\", \"noProxy\": \"$NO_PROXY\" } } }" > $HOME/.docker/config.json'
或者在被影响的 gitlab-runner
(/etc/gitlab-runner/config.toml
)的配置中:
[[runners]]
pre_build_script = "mkdir -p $HOME/.docker/ && echo \"{ \\\"proxies\\\": { \\\"default\\\": { \\\"httpProxy\\\": \\\"$HTTP_PROXY\\\", \\\"httpsProxy\\\": \\\"$HTTPS_PROXY\\\", \\\"noProxy\\\": \\\"$NO_PROXY\\\" } } }\" > $HOME/.docker/config.json"
"
的额外级别,因为创建了带有 Shell 的 JSON 文件,这个 Shell 被指定为
TOML 文件内的单个字符串。
因为它不是 YAML,所以不要转义 :
。请注意,如果需要扩展 NO_PROXY
列表,通配符 *
仅对后缀生效,对前缀或 CIDR 标注都无效。
详情请参见
https://github.com/moby/moby/issues/9145
和
https://unix.stackexchange.com/questions/23452/set-a-network-range-in-the-no-proxy-environment-variable。
处理速率限制请求
极狐GitLab 实例或许会通过反向代理进行使用,这些反向代理对 API 请求有速率限制,以防滥用。极狐GitLab Runner 向 API 发送多个请求并可以检查这些速率限制。
因此,极狐GitLab Runner 用以下逻辑处理速率限制场景:
- 收到 429 - TooManyRequests 的响应码。
- 为
RateLimit-ResetTime
Header 检查响应 Header。RateLimit-ResetTime
Header 应该有一个值,并且是有效的 HTTP Date (RFC1123),例如Wed, 21 Oct 2015 07:28:00 GMT
。- 如果 Header 存在且是一个有效的值,Runner 会等到特定时间并发送另一个请求。
- 如果 Header 存在,但不是一个有效的日期,会使用 1 分钟的回退。
- 如果 Header 不存在,不会采取额外动作,且会返回响应错误。
- 上述过程重复 5 次,会返回
gave up due to rate limit
错误。
RateLimit-ResetTime
区分大小写,因为所有的 Header Key 都要通过
http.CanonicalHeaderKey
功能运行。