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 时出错:资源名称可能不为空

Kubernetes中gitlab的一次迁移

如何将 Kubernetes 与 Gitlab 集成

GitLab + Jenkins + Docker + Kubernetes。

Gitlab Kubernetes 集成

kubernetes(k8s)Gitlab CI Runner 的安装