持续集成中的 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,注意:必须安装

我们通过下面的脚本一次搞定这些操作:

在容器中运行 Jenkins pipeline 任务
#!/bin/bash
# run this script like this: sudo ./addsudouser.sh

useradd -m jenkins -d /home/jenkins -s /bin/bash;
echo 'jenkins:xA123456' | 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
在容器中运行 Jenkins pipeline 任务

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

在容器中运行 Jenkins pipeline 任务

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

运行简单的 demo

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

在容器中运行 Jenkins pipeline 任务
pipeline {
    agent {
        docker { image 'node:7-alpine' }
    }
    stages {
        stage('Test') {
            steps {
                sh 'node --version'
            }
        }
    }
}
在容器中运行 Jenkins pipeline 任务

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

在容器中运行 Jenkins pipeline 任务
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Test)
[Pipeline] sh
[myjob] Running shell script
+ node --version
v7.10.1
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
在容器中运行 Jenkins 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 的任务上:

在容器中运行 Jenkins pipeline 任务

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

运行多个不同的容器

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

在容器中运行 Jenkins pipeline 任务
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'
            }
        }
    }
}
在容器中运行 Jenkins pipeline 任务

使用 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 内容如下:

在容器中运行 Jenkins pipeline 任务
#!/bin/sh
set -e
# Prepend "curl" if the first argument is not an executable
if ! type -- "$1" &> /dev/null; then
    set -- curl "[email protected]"
fi
exec "[email protected]"
在容器中运行 Jenkins pipeline 任务

Jenkinsfile 的内容如下:

在容器中运行 Jenkins pipeline 任务
pipeline {
    agent {
        dockerfile {
            filename 'Dockerfile'
            dir 'curl'
            label 'docker'
        }
    }
    stages {
        stage('Test') {
            steps {
                sh 'curl http://www.cnblogs.com/sparkdev/p/8795141.html'
            }
        }
    }
}
在容器中运行 Jenkins pipeline 任务

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

在容器中运行 Jenkins pipeline 任务

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

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

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

在容器中运行 Jenkins pipeline 任务

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

在容器中运行 Jenkins pipeline 任务
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')
    }
}
在容器中运行 Jenkins pipeline 任务

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

在容器中运行 Jenkins pipeline 任务

总结

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

http://www.qhr2747.cn
http://www.xrp0406.cn
http://www.iqs1471.cn
http://www.abu7172.cn
http://www.hlv4231.cn
http://www.hir0167.cn
http://www.gzh1725.cn
http://www.dox1148.cn
http://www.xip7382.cn
http://www.ngm1905.cn
http://www.dmb8658.cn
http://www.nqa8573.cn
http://www.esz4596.cn
http://www.nhs9541.cn
http://www.kfq4961.cn
http://www.fsi2703.cn
http://www.ybc8953.cn
http://www.myy9223.cn
http://www.paf5803.cn
http://www.njb8631.cn
http://www.kzo4326.cn
http://www.tso8557.cn
http://www.nwm1536.cn
http://www.tae4138.cn
http://www.dxc3579.cn
http://www.ffp5727.cn
http://www.lhb4836.cn
http://www.xdi0113.cn
http://www.bpa2365.cn
http://www.fks8445.cn
http://www.aht8537.cn
http://www.cun5054.cn
http://www.gdk7028.cn
http://www.ypk8666.cn
http://www.wan2959.cn
http://www.sit9945.cn
http://www.zmj4226.cn
http://www.ccn6233.cn
http://www.jck8045.cn
http://www.ckk6213.cn
http://www.mak1390.cn
http://www.vii0197.cn
http://www.pwj5001.cn
http://www.wvh4263.cn
http://www.mvg0339.cn
http://www.yif9712.cn
http://www.jta0960.cn
http://www.omx8816.cn
http://www.nlc4773.cn
http://www.dep9137.cn
http://www.vlq7732.cn
http://www.umg2515.cn
http://www.kog1435.cn
http://www.nxf9936.cn
http://www.hqh7518.cn
http://www.hij5984.cn
http://www.vui9639.cn
http://www.fzl7156.cn

相关文章:

  • 2022-01-21
  • 2022-12-23
  • 2021-07-14
  • 2021-12-03
猜你喜欢
  • 2021-10-29
  • 2021-12-05
  • 2021-10-18
  • 2022-01-01
  • 2022-12-23
相关资源
相似解决方案