konakona
Dream Afar.
konakona
Gitlab CICD 构建失败剖析 RPC failed原因

最近发现有的仓库在运行CICD时报出error: RPC failed; curl 18 transfer closed with outstanding read data remaining。而简单的项目(静态项目)则不会出现这个问题。

https://blog.img.crazyphper.com/2020/04/image-800x165.png
出问题的仓库的info

Curl 18错误是CURLE_PARTIAL_FILEvia),引发这个问题的可能性有:

  1. Git clone期间磁盘空间不足问题
  2. Git浅克隆有关
  3. Git+HTTP之间的通信问题,分块传输编码有关(我是这个原因)
  4. Nginx代理缓冲问题

推荐按照这个顺序排查问题。


一、Git Clone期间磁盘空间不足

在CICD中,Git Clone由Runner管理。因cache目录磁盘空间不足引起这个情况时,可以通过重新部署runner到一个更大的分区来解决。

由于我使用Helm安装的runner,因此修改yaml文件中RUNNER_CACHE_DIR RUNNER_BUILDS_DIR部分。

envVars:
     value: /data/k8s/gitlab/cache/runner
   - name: RUNNER_BUILDS_DIR
     value: /data/k8s/gitlab/cache/builds
   - name: DOCKER_DRIVER

其他安装方式请借鉴官网文档

二、Git浅克隆有关(Shallow cloning)

当遇到很大的仓库(比如几个G)时,我们必须优化Gitlab。

默认情况下,Gitlab和Runner始终执行完整克隆。就相当于把所有Tag、Branch这些都Clone到Runner cache中,对于文件体积大仓库或者历史冗长的仓库会造成很大的性能浪费。

理想情况下,应该始终使用GIT_DEPTH小于10的配置,这意味着Runner会执行浅克隆。

#gitlab-ci.yaml
variables:
  GIT_DEPTH: 10

其实每个人都遇到过这个报错了,这不仅仅是Gitlab上会遇到的。在加入一个Team时,准备Clone一个不断迭代的项目也会遇到,太常见了。

https://i.stack.imgur.com/0pq0u.png
在网上找了张图

值得一提的是,我使用Kubernetes运行Runner的环境是docker+machine,Gitlab默认采用GIT_STRATEGY: fetch策略对此是有局限性的,可以设置为GIT_STRATEGY: none策略,这会禁止Gitlab完成任何fetch和checkout命令,而原本的这些工作由你在gitlab-ci.yaml中做实现。

https://blog.img.crazyphper.com/2020/04/image-1-800x431.png
https://docs.gitlab.com/ee/ci/large_repositories/

只有在很大的仓库时才需要考虑这么做。

三、Git+HTTP之间的通信问题

如果以上2个方式依然无法解决报错,那么通常情况下,可以认定是由于分块传输引起,而处理这一事务的是Nginx。

https://blog.img.crazyphper.com/2020/04/image-2-800x125.png
依然报错

首先确保Nginx反代理配置不会产生多余的步骤,比如我一开始手残写成来proxy_pass https://:真实域名,结果造成来多次连接……修正后,我的配置如下:

#仅供参考

upstream app_name {
    server 127.0.0.1:8444;
}
server {
    listen 443  ssl;
    server_name git.app_name.com;
    #SSL
    ...
    client_max_body_size 0;

    location / {
	proxy_pass https://app_name;
    }
}

另一个要注意的就是磁盘空间大小变化。简单粗暴一点就是看df -h,可以用一个shell命令来观察:

while true; do df; sleep 1; done

通过观察CICD runner 克隆过程中,磁盘空间使用率的增加表明nginx正在进行某些操作。有可能是nginx响应缓冲proxy_buffering(默认开启)引发的问题,可以根据自己的理解判断是否将其关闭。

启用缓冲后,nginx会尽快从代理服务器收到响应,并将其保存到proxy_buffer_size和proxy_buffers指令设置的缓冲区中。如果整个响应都无法容纳到内存中,则可以将一部分响应保存到磁盘上的临时文件中。写入临时文件由proxy_max_temp_file_size和proxy_temp_file_write_size指令控制。

via: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering

除此意外,还可以检查Gitlab Rails应用程序的日志(production.log,独角兽日志)和Gitlab Workhouse日志。借此来找到有针对性的问题根源。

# 进入容器
docker exec -ti gitlab /bin/bash

# 输出日志
sudo gitlab-ctl tail 
# 查看某一个程序的日志
sudo gitlab-ctl tail gitlab-rails/api_json.log

本文至此结束,感谢大家的阅读,有描述不对的地方还望大家留言指出。

赞赏
首页      程序开发      Linux      DevOps      Gitlab CICD 构建失败剖析 RPC failed原因

团哥

文章作者

继续玩我的CODE,让别人说去。 低调,就是这么自信。

发表评论

textsms
account_circle
email

konakona

Gitlab CICD 构建失败剖析 RPC failed原因
最近发现有的仓库在运行CICD时报出error: RPC failed; curl 18 transfer closed with outstanding read data remaining。而简单的项目(静态项目)则不会出现这个问题。 出问题的仓库…
扫描二维码继续阅读
2020-04-15