2

默认情况下,我们的管道尝试使用与当前阶段名称匹配的容器。如果此容器不存在,则使用容器“默认”。此功能有效,但问题是当不存在与阶段名称匹配的容器时,会发生 ProtocolException,这是无法捕获的,因为它是由不受我们控制的线程引发的。在使用 Jenkins 的 Kubernetes 插件以防止出现此异常时,有没有办法检查容器是否确实存在?这似乎是一个基本功能,但我无法在网上找到类似的东西。

我无法显示实际代码,但这是一个会触发此异常的管道脚本示例摘录:

node(POD_LABEL)
        stage('Check Version (Maven)') {
            container('containerThatDoesNotExist'}{
                try{
                    sh 'mvn --version'
                }catch(Exception e){
                    // catch Exception
                }
        }
java.net.ProtocolException: Expected HTTP 101 response but was '400 Bad Request'
    at okhttp3.internal.ws.RealWebSocket.checkResponse(RealWebSocket.java:229)
    at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:196)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
4

1 回答 1

0

您可以通过 exec kubectl 命令到服务器运行 pre stage 以获取当前正在运行的容器。棘手的一点是工人上不存在 kubectl - 所以在这种情况下:

  1. 在 worker 上拉出 kubectl 的图像。
  2. 添加一个用于获取正在运行的容器的阶段 - 使用标签或时间戳来获取所需的容器。
  3. 使用正确的容器“默认”或更确切地说是“某些容器”。

例子:

pipeline {
    
    environment {
    CURRENT_CONTAINER="default"
  }

  agent {
    kubernetes {
      defaultContainer 'jnlp'
      yaml '''
        apiVersion: v1
        kind: Pod
        spec:
          containers:
          - name: some-app
            image: XXX/some-app
            imagePullPolicy: IfNotPresent
            tty: true
          - name: kubectl
            image: gcr.io/cloud-builders/kubectl
            imagePullPolicy: IfNotPresent
            command:
            - cat
            tty: true
        '''
    }
  }
  stages {
    stage('Set Container Name') {
      steps {
          container('kubectl') {
            withCredentials([
            string(credentialsId: 'minikube', variable: 'api_token')
            ]) {
            script {
                    CURRENT_CONTAINER=sh(script: 'kubectl get pods -n jenkins -l job-name=pi -o jsonpath="{.items[*].spec.containers[0].name}"',
                                        returnStdout: true
                                        ).trim()
                    echo "Exec container ${CURRENT_CONTAINER}"
            }
          }
        }
      }
    }
    
    stage('Echo Container Name') {
      steps {
          echo "CURRENT_CONTAINER is ${CURRENT_CONTAINER}"
      }
    }
  }
}
于 2022-02-02T10:39:49.877 回答