从一个Jenkinsfile运行多个Docker容器

tam*_*gal 3 groovy jenkins docker jenkins-pipeline

因此,我花了一整天的时间来弄清楚如何用多个Docker映像配置一个简单的Jenkins Pipeline,我一点都不高兴。

我需要在几个不同的Docker容器上执行(准备,构建,测试,文档)几个阶段(当前,我只选择了三个标准的Python容器)。如果这些程序可以并行运行会很好,但是我只找到了这个解决方案,它将所有阶段组合到一个阶段(因此在Blue Ocean UI中创建了一个不太有用的概述):跨多个Docker映像的Jenkins管道

因此,我结束了下面的配置,这很丑陋(到处都是代码重复),但是或多或少在经典UI中创建了一个漂亮的概览:

经典UI阶段

蓝海用户界面中的信息不多

蓝海舞台概述

来自的可接受的测试概述junit,它结合了每个阶段的所有测试,但是如果任何测试失败,则会显示相应的“版本”:

unit

但是,最令人讨厌的是,您看不到哪个步骤失败了。如果Python 2.7失败,其他所有内容也都标记为失败,甚至看不到哪个阶段失败。

我尝试了许多不同的方法,但我想知道应该怎么做。这对詹金斯来说应该是一件很平常的事,所以我想我在这个(对我来说绝对是全新的)管道/节点/标签/阶段/步骤/声明式/脚本化/ groovy / blueocean方面有一些普遍的误解...

应该可以为每个Docker容器定义一些列表(可能是可定制的阶段/步骤),并并行运行它们,并使其在Blue Ocean和Classic UI中很好地显示,不是吗?

node {
    stage("Python 2.7.14") {
        checkout scm
        docker.image('python:2.7.14').inside {  // just a dummy for now
            stage("Prepare") { sh 'python --version' }
            stage("Build") { sh 'ls -al' }
        }
    }
    stage("Python 3.5.4") {
        checkout scm
        docker.image('python:3.5.4').inside {
            stage("Prepare") { sh 'python -m venv venv' }
            stage("Build") {
                sh """
                    . venv/bin/activate
                    make install-dev
                """
            }
            stage('Test') {
                sh """
                    . venv/bin/activate
                    make test
                """
            }
            stage('Docs') {
                sh """
                    . venv/bin/activate
                    make doc-dependencies
                    cd docs
                    make html
                """
            }
        }
    }
    stage("Python 3.6.4") {
        checkout scm
        docker.image('python:3.5.4').inside {
            stage("Prepare") { sh 'python -m venv venv' }
            stage("Build") {
                sh """
                    . venv/bin/activate
                    make install-dev
                """
            }
            stage('Test') {
                sh """
                    . venv/bin/activate
                    make test
                """
            }
            stage('Docs') {
                sh """
                    . venv/bin/activate
                    make doc-dependencies
                    cd docs
                    make html
                """
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:这是步骤失败时在Blue Ocean UI中的外观,在这种情况下,Python 3.5.4和3.6.4中的“测试”都失败了,但看起来一切都失败了。 测试步骤失败

此外,Python 2.7.14和3.5.4阶段已折叠,无法单独查看。如果单击其中之一,则所有步骤均显示为绿色,尽管在这种情况下. venv/bin/activate make test失败:

测试步骤失败以绿色显示

tam*_*gal 7

这就是我最终得到的。当然有更好的解决方案,但我必须继续。我希望能及时收集到一些(更好的)答案,但我不会将其标记为“解决方案”;)

首先,请参考Stephen Kings的幻灯片(标题为“ Declarative”,但有关脚本化Pipeline的示例很好):(Declarative)Jenkins Pipelines

这是我在GitHub上的要点,其中包含以下代码段:

def docker_images = ["python:2.7.14", "python:3.5.4", "python:3.6.2"]

def get_stages(docker_image) {
    stages = {
        docker.image(docker_image).inside {
            stage("${docker_image}") {
                echo 'Running in ${docker_image}'
            }
            stage("Stage A") {
                switch (docker_image) {
                    case "python:2.7.14":
                        sh 'exit 123'  // for python 2.7.14 we force an error for fun
                        break
                    default:
                        sh 'sleep 10'  // for any other docker image, we sleep 10s
                }
                sh 'echo this is stage A'  // this is executed for all
            }
            stage("Stage B") {
                sh 'sleep 5'
                sh 'echo this is stage B'
            }
            stage("Stage C") {
                sh 'sleep 8'
                sh 'echo this is stage C'
            }

        }
    }
    return stages
}

node('master') {
    def stages = [:]

    for (int i = 0; i < docker_images.size(); i++) {
        def docker_image = docker_images[i]
        stages[docker_image] = get_stages(docker_image)
    }

    parallel stages
}
Run Code Online (Sandbox Code Playgroud)

我试图使其易于使用:

  • 您将Docker映像添加到顶部的列表中,然后stagesget_stages()函数中定义
  • 添加常见的阶段和步骤
  • 如果任何Docker映像需要特殊处理(例如python:2.7.14在我的示例中),则可以使用simple switch。对于特殊情况('images'->'stage'='steps')的双重映射和默认值的后备双重映射也可以实现这一点,但是我将其留给读者练习。(说实话,我无法弄清楚正确的,受支持的Groovy-lang语法)

这是在Classic和Blue Ocean用户界面中一切都很好时的样子(众所周知,Blue Ocean UI在并行运行中无法显示多个阶段,请参阅JENKINS-38442):

经典界面 经典用户界面-生成正常

蓝海UI 蓝海UI-生成正常

这是输出,如果Stage Apython:2.7.14失败:

经典界面 旧版用户界面-阶段A失败

蓝海UI 蓝海UI-失败的步骤A

  • 如果我的测试需要 MySQL,我该怎么办? (2认同)