一、问题现象描述
当你的GitLab Runner运行时突然报错"ERROR: Failed to connect to...",就像快递员找不到仓库地址一样令人抓狂。典型的错误场景包括:
- CI/CD流水线突然中断
- Runner注册成功但无法执行任务
- 间歇性出现
x509: certificate signed by unknown authority
等证书错误 - 网络超时提示
dial tcp 10.0.0.1:443: i/o timeout
二、实战环境说明
技术栈:Docker Executor + GitLab CE 15.4 + Self-Hosted Runner 15.4.0 测试环境:阿里云ECS(CentOS 7.9)自建GitLab服务
三、六步排查法详解
1. 基础网络诊断(TCP层)
nc -zv gitlab.example.com 443
telnet 10.0.0.1 443
# 查看DNS解析是否正常(示例输出)
$ dig +short gitlab.example.com
10.0.0.1
# 追踪路由路径(适合跨机房情况)
mtr --report gitlab.example.com
2. 证书验证穿透(TLS层)
# 使用openssl验证证书链(重点看Verify return code)
openssl s_client -connect gitlab.example.com:443 -showcerts
# 预期正常输出结尾示例
Verify return code: 0 (ok)
# 异常情况处理建议:
# 返回码18(自签名证书)需配置CA证书
# 返回码20(证书过期)需更新服务器证书
3. Runner配置文件解析(关键参数验证)
查看/etc/gitlab-runner/config.toml
配置文件:
[[runners]]
name = "prod-runner"
url = "https://gitlab.example.com" # 必须与浏览器访问地址完全一致
token = "glrt-xxxxxx" # 注意区分注册令牌与运行令牌
executor = "docker"
[runners.docker]
image = "alpine:latest"
volumes = ["/cache"]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
4. 容器网络模式验证(Docker特有)
当使用Docker executor时,特别注意网络模式:
# 错误的桥接模式可能导致容器无法访问宿主机网络
docker run --network host -it alpine ping gitlab.example.com
# 正确做法:在config.toml中配置extra_hosts
[[runners]]
[runners.docker]
extra_hosts = ["gitlab.example.com:10.0.0.1"]
5. 防火墙规则深度检查
使用firewalld时的典型配置示例:
# 查看当前放行端口(确保443/80端口开放)
firewall-cmd --list-ports
# 永久开放Runner通信端口(包括出站规则)
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --reload
# 检查iptables规则链(注意FORWARD链是否被拦截)
iptables -L -n -v
6. 服务端日志关联分析
查看GitLab服务器的Nginx日志:
tail -f /var/log/nginx/gitlab_access.log
# 典型错误日志示例:
10.0.0.2 - - [15/Jul/2023:14:23:45 +0800] "POST /api/v4/jobs/request HTTP/1.1" 502 157 "-" "gitlab-runner 15.4.0 (15.4.0)"
四、三大典型场景解决方案
场景1:自签名证书问题
生成并部署CA证书:
# 生成CA证书(有效期10年)
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \
-keyout gitlab.key -out gitlab.crt \
-subj "/CN=gitlab.example.com" -nodes
# 将证书添加到系统信任链
sudo cp gitlab.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
场景2:跨云网络配置
阿里云与AWS的VPC对等连接配置要点:
# 配置云企业网(CEN)路由策略
# 确保10.0.0.0/24(GitLab服务器)与172.16.0.0/16(Runner集群)互通
# 在Runner配置中设置HTTP代理
export HTTP_PROXY=http://proxy.example.com:3128
gitlab-runner register --url https://gitlab.example.com \
--registration-token glrt-xxxx
场景3:高并发下的连接耗尽
优化Runner的并发参数:
concurrent = 10 # 根据CPU核心数调整
check_interval = 3 # 请求间隔不宜过短
[[runners]]
pre_clone_script = "sysctl -w net.core.somaxconn=65535"
[runners.docker]
shm_size = "2gb" # 防止容器内存不足
五、技术方案对比分析
方案类型 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
HTTP代理 | 快速解决网络隔离问题 | 增加单点故障风险 | 企业内网穿透 |
自签名证书 | 免去证书购买成本 | 需要维护CA信任链 | 测试/内部环境 |
VPC对等连接 | 高速稳定 | 云服务商收费较高 | 生产环境跨云部署 |
容器网络定制 | 灵活控制网络策略 | 增加运维复杂度 | Kubernetes集群环境 |
六、注意事项清单
- 证书更新后必须重启GitLab服务:
gitlab-ctl restart nginx
- 跨版本升级时注意API兼容性(特别是14.x到15.x的升级)
- 生产环境避免使用
clone_url
覆盖设置,容易导致地址解析异常 - 定期清理Runner的陈旧日志:
find /var/log/gitlab-runner/ -mtime +7 -delete
七、总结与展望
通过本文的排查流程,我们建立了从物理层到应用层的完整诊断框架。建议企业用户建立以下长效机制:
- 搭建Runner健康度监控仪表盘(Prometheus+Granfana)
- 实施配置变更审核流程(GitOps最佳实践)
- 定期进行灾难恢复演练(模拟服务器宕机场景)