繁体   English   中英

Jenkins:从与代理(另一个 Docker 容器)一起运行的阶段连接到 Docker 容器

[英]Jenkins: Connect to a Docker container from a stage that is run with an agent (another Docker container)

我正在重新设计管道以使用声明式管道方法,以便我能够在每个阶段使用 Docker 映像

目前我有以下工作代码,它执行连接到在 Docker 容器中运行的数据库的集成测试。

node {
    // checkout, build, test stages...
    stage('Integration Tests') {            
        docker.image('mongo:3.4').withRun(' -p 27017:27017') { c ->
        sh "./gradlew integrationTest"
    }
}

现在使用声明式管道,相同的代码看起来像这样:

pipeline {
    agent none
    stages {
        // checkout, build, test stages...
        stage('Integration Test') {
            agent { docker { image 'openjdk:11.0.4-jdk-stretch' } }
            steps {
                script {
                    docker.image('mongo:3.4').withRun(' -p 27017:27017') { c ->
                        sh "./gradlew integrationTest"
                    }
                }
            }
        }
    }
}

问题:舞台现在在 Docker 容器中运行,运行docker.image()会导致docker.image() docker: not found错误在舞台中(它正在现在使用的openjdk图像中寻找openjdk )。

问题:如何启动一个数据库容器并从声明性管道的一个阶段连接到它?

本质上您正在尝试使用的是 DIND。

您正在使用一个 jenkins 从站,它基本上是使用 docker agent { docker { image 'openjdk:11.0.4-jdk-stretch' } }

容器运行后,您将尝试执行 docker 命令。 错误docker: not found是有效的,因为没有安装 docker cli。 您需要更新 dockerfile/创建一个安装了 openjdk:11.0.4-jdk-stretch 和 docker dameon 的自定义镜像。

安装守护程序后,您需要批量挂载 /var/run/docker.sock 以便守护程序将通过套接字与主机 docker 守护程序通信。

用户应该是 root 或特权用户,以避免出现权限被拒绝的问题。

因此,如果我正确理解这一点,您的测试需要两件事:

  • Java环境
  • 数据库连接

在这种情况下,您是否尝试过不同的方法,例如Docker In Docker (DIND)

如果您可以拥有使用docker:dind作为基础镜像并包含您的 java 环境并在agent部分使用它的自定义镜像,那么其余的管道步骤将能够按照您的预期使用 docker 命令。

在您的示例中,您试图在 openjdk:11.0.4-jdk-stretch 中运行一个容器。 如果这个镜像没有安装 docker daemon,你将无法执行 docker,但在这种情况下,它会在 docker 中运行一个你不应该运行的 docker。

所以这取决于你想要什么时候。

  • 使用多个容器:在这种情况下,您可以组合多个 docker 镜像,但它们不相互依赖:

     pipeline { agent none stages { stage('Back-end') { agent { docker { image 'maven:3-alpine' } } steps { sh 'mvn --version' } } stage('Front-end') { agent { docker { image 'node:7-alpine' } } steps { sh 'node --version' } } }

    }

  • 运行“sidecar”容器:此示例显示您同时使用两个容器,它们将能够相互交互:

     node { checkout scm docker.image('mysql:5').withRun('-e "MYSQL_ROOT_PASSWORD=my-secret-pw"') { c -> docker.image('mysql:5').inside("--link ${c.id}:db") { /* Wait until mysql service is up */ sh 'while ! mysqladmin ping -hdb --silent; do sleep 1; done' } docker.image('centos:7').inside("--link ${c.id}:db") { /* * Run some tests which require MySQL, and assume that it is * available on the host name `db` */ sh 'make check' } }

    }

请参考官方文档-> https://jenkins.io/doc/book/pipeline/docker/

我希望它会帮助你。

我遇到了类似的问题,我希望能够使用现成的 Maven Docker 映像来运行我的构建,同时还能够构建包含应用程序的 Docker 映像。 我通过首先启动要在其中运行构建的 Maven 容器来实现这一点,并允许它访问主机 Docker 端点。
部分示例:

docker run -v /var/run/docker.sock:/var/run/docker.sock maven:3.6.1-jdk-11

然后,在构建容器中,我下载 Docker 二进制文件并设置 Docker 主机:

export DOCKER_HOST=unix:///var/run/docker.sock
wget -nv https://download.docker.com/linux/static/stable/x86_64/docker-19.03.2.tgz
tar -xvzf docker-*.tgz
cp docker/docker /usr/local/bin

现在我可以在我的构建容器中运行 docker 命令。 对我来说,积极的副作用是,在构建的一个步骤中在容器内构建的任何 Docker 映像都将可用于构建的后续步骤,也在容器中运行,因为它们将保留在主机中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM