当使用 GitLab Auto DevOps 构建应用程序并将其从我的存储库部署到 microk8s 时,构建作业通常需要很长时间才能运行,最终会超时。 99% 的情况下都会出现此问题,但有些构建会运行。通常,构建会在构建脚本中的不同时间停止。
这些项目不包含
.gitlab-ci.yml
文件,并完全依赖 Auto DevOps 功能来发挥其魔力。
对于 Spring Boot/Java 项目,通过 Gradle 包装器下载 Gradle 时构建通常会失败,有时在下载依赖项本身时也会失败。错误消息非常模糊,根本没有帮助:
Step 5/11 : RUN /bin/herokuish buildpack build
---> Running in e9ec110c0dfe
-----> Gradle app detected
-----> Spring Boot detected
The command '/bin/sh -c /bin/herokuish buildpack build' returned a non-zero code: 35
有时,如果幸运的话,错误会有所不同:
Step 5/11 : RUN /bin/herokuish buildpack build
---> Running in fe284971a79c
-----> Gradle app detected
-----> Spring Boot detected
-----> Installing JDK 11... done
-----> Building Gradle app...
-----> executing ./gradlew build -x check
Downloading https://services.gradle.org/distributions/gradle-7.0-bin.zip
..........10%...........20%...........30%..........40%...........50%...........60%...........70%..........80%...........90%...........100%
To honour the JVM settings for this build a single-use Daemon process will be forked. See https://docs.gradle.org/7.0/userguide/gradle_daemon.html#sec:disabling_the_daemon.
Daemon will be stopped at the end of the build
> Task :compileJava
> Task :compileJava FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileJava'.
> Could not download netty-resolver-dns-native-macos-4.1.65.Final-osx-x86_64.jar (io.netty:netty-resolver-dns-native-macos:4.1.65.Final)
> Could not get resource 'https://repo.maven.apache.org/maven2/io/netty/netty-resolver-dns-native-macos/4.1.65.Final/netty-resolver-dns-native-macos-4.1.65.Final-osx-x86_64.jar'.
> Could not GET 'https://repo.maven.apache.org/maven2/io/netty/netty-resolver-dns-native-macos/4.1.65.Final/netty-resolver-dns-native-macos-4.1.65.Final-osx-x86_64.jar'.
> Read timed out
对于 React/TypeScript 问题,症状相似,但错误本身以不同的方式表现:
[INFO] Using npm v8.1.0 from package.json
/cnb/buildpacks/heroku_nodejs-npm/0.4.4/lib/build.sh: line 179: /layers/heroku_nodejs-engine/toolbox/bin/yj: Permission denied
ERROR: failed to build: exit status 126
ERROR: failed to build: executing lifecycle: failed with status code: 145
该问题似乎主要发生在 GitLab 运行器本身部署在 Kubernetes 中时。 microk8s 使用 Project Calico 来实现虚拟网络。
什么给予?为什么错误消息没有帮助?有没有办法打开详细的构建日志或调试构建步骤?
这似乎是由 Calico 网络层和 Docker 网络配置之间不兼容的 MTU 设置引起的网络问题(并且无法正确自动配置 MTU?)当 MTU 值不匹配时,网络数据包会碎片化并且 Docker 运行程序无法完成 TLS 握手。据我了解,这只影响 DIND (docker-in-docker) 运行者。
即使发现这一点也需要克服一些困难。你必须:
kubectl exec
进入当前/活动的 GitLab runner pod DOCKER_HOST
环境变量的正确值(例如,通过 grep /proc/$pid/environ
。很可能,这将是 tcp://localhost:2375
。docker
客户端使用的值:export DOCKER_HOST=tcp://localhost:2375
docker ps
,然后docker exec
进入实际的 CI 作业容器执行
microk8s kubectl get -n kube-system cm calico-config -o yaml
并查找
veth_mtu
值,该值很可能会设置为 1440
。 DIND 使用相同的 MTU,因此无法发送或接收某些网络数据包(每个虚拟网络需要向网络数据包添加自己的标头,这会在每一层添加几个字节)。
天真的修复方法是将 Calico 设置更改为更高或更低的值,但不知何故,即使在 Calico 部署之后,这也没有真正起作用。此外,该值似乎会不时地重置为原始值;可能是由 microk8s 自动更新引起的(以 Snap 的形式提供)。
那么什么是真正有效且永久的解决方案呢?通过编写自定义
.gitlab-ci.yml
文件并简单地包含 Auto DevOps 模板,可以覆盖 Auto DevOps 的 DIND 设置:
build:
services:
- name: docker:20.10.6-dind # make sure to update version
command: ['--tls=false', '--host=tcp://0.0.0.0:2375', '--mtu=1240']
include:
- template: Auto-DevOps.gitlab-ci.yml
build.services
定义是从 Jobs/Build.gitlab-ci
模板复制的,并使用附加 --mtu
选项进行扩展。
到目前为止,我通过将 DIND MTU 设置为 1240 获得了很好的经验,这比 Calico 的 MTU 低 200 字节。作为额外的好处,它不会影响任何其他 Pod 的网络设置。对于 CI 构建,我可以忍受非最佳网络设置。
参考资料: