目录
[1. docker部署jenkins](#1. docker部署jenkins)
[1.1 准备数据目录](#1.1 准备数据目录)
[1.2 拉取jenkins镜像并启动](#1.2 拉取jenkins镜像并启动)
[1.3 初始化配置](#1.3 初始化配置)
[1.3.1 登录容器查看初始化密码](#1.3.1 登录容器查看初始化密码)
[1.3.2 访问jenkins并输入初始化密码](#1.3.2 访问jenkins并输入初始化密码)
[1.3.3 创建管理员账户](#1.3.3 创建管理员账户)
[1.3.4 初始化完成](#1.3.4 初始化完成)
[2. jenkins使用之多分支流水线](#2. jenkins使用之多分支流水线)
[2.1 准备代码分支](#2.1 准备代码分支)
[2.1.1 gitlab创建一个仓库](#2.1.1 gitlab创建一个仓库)
[2.1.2 添加JenkinsFile和build脚本](#2.1.2 添加JenkinsFile和build脚本)
[2.1.3 基于main分支创建一个dev分支](#2.1.3 基于main分支创建一个dev分支)
[2.2 创建多分支流水线](#2.2 创建多分支流水线)
[2.2.1 新建Item](#2.2.1 新建Item)
[2.2.2 选择创建多分支流水线](#2.2.2 选择创建多分支流水线)
[2.2.3 弹出配置页面并输入名称](#2.2.3 弹出配置页面并输入名称)
[2.2.4 选择分支源并配置](#2.2.4 选择分支源并配置)
[2.2.5 点击确认](#2.2.5 点击确认)
[2.2.6 查看多分支流水线状态](#2.2.6 查看多分支流水线状态)
[2.2.7 流水线更新](#2.2.7 流水线更新)
[2.3 让流水线运行到其他开发机](#2.3 让流水线运行到其他开发机)
[2.3.1 arm机器环境准备](#2.3.1 arm机器环境准备)
[2.3.2 新建node](#2.3.2 新建node)
[2.3.3 在新node中运行流水线](#2.3.3 在新node中运行流水线)
[2.3.4 查看状态](#2.3.4 查看状态)
[2.4 让流水线运行到docker中](#2.4 让流水线运行到docker中)
[3. Jenkins cloud(通过docker服务器管理node)](#3. Jenkins cloud(通过docker服务器管理node))
[3.1 准备node镜像](#3.1 准备node镜像)
[3.2 准备主机](#3.2 准备主机)
[3.2.1 打开docker服务的tcp端口](#3.2.1 打开docker服务的tcp端口)
[3.2.2 测试docker tcp服务](#3.2.2 测试docker tcp服务)
[3.3 创建cloud](#3.3 创建cloud)
[3.3.1 新建node](#3.3.1 新建node)
[3.3.2 配置docker cloud details](#3.3.2 配置docker cloud details)
[3.3.3 配置docker agent templete](#3.3.3 配置docker agent templete)
[3.4 创建freestyle流水线并使用cloud](#3.4 创建freestyle流水线并使用cloud)
[3.4.1 新建freestyle project类型的Item](#3.4.1 新建freestyle project类型的Item)
[3.4.2 限制流水线运行在cloud上](#3.4.2 限制流水线运行在cloud上)
[3.4.3 选择git并指定分支](#3.4.3 选择git并指定分支)
[3.4.4 输入build步骤](#3.4.4 输入build步骤)
[3.4.5 运行流水线](#3.4.5 运行流水线)
[4. Jenkins的docker插件(docker in docker支持)](#4. Jenkins的docker插件(docker in docker支持))
[4.1 要求](#4.1 要求)
[4.2 具体方案](#4.2 具体方案)
[4.3 多分支流水线示例(基于node)](#4.3 多分支流水线示例(基于node))
[4.3.1 修改dockerfile](#4.3.1 修改dockerfile)
[4.3.2 jenkins中安装docker插件](#4.3.2 jenkins中安装docker插件)
[4.3.3 新建基于SCM的多分支流水线](#4.3.3 新建基于SCM的多分支流水线)
[4.3.4 启动状态确认](#4.3.4 启动状态确认)
[4.4 多分支流水线示例(基于cloud)](#4.4 多分支流水线示例(基于cloud))
[4.4.1 配置cloud](#4.4.1 配置cloud)
[4.4.2 为流水线指定cloud](#4.4.2 为流水线指定cloud)
一、摘要
本文先介绍了jenkins在docker中的部署
然后以SCM多分支流水线配置为例创建了基于内置node的流水线
接下来让SCM多分支流水线跑在基于其他物理机或者docker机器环境的node中
最后创建jenkins cloud并以FreeStyle流水线为例,让node在docker服务器上执行任务
-
在docker中部署jenkins
-
基于源码管理的SCM流水线
-
jenkins node:在jenkins slave上跑流水线
-
jenkins cloud:node集合
主要包含4小块内容

二、部署和使用
1. docker部署jenkins

1.1 准备数据目录
makedir -p /home/jenkins/jenkins-data
1.2 拉取jenkins镜像并启动
这里以2.440.3-lts版本为例
docker pull jenkins/jenkins:2.440.3-lts
docker run \
--name jenkins-jenkins \
# 容器在退出时,自动清除挂在的卷,以便清除数据
# 等价于在容器退出后,执行docker rm -v,正式环境下不要使用
--rm \
# 后台运行
--detach \
# jenkins web访问端口为主机的9880, jenkins slave连接端口为50000
--publish 9880:8080 --publish 50000:50000 \
# 物理机/home/jenkins/jenkins-data指定为jenkins数据目录
-v /home/jenkins/jenkins-data:/var/jenkins_home \
# jenkins复用物理主机的docker服务
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:2.440.3-lts
1.3 初始化配置
1.3.1 登录容器查看初始化密码
docker exec -it jenkins-jenkins bash
cat /var/jenkins_home/secrets/initialAdminPassword
# 399861214afc433e80980d4b607e60df

1.3.2 访问jenkins并输入初始化密码
通过127.0.0.1:9880访问jenkins网页

跳过新手入门界面

等待jenkins初始化一段时间

1.3.3 创建管理员账户
输入用户名和密码

记住访问地址

1.3.4 初始化完成

2. jenkins使用之多分支流水线
这个例子中
我们先创建一个含有JenkinsFile的代码仓库,并额外创建dev分支
然后在Jenkins中创建一个多分支流水线
接下来通过 立即扫描多分支流水线 拉取代码并配置流水线
最后点击运行按钮触发特定分支的流水线
注意:流水线首次创建完成后,会自动执行立即扫描多分支流水线的功能,拉取git仓库代码,并根据代码中的JenkinsFile自动配置流水线,自动在各个分支上执行触发特定分支的流水线功能。

2.1 准备代码分支
jenkins会通过代码仓库下的JenkinsFile构建流水线,跟gitlab-ci.yml类似
该例子中
Build阶段每个分支(main和dev)都会执行,Test阶段每个分支都会执行 Release for dev阶段只有dev分支会执行,Release for main阶段只有main分支会执行
2.1.1 gitlab创建一个仓库

2.1.2 添加JenkinsFile和build脚本
JenkinsFile内容
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'pwd && ls -alh'
sh 'bash ./build_b.sh building'
}
}
stage('Test') {
steps {
sh 'bash ./build_b.sh testing'
}
}
stage('Release for dev') {
when {
branch 'dev'
}
steps {
sh 'bash ./build_b.sh release when dev'
# 实现流水线和jenkins前台交互,执行到这里的时候需要在jenkins任务界面点击确认按钮
# 不是必须的
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'bash ./build_b.sh release when dev after input'
}
}
stage('Release for main') {
when {
branch 'main'
}
steps {
sh 'bash ./build_b.sh release when main'
# 实现流水线和jenkins前台交互,执行到这里的时候需要在jenkins任务界面点击确认按钮
# 不是必须的
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'bash ./build_b.sh release when main after input'
}
}
}
}
build脚本内容(输出如下内容和命令行参数)
echo "[main branch]this is a test build b test script: $@"
2.1.3 基于main分支创建一个dev分支
多分支流水线会根据分支和jenkinsfile执行不同的steps
2.2 创建多分支流水线
2.2.1 新建Item

2.2.2 选择创建多分支流水线

2.2.3 弹出配置页面并输入名称

2.2.4 选择分支源并配置
选择Git

输入git仓库地址

选择添加git凭据

添加一个全局凭据

2.2.5 点击确认
自动进入多分支流水线扫描(自动通过gitlab凭据拉取代码)

首次构建完成会扫描并自动执行,如左下角进度所示

2.2.6 查看多分支流水线状态
点击任意一个查看执行状态

可以回到主页查看整体状态 也可以点击右侧三角图标重新触发流水线

2.2.7 流水线更新
如果代码内容有变更,需要手动重新扫描多分支流水线触发代码的重新拉取

2.3 让流水线运行到其他开发机
默认情况下上面的多分支流水线会在jenkins的内置node中执行,也就是在jenkins所在环境中运行
我们将jenkins安装到了dcoker中,因此上面的流水线会在jenkins所在docker容器中运行
上面的流水线相对简单,主要是执行了一个bash脚本,因此内置的node可以跑起来
但是当我们的build脚本比较复杂,对运行环境有要求,那么内置的node就不能满足我们的需要了 这时候我们就需要额外创建node,让我们的任务跑在指定的环境上
我们将一台arm机器作为node,来运行我们的流水线

2.3.1 arm机器环境准备
安装java 11
sudo apt-get install openjdk-11-jdk
准备一个node的工作目录, Jenkins会将一些必要的文件copy到工作目录中
mkdir -p /home/cpf/jenkins/node_work_dir/
2.3.2 新建node
打开管理jenkins页面并点击nodes

点击新建node

输入node名称并创建

添加ssh凭据,jenkins将通过凭据登录node
这里为了演示方便统一使用用户名和密码作为凭据(也可以用sshkey)

工作目录,标签和启动方式配置

点击保存后查看node状态

2.3.3 在新node中运行流水线
修改流水线配置,将node指定为我们刚才创建的node
先打开build流水线界面,点击左侧配置菜单

拖到最下面, 输入dockerlable(之前步骤中设置的node的lable)后save

重新触发流水线

2.3.4 查看状态
查看状态

2.4 让流水线运行到docker中
在2.3中,我们在arm机器上安装了java 11后,可以创建一个基于实体机器的node,jenkins可以通过ssh链接到node并运行流水线
类似的,我们也可以启动一个安装了java 11的docker镜像,创建一个基于docker的node,jenkins通过ssh链接到docker中,并运行流水线

3. Jenkins cloud(通过docker服务器管理node)
在前面的示例中,我们需要提前准备一个安装有java11环境的实体机或者提前启动一个带有java11的docker镜像来作为node
然而jenkins的cloud提供了另外一种方式,任务创建后自动通过docker服务创建一个node,任务完成后自动销毁

3.1 准备node镜像
准备一个安装了java 11的镜像作为node(dockerhub上已经有这样的镜像了,我们可以直接拉取使用,注意:dockerhub上的node镜像没有安装docker)

3.2 准备主机
准备一台安装了docker的主机
注意:docker服务需要开启tcp服务已被jenkins连接,同时确保防火墙打开了docker的TCP侦听端口的2376端口
3.2.1 打开docker服务的tcp端口
默认情况下docker服务不开启tcp服务
我们可以通过修改启动配置打开tcp侦听服务
sudo vi /lib/systemd/system/docker.service
# -H tcp://10.31.1.12:2376

需重新加载并启动服务后生效
sudo systemctl daemon-reload
sudo systemctl restart docker.service
检查确认端口已经侦听

3.2.2 测试docker tcp服务
在另一台机器上访问docker端口
curl http://10.31.1.12:2376/version

3.3 创建cloud
3.3.1 新建node
在管理kenkins界面点击Clouds

点击add

输入名字

3.3.2 配置docker cloud details
输入tcp链接地址和端口(docker服务器提供的服务地址和端口)

测试端口 点击右侧的按钮可以测试连接

3.3.3 配置docker agent templete
展开docker agent templete后点击Add Dcoker Templete按钮
-
Lables:docker_10.31.1.12
-
Name:docker_10.31.1.12
-
image:jenkins/agent:jdk11(注意这里的镜像是node的镜像也即agent镜像)
-
container setting:先不填写

Instance capacity:5
同时启动的docker agent镜像数量,这里设置为5),其他参数默认不管

连接方式选择attach docker container
通过docker exec的方式登录到docker内部
pull strategy修改为从不(我们手动维护aget镜像,不用每次重新pull)

点击保存

3.4 创建freestyle流水线并使用cloud
3.4.1 新建freestyle project类型的Item

3.4.2 限制流水线运行在cloud上
输入之前创建的cloud的标签

3.4.3 选择git并指定分支

3.4.4 输入build步骤
我们这里指定为运行代码仓库目录下的build脚本
注意:如果我们不指定构建步骤将只会clone代码

3.4.5 运行流水线
保存后运行流水线

4. Jenkins的docker插件(docker in docker支持)
以上的演示,我们的流水线任务和build步骤都是直接跑在node节点中的
-
如果node节点是物理机,则流水线任务直接在物理机上跑,build步骤也一样
-
如果node节点是docker镜像实例,则流水线任务会跑在docker实例中,build步骤也一样
-
如果node节点是通过cloud启动的,则流水线任务任务会跑在cloud服务器启动的docker实例中,build步骤也一样
想像这样一个场景。前期公司没有jenkins,编译镜像也没有java 11环境,因此这些编译镜像是不能作为node镜像来用
其实node镜像和build镜像可以不是用一个。我们是可以让build步骤(构建过程)跑在其他镜像中来解决这个问题

4.1 要求
作为node的jenkins agent镜像需要支持docker in docker功能,也即在docker中使用docker的功能
4.2 具体方案
将宿主机的docker通信套接字挂载给node,这样node就会使用宿主机提供的docker服务,node启动的镜像实例会在宿主机上启动
4.3 多分支流水线示例(基于node)
在基于arm实体机器的node上运行多分支流水线,流水线中的build任务将基于 ubuntu:20.04 镜像运行
主要流程是 jenkins触发流水线->在物理机的node接收任务->启动一个ubuntu:20.04->执行build任务
4.3.1 修改dockerfile
添加agent指定镜像,image 'ubuntu:20.04'
pipeline {
agent {
docker {
image 'ubuntu:20.04'
}
}
stages {
stage('Build') {
steps {
sh 'pwd && ls -alh'
sh 'bash ./build_b.sh building'
}
}
stage('Test') {
steps {
sh 'bash ./build_b.sh testing'
}
}
stage('Release for dev') {
when {
branch 'dev'
}
steps {
sh 'bash ./build_b.sh release when dev'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'bash ./build_b.sh release when dev after input'
}
}
stage('Release for main') {
when {
branch 'main'
}
steps {
sh 'bash ./build_b.sh release when main'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'bash ./build_b.sh release when main after input'
}
}
}
}
4.3.2 jenkins中安装docker插件
在管理jenkins中打开Plugins

安装docker pipeline插件

点击安装后,同时会自动安装docker插件

如果不装docker pileline插件将报错: 无法解析JenkinsFile中的docker字段

如果node中没有安装docker软件将会有如下错误

4.3.3 新建基于SCM的多分支流水线
基础配置
-
输入仓库名
-
设置凭据
-
选择jenkinsfile模式并指定文件路径(默认不需要修改)

指定node为我们刚才创建的cloud

4.3.4 启动状态确认
重新运行

点击继续

运行成功

查看日志 docker inspect -f . ubuntu:20.04 执行成功了,日志正常打印

4.4 多分支流水线示例(基于cloud)
4.4.1 配置cloud
配置cloud,让node使用docker服务器的docker服务
即在node使用的docker命令都会在物理docker服务器运行
参考:Jenkins Docker plugin volume/mount what syntax to use


4.4.2 为流水线指定cloud
将4.3中的流水线指定在cloud上运行后,重新触发流水线即可

三、注意事项
-
Jenkins node镜像请安装docker 在node中安装docker后,支持docker in docker这种构建方式
-
Jenkins node可以共用主机的docker服务 如果node是一个镜像实例,则启动的时候可以挂载上主机的/var/run/docker.sock:/var/run/docker.sock以统一使用主机提供的docker服务
关注 非科班CPP程序员,一起进步。