一、问题现象描述

当你的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集群环境

六、注意事项清单

  1. 证书更新后必须重启GitLab服务:gitlab-ctl restart nginx
  2. 跨版本升级时注意API兼容性(特别是14.x到15.x的升级)
  3. 生产环境避免使用clone_url覆盖设置,容易导致地址解析异常
  4. 定期清理Runner的陈旧日志:find /var/log/gitlab-runner/ -mtime +7 -delete

七、总结与展望

通过本文的排查流程,我们建立了从物理层到应用层的完整诊断框架。建议企业用户建立以下长效机制:

  • 搭建Runner健康度监控仪表盘(Prometheus+Granfana)
  • 实施配置变更审核流程(GitOps最佳实践)
  • 定期进行灾难恢复演练(模拟服务器宕机场景)