如何在Jenkins Blue Ocean中运行“ sidecar”容器?

时间:2020-06-02 21:10:43

标签: docker jenkins jenkins-pipeline jenkins-blueocean

我对詹金斯(Jenkins)和CI / CD总体来说还很陌生,但是我相信我已经搜索了足够长的时间,得出结论认为事情并非我所期望的。

我想在我的网站上进行一些前端测试,就像在现实生活中一样,我想在一个Docker容器中对网站进行测试,而在另一个容器中对数据库进行测试。詹金斯将此文档记录为"sidecar" containers,可以作为管道的一部分。

他们的示例:

node {
    checkout scm
    /*
     * In order to communicate with the MySQL server, this Pipeline explicitly
     * maps the port (`3306`) to a known port on the host machine.
     */
    docker.image('mysql:5').withRun('-e "MYSQL_ROOT_PASSWORD=my-secret-pw" -p 3306:3306') { c ->
        /* Wait until mysql service is up */
        sh 'while ! mysqladmin ping -h0.0.0.0 --silent; do sleep 1; done'
        /* Run some tests which require MySQL */
        sh 'make check'
    }
}

问题是我没有“传统的” Jenkins管道,但是我正在运行Jenkins Blue Ocean。这给了我一个不错的管道编辑器,但是我的管道代码(Jenkinsfile)看起来与示例完全不同:

pipeline {
  agent {
    docker {
      image 'php'
    }

  }
  stages {
    stage('Build') {
      steps {
        sh 'composer --version'
        sh 'composer install'
      }
    }

    stage('Tests') {
      steps {
        echo 'Do test'
      }
    }

  }
}

那么,我将如何在Blue Ocean管道中生成(和拆除)这些“ sidecar”容器?如果要添加与Docker相关的步骤,当前Pipeline编辑器没有可用选项。我还能使用docker.image吗?我确实安装了Docker Pipeline plugin

no available steps

2 个答案:

答案 0 :(得分:2)

Jenkins在link中提供的示例实际上是一个功能齐全的管道,只有一个例外。如果直接将管道脚本提供给Jenkins,则需要注释checkout scm

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

可能会让您感到困惑的是,上面示例中的代码样式与Blue Ocean管道编辑器生成的样式非常不同。这是因为脚本是用Scripted Pipeline编写的,并且Blue Ocean已生成Declarative Pipeline。 Jenkins完全支持这两者,并且两者都在下面使用相同的引擎,但是语法上的差异可能会在启动时造成混乱。

您可以很好地使用上面的脚本管道示例,但是,如果要保留声明性管道,可以在script步骤中运行脚本部分。在这两种情况下,您都需要根据需要更改docker映像和已执行的命令。

pipeline {
    agent any
    stages {
        stage('Build and test') {
            steps {
                script {
                    node {
                        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'
                            }
                        }
                    }
                }
            }
        }
    }
}

请注意:

  1. 本示例中使用的Docker容器链接功能是一项旧功能,最终可能会删除。
  2. 由于make check映像中未提供make,因此流水线将在centos:7处失败。

答案 1 :(得分:1)

半年后我终于发现它比我想象的要简单得多。可以通过 docker-compose 来完成。

您需要确保您的 Jenkins 可以访问 docker-compose。因此,如果您将 Jenkins 作为 Docker 容器运行,请确保它可以访问 Docker 套接字。此外,Jenkins 不太可能随附 docker-compose (JENKINS-51898),因此您必须构建自己的蓝海映像来安装 docker-compose。

与其复制下面的文件,不如检查 https://docs.docker.com/compose/install/ 以获得最新版本!

# Dockerfile
FROM jenkinsci/blueocean

USER root

RUN curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose && \
    chmod +x /usr/local/bin/docker-compose
    
USER jenkins

一旦您启动并运行 Jenkins 和 Docker,您就可以使用常规 docker-compose 文件部署应用程序的测试版本,包括您可能需要的所有数据库和其他容器。您可以通过使用 docker-compose exec 在以 docker-compose 启动的容器内执行命令来安装依赖项并启动测试。

请注意,docker-compose -f docker-compose.test.yml exec -T php composer-install 在 docker-compose 文件中定义为 composer-install 服务的容器中执行 php 命令。

最后,无论测试结果如何,所有容器和相关卷(-v 标志)都将关闭并删除。

# Jenkinsfile
pipeline {
  agent any
  stages {
    stage('Start') {
      steps {
        sh 'docker-compose -f docker-compose.test.yml up -d'
      }
    }
    stage('Composer install') {
      steps {
        sh 'docker-compose -f docker-compose.test.yml exec -T php composer install --no-interaction --no-progress --optimize-autoloader'
      }
    }
    stage('Test') {
      steps {
        sh 'docker-compose -f docker-compose.test.yml exec -T php <run test script>'
      }
    }
  }
  post {
    always {
      sh 'docker-compose -f docker-compose.test.yml down -v'
    }
  }
}