为jenkins使用Kubernetes插件时,请检查容器是否存在



默认情况下,我们的管道会尝试使用与当前阶段名称匹配的容器。如果此容器不存在,则使用容器"default"。该功能有效,但问题是,当与阶段名称匹配的容器不存在时,会发生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)

您可以运行一个预阶段,以便通过向服务器执行kubectl命令来获取当前正在运行的容器。棘手的一点是,工人身上不存在kubectl,所以在这种情况下:

  1. 在worker上拉一张kubectl的图片
  2. 添加一个获取正在运行的容器的阶段-使用标签或时间戳来获取所需的容器
  3. 使用正确的容器"default",或者更确切地说是"some container">

示例:

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}"
}
}
}
}

相关内容

最新更新