如何在Docker容器中运行所有Jenkins流水线步骤,除了一个?

12

我正在尝试设置jenkins多分支流水线,以在docker容器中运行所有代码验证步骤,然后构建docker镜像并将其推送到docker容器之外。

目前,我的Jenkinsfile看起来像这样(为了易读性而简化):

pipeline {
    agent {
        label 'AWS'
    }
    stages {
        stage('stuff in docker') {
            agent {
                dockerfile {
                    filename 'Dockerfile.jenkins'
                    reuseNode true
                }
            }
            steps {
                stuff
            }
        }
        stage('more stuff in docker') {
            agent {
                dockerfile {
                    filename 'Dockerfile.jenkins'
                    reuseNode true
                }
            }
            steps {
                stuff
            }
        }
        stage('stuff not in docker') {
            steps {
                stuff
            }
        }
        stage('more stuff not in docker') {
            steps {
                stuff
            }
        }
    }
    post {
        always {
            cleanWs()
        }
    }
}

问题在于每次使用dockerfile代理时,Jenkins都会尝试重新构建docker镜像。虽然这些步骤都被缓存了,但发送构建上下文和实际处理所有内容仍然比我想要的时间更长。如果我将dockerfile用作根代理,我可以在同一个docker容器中运行所有内容,但我失去了执行git操作和构建docker镜像的能力(至少不连接到外部docker进程sock的话,这似乎比应该必要的麻烦还要多)。
我想知道是否有一种方法可以为多个步骤使用相同的docker镜像,然后在某些其他步骤中退出该docker镜像。

1
你是否探索过docker savedocker load?你可以在一个步骤中使用_save_命令,在另一个步骤中使用_load_命令。 - Technext
1
构建图像是否可以在管道之外或另一个管道中完成,然后再利用 Docker 代理呢? - Matt Schuchard
2个回答

18

弄明白了!

pipeline {
    agent {
        label 'AWS'
    }
    stages {
        stage('do everything in docker') {
            agent {
                dockerfile {
                    filename 'Dockerfile.jenkins'
                    reuseNode true
                }
            }
            stages {
                stage('stuff in docker') {
                    steps {
                        stuff
                    }
                stage('more stuff in docker') {
                    steps {
                         stuff
                    }
                }
            }
        }
        stage('stuff not in docker') {
            steps {
                stuff
            }
        }
        stage('more stuff not in docker') {
            steps {
                stuff
            }
        }
    }
    post {
        always {
            cleanWs()
        }
    }
}

简而言之,您可以嵌套阶段


2
这解决了我的问题 - 谢谢!此外,这是官方的Jenkins博客文章,详细解释了这个功能。在https://dev59.com/VVUL5IYBdhLWcg3wYHDD#76094847找到了链接。 - jhn

1
使用dockerfile作为构建代理将始终导致容器重建。如果您只想在(预构建的)容器内运行一些步骤,请使用docker作为代理。当然,这也可以是在同一流水线中本地构建的容器。您还可以利用绑定挂载在容器之间共享数据。
如果不确定,请查看文档12。也许在您的情况下,将全局代理设置为none也是明智的选择。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接