一次京东云NAT网络下的gitlab-ci错误排查

一次京东云NAT网络下的gitlab-ci错误排查_第1张图片
HY-g-hkmwytp9590861.png

背景

由于历史原因,我们是京东云的大客户,关于京东云,可以说是又爱又恨,我们作为早期客户,没少踩坑,随着京东云这几年逐步走向正轨,产品也是越来越稳定,功能也越来越丰富,衷心的希望我们的合作能够一直保持。

我年初加入公司后,发现公司IT建设较落后,所以下大力气开始进行改造,将代码从svn迁移到git,是所有后续工作的基础,这里我选用了自建gitlab作为git管理工具,并为每个项目编写了gitlab-ci,用来做提交代码后的编译检查。

由于种种原因,最开始只有一台服务器,除了gitlab,还有跑runner、jenkins、registry、sentry等工具和服务,虽然都是通过docker架设的,但稳定性也是相当让人堪忧,所以最近将gitlab和runner进行了迁移。

为了拆分这些服务,我在京东云上搭建了基于nat的vpc,服务器A作为nat网关暴露在公网上,其他服务访问外网均通过服务器A完成,外部访问内网服务则全通过服务器A的反向代理实现,gitlab是一台内网独立的ecs,runner也是独立的一台ecs。反向代理、ssh tunnel全部配置完成后,基本访问和提交代码全都正常,但是runner注册后,问题来了。

问题

我的gitlab-ci用的runner,是通过如下配置进行注册的:

docker run --rm -v /root/gitlab-runner/${name}/config:/etc/gitlab-runner gitlab/gitlab-runner register \
  --non-interactive \
  --executor "docker" \
  --docker-image "alpine:latest" \
  --url "http://xxxxx/" \
  --registration-token "token" \
  --description "${name}" \
  --tag-list "${taglist}" \
  --run-untagged="true" \
  --locked="false"

我的gitlab-ci是这样写的:

image: maven:3.6.0-jdk-8

stages:
  - build
  - test

variables:
  MAVEN_CLI_OPTS: "-s .m2/settings.xml --batch-mode"

cache:
  paths:
    - .m2/repository/
    - target/

build:
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

test:
  stage: test
  script:
    - mvn $MAVEN_CLI_OPTS test -Ptest -DargLine="-Djdk.net.URLClassPath.disableClassPathURLCheck=true"

其中settings.xml文件里配置了阿里云的maven仓库镜像。

当在runner中执行mvn命令时,会发现所有的jar包依赖,均不能下载,全部卡住。当我把阿里云的maven镜像换成官方中央仓库的地址,一切正常。经过反复实验,发现阿里云的maven镜像用的是https,而官方中央仓库用的是http。

接着curl了https://www.baidu.com,也是卡住。随便找了个jar包,通过wget下载,http的可以正常下载,而https的全都卡住,telnet了443端口,是通的。由此,基本可以判断为证书检查出了问题,wget加上–no-check-certificate参数,一切正常,看来果然是证书的问题。

问题:京东云nat网络下,内网ecs的docker容器内,访问https的资源,会有证书问题,导致资源不能正常加载,一直卡住。使用mvn命令,没有任何错误提示,其他命令没有尝试。

解决方法

通过现象,基本可以判断为docker的网络环境配置的问题,知道了原因,解决起来就简单了。

既然是网络问题,那就让docker直接接在主机的网络上,不使用默认的bridge网络。

停止所有runner,修改注册runner的脚本,增加–docker-network-mode “host”,如下:

docker run --rm -v /root/gitlab-runner/${name}/config:/etc/gitlab-runner gitlab/gitlab-runner register \
  --non-interactive \
  --executor "docker" \
  --docker-image "alpine:latest" \
  --docker-network-mode "host" \
  --url "http://xxxxxx/" \
  --registration-token "token" \
  --description "${name}" \
  --tag-list "${taglist}" \
  --run-untagged="true" \
  --locked="false"

重新注册runner后,阿里云的jar包依赖终于可以正常下载了:)

总结

这个问题着实让我慌了一下,google了半天,一直没有找到解法,由于网络知识的匮乏,导致一开始就没往网络这方面想,直到咨询了京东云的技术人员,才知道可能是网络的问题。

事实证明,解决任何问题,应该先怀疑自己,再怀疑其他,尤其是成熟的技术和应用。很多事情,往往都是源于自己的无知。

至于为什么多层nat下会出现证书问题,是京东云的问题,还是docker默认的bridge网络问题?还是二者一结合就这样?这恐怕得等把nat学明白了再下结论了。

你可能感兴趣的:(一次京东云NAT网络下的gitlab-ci错误排查)