zoukankan      html  css  js  c++  java
  • 在容器中运行 Jenkins pipeline 任务

    持续集成中的 pipeline 技术和 docker 都是当前正在发展的主流方向,当然把它们结合起来在 CI/CD 过程中发挥出更强大的威力也是大家共同的目标。本文将介绍如何在 Jenkins pipeline 中集成使用 docker,好在当前的 Jenkins 已经默认通过插件实现了与 docker 的集成,所以这将是一段轻松愉快的旅程。

    添加 linux 主机作为 build agent

    简单起见,我们使用一台安装了 docker 的 linux 虚机,并通过 ssh 将其启动为 Jenkins server 的 build agent。主要操作步骤如下:

    • 在 linux 机器上创建一个用户 jenkins, 密码为 123456
    • 创建目录 /var/jenkins, 并把 owner 修改为 jenkins
    • 安装 jre,注意:必须安装
    • 安装 docker

    我们通过下面的脚本一次搞定这些操作(docker 的安装请参考官方文档):

    #!/bin/bash
    # run this script like this: sudo ./addsudouser.sh
    
    useradd -m jenkins -d /home/jenkins -s /bin/bash;
    echo 'jenkins:123456' | sudo chpasswd
    usermod -a -G sudo jenkins;
    usermod -a -G docker jenkins;
    echo 'jenkins   ALL=(ALL:ALL) NOPASSWD: ALL' >> /etc/sudoers;
    sudo mkdir /var/jenkins
    sudo chown jenkins /var/jenkins
    sudo apt-get -y install default-jre

    在 linux 虚机上执行上面的脚本,然后在 Jenkins 中添加 node(build agent):

    其中的 "Remote root directory" 就是刚才创建的 /var/jenkins 目录。"Launch method" 选择 "Launch slave agents via SSH"。Host 为 linux 虚机的 IP,Credentials 则为刚才创建的 jenkins 用户。

    运行简单的 demo

    先来运行一个简单的 demo。创建一个 pipeline 类型的 job,并输入下面的 pipeline script:

    pipeline {
        agent {
            docker { image 'node:7-alpine' }
        }
        stages {
            stage('Test') {
                steps {
                    sh 'node --version'
                }
            }
        }
    }

    运行该任务,执行结果如下:

    [Pipeline] {
    [Pipeline] stage
    [Pipeline] { (Test)
    [Pipeline] sh
    [myjob] Running shell script
    + node --version
    v7.10.1
    [Pipeline] }
    [Pipeline] // stage
    [Pipeline] }

    其中的命令 node --version 就是在容器中执行的。

    通过 label 指定运行 stage 的 agent

    Jenkins 默认会把任务分配给任何可用的 agent,如果我们要指定任务执行的 agent,可以在 docker 的配置中指定 label,这样该任务只会被分配到具有某个 label 的 agent 上运行:

    agent {
        docker {
            image 'node:7-alpine'
            label 'xxxxxx'
        }
    }

    在 Folder 级别指定 label 和 registry 信息

    我们还可以在 folder 级别指定 label,这样的设置会应用在 folder 内所有没有设置 label 的任务上:

    除了 label,还可以设置 docker registry URL 及其身份认证的凭据。

    运行多个不同的容器

    我们还可以在不同的 stage 中运行不同的容器,其实就是每个 stage 用自己的容器镜像创建容器并执行任务,stage 之间没啥关系:

    pipeline {
        agent none
        stages {
            stage('Back-end') {
                agent {
                    docker { image 'appropriate/curl' }
                }
                steps {
                    sh 'curl www.google.com'
                }
            }
            stage('Front-end') {
                agent {
                    docker { image 'node:7-alpine' }
                }
                steps {
                    sh 'node --version'
                }
            }
        }
    }

    使用 Dockerfile

    通过指定 Dockerfile 文件,在 build agent 上直接构建容器镜像,然后生成容器并执行命令。下面的 demo 中我们通过 Dockerfile 创建一个包含 curl 工具的容器镜像,然后通过该镜像启动容器并执行 HTTP 请求。该 demo 一共包含三个文件:Dockerfile 、entrypoint.sh 和 Jenkinsfile,大家可以直接从这里下载它们。先看一下 Dockerfile 文件的内容:

    FROM alpine:latest
    RUN apk add --update curl && rm -rf /var/cache/apk/*
    COPY entrypoint.sh /
    ENTRYPOINT ["/entrypoint.sh"]
    CMD ["curl"]

    其中的 entrypoint.sh 内容如下:

    #!/bin/sh
    set -e
    # Prepend "curl" if the first argument is not an executable
    if ! type -- "$1" &> /dev/null; then
        set -- curl "$@"
    fi
    exec "$@"

    Jenkinsfile 的内容如下:

    pipeline {
        agent {
            dockerfile {
                filename 'Dockerfile'
                dir 'curl'
                label 'docker'
            }
        }
        stages {
            stage('Test') {
                steps {
                    sh 'curl http://www.cnblogs.com/sparkdev/p/8795141.html'
                }
            }
        }
    }

    注意,该文件中我们设置了 dir 为 curl 目录,这是因为此项目的 Dockerfile 文件不是在代码库的根目录下,所以需要指定其相对目录的路径。
    然后在 Jenkins 中创建 pipeline 类型的 job,并把 pipeline 的 Definition 设置为 "Pipeline script from SCM" 。接下来设置好代码仓库的路径就可以了。运行该任务,从日志上可以看到取完代码后先通过 Dockerifle 文件构建了容器镜像:

    并在容器中运行了 curl http://www.cnblogs.com/sparkdev/p/8795141.html 命令。

    把生成的容器镜像推送到仓库中

    上面的例子中我们通过 Dockerfile 生成了容器镜像,并且完成了相关的测试(通过 curl 请求了测试网页)。接下来就是把生成的容器镜像推送到镜像仓库中。下面将演示如何在 pipeline 中把构建的镜像推送的镜像仓库。首先在 Folder 的配置界面中添加访问 dockerhub.com 凭据如下:

    如果是访问 dockerhub 就不需要填写 "Docker registry URL"。然后添加下面的 Pipeline script:

    node {
        checkout([$class: 'GitSCM', branches: [[name: '*/master']], userRemoteConfigs: [[url: 'https://github.com/sparkdevo/ctools.git']]])
        docker.withRegistry('', '9e70c1eb-814c-4cf2-97e9-5bfc20461231') {
            def customImage = docker.build("ljfpower/curl:${env.BUILD_ID}","./curl")
            customImage.inside {
                sh 'curl http://www.cnblogs.com/sparkdev/p/8795141.html'
            }
            customImage.push()
            customImage.push('latest')
        }
    }

    注意, 9e70c1eb-814c-4cf2-97e9-5bfc20461231 刚才创建的凭据的 ID,可以从 folder 的 Credentials 界面中获得。运行这个任务,执行成功后去 dockerhub.com 上看一下,是不是已经把新构建的镜像推送上去了:

    总结

    从本文的几个简单 demo 可以看出,jenkins pipeline 和 docker 集成的已经很好了。当然你还可以实现更多更复杂的用例,赶紧动手吧!

    参考:
    Using Docker with Pipeline
    Pipeline Syntax

  • 相关阅读:
    RN-Android构建失败:Caused by: org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project 'AwesomeProject'.
    Android更新包下载成功后不出现安装界面
    真机调试: The application could not be installed: INSTALL_FAILED_TEST_ONLY
    react native 屏幕尺寸转换
    Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值
    React Native安卓真机调试
    git提交代码报错Permission denied, please try again
    The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
    命令行设置快捷命令
    Linux 常用指令
  • 原文地址:https://www.cnblogs.com/sparkdev/p/8863773.html
Copyright © 2011-2022 走看看