Kubernetes 上的 GitLab Auto DevOps 挂起,网络超时,无法执行 yj
Posted
技术标签:
【中文标题】Kubernetes 上的 GitLab Auto DevOps 挂起,网络超时,无法执行 yj【英文标题】:GitLab Auto DevOps on Kubernetes hangs, network timeouts, cannot execute yj 【发布时间】:2022-01-21 15:29:40 【问题描述】:使用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 实现虚拟网络。
什么给了?为什么错误消息没有帮助?有没有办法打开详细的构建日志或调试构建步骤?
【问题讨论】:
【参考方案1】:这似乎是由于 Calico 网络层和 Docker 网络配置之间的 MTU 设置不兼容(以及无法正确自动配置 MTU?)导致的网络问题。 Docker 运行器无法完成 TLS 握手。据我了解,这只影响 DIND (docker-in-docker) 跑步者。
即使发现这一点也需要跳几圈。你必须:
-
启动 CI 管道并等待作业“挂起”
kubectl exec
进入当前/活动的 GitLab 运行器 pod
找出DOCKER_HOST
环境变量的正确值(例如,通过搜索/proc/$pid/environ
。很可能是tcp://localhost:2375
。
导出docker
客户端使用的值:export DOCKER_HOST=tcp://localhost:2375
docker ps
然后 docker exec
进入实际的 CI 作业容器
使用 ping 和其他工具查找正确的 MTU 值(但 MTU 是为了什么?Docker、Calico、OS、路由器……?)。使用 curl/openssl 验证(某些)https 站点是否会导致 DIND 容器内部出现问题。
执行
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 的 DIND 设置,并且只需包含 Auto DevOps 模板:
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 构建,我可以忍受非最佳网络设置。
参考资料:
https://gitlab.com/gitlab-org/gitlab-runner/-/issues/27300 https://projectcalico.docs.tigera.io/networking/mtu https://liejuntao001.medium.com/fix-docker-in-docker-network-issue-in-kubernetes-cc18c229d9e5 https://kb.netgear.com/19863/Ping-Test-to-determine-Optimal-MTU-Size-on-Router【讨论】:
以上是关于Kubernetes 上的 GitLab Auto DevOps 挂起,网络超时,无法执行 yj的主要内容,如果未能解决你的问题,请参考以下文章
kubernetes/docker 上的 gitlab:管道失败:清理 configmap 时出错:资源名称可能不为空