基于已经配置好的 Jenkins 环境,本文参考中国DevOps社区核心组织者刘征老师在中国DevOps社区济南Meetup活动上分享的 "用Jenkins实施CI/CD工作坊",展示如何使用 Jenkins 实现 Java 项目的 CI/CD (持续集成/持续交付)。
软件版本和环境准备
本次安装中使用的主要软件版本如下:
-
Ubuntu
- Ubuntu 16.04.6 LTS
- Ubuntu 18.04.2 LTS
-
openjdk
- openjdk version "1.8.0_212"
- openjdk version "11.0.3"
- Jenkins 2.164.3
- Apache Maven 3.6.1
-
Apache Tomcat
- Apache Tomcat/8.0.32 (Ubuntu)
- Apache Tomcat/8.5.39 (Ubuntu)
- Apache Tomcat/9.0.16 (Ubuntu)
Jenkins 和 Tomcat 分别安装在两台云主机中,因为未进行安全防护,为避免受到攻击,示例中的 IP 地址不是真实的 IP 地址:
- Jenkins 节点: 114.111.111.111
- Tomcat 节点: 114.111.111.222
在使用 GitHub hook 功能时, Jenkins 节点应能被 GitHub 访问。
下载安装最新版 Maven
Ubuntu apt 源指向的 Maven 版本不是最新的。为了使用推荐版本的 Maven, 可从 Maven 官网或镜像网站下载, 解压后配置给 Jenkins 使用。在 Ubuntu 下命令如下:
wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
wget https://www.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz.sha512
cat apache-maven-3.6.1-bin.tar.gz.sha512
sha512sum apache-maven-3.6.1-bin.tar.gz # 确保输出内容与文件 apache-maven-3.6.1-bin.tar.gz.sha512 内容一致
tar xzvf apache-maven-3.6.1-bin.tar.gz
mv apache-maven-3.6.1/ /opt/
cat /etc/passwd | grep jenkins # 查找 jenkins 用户的主目录,以下假设为 /var/lib/jenkins/
echo 'export PATH=/opt/apache-maven-3.6.1/bin:$PATH' >> /var/lib/jenkins/.bash_profile
chown jenkins:jenkins /var/lib/jenkins/.bash_profile
service jenkins restart
修改先前建立的 Hello World 项目的 Shell Command 为:
echo $JAVA_HOME
echo $PATH
mvn -v
启动手工构建,查看构建结果中的 "Console Output", 验证 maven 版本。
安装 tomcat
安装 tomcat 用于测试应用发布,安装后替换默认监听端口,为部署应用增加管理用户,并重启服务。
apt install tomcat8 tomcat8-admin tomcat8-examples
sed -i.bak 's/8080/8050/g' /etc/tomcat8/server.xml
systemctl restart tomcat8.service
sed -i.bak "/<\/tomcat-users>/i<user username=\"cuilongbo\" password=\"my-secure-password\" roles=\"manager-gui,manager-script,manager-jmx\"\/>" /etc/tomcat8/tomcat-users.xml
在 Ubuntu 18.04.2 LTS 下,还可再安装一个 tomcat9 用于对照:
apt install tomcat9 tomcat9-admin tomcat9-examples
sed -i.bak 's/8080/8060/g' /etc/tomcat9/server.xml
vim /etc/tomcat9/tomcat-users.xml
systemctl restart tomcat9.service
sed -i.bak "/<\/tomcat-users>/i<user username=\"cuilongbo\" password=\"my-secure-password\" roles=\"manager-gui,manager-script,manager-jmx\"\/>" /etc/tomcat9/tomcat-users.xml
为了远程访问 tomcat, 可能还需要在安全组中开启 tomcat 监听端口。
安装 Jenkins 插件
进入 Manage Jenkins » Manage Plugins 页面,安装或检查以下插件:
- Build Pipeline Plugin
- Checkstyle Plug-in
- Copy Artifact Plugin
- Deploy to container
- Git plugin
- GitHub plugin
- Maven Integration plugin
- Pipeline
在 Jenkins 中添加 JDK 和 Maven
进入 Manage Jenkins » Global Tool Configuration 页面,添加 JDK, 取消 Install automatically 选项,输入已在 Ubuntu 中安装的 JDK 的 JAVA_HOME 路径并命名。
图1. Add JDK
在同一页面的 Maven installations 中,单击 "Add Maven", 取消 Install automatically 选项,输入已在 Ubuntu 中安装的 Maven 的 MAVEN_HOME 路径并命名。
图2. Add Maven
Fork 代码库并克隆到本地
为了对代码库有修改权限,登录 GitHub 访问 https://github.com/martinliu/devops-maven 并 Fork, 以下假设 Fork 出的代码库为 https://github.com/cuilongbo/devops-maven.
将代码库克隆到本地,以便于修改测试。
git clone https://github.com/cuilongbo/devops-maven.git
cd devops-maven
基于首次 commit 创建分支 test 用于体验历史提交带来的变化,切换 test 为工作分支,并同步新分支到 GitHub:
git branch test 604a6b2
git checkout test
git push origin test
创建一组 Jenkins 任务并组装成流水线
创建打包任务
在 Jenkins 主页面点击 "New Item" 或 "create new jobs", 输入任务名称 "test-maven-package", 选择 "Maven project", 然后单击 "OK"。
图3. 创建打包任务
在 Source Code Management 页签下选择源代码管理方式为 Git, 并填写 Repository URL, Credentials, Branch Specifier 等信息:
图4. 源代码管理
在 Build 页签下输入 clean package 两条指令:
图5. 构建指令
在 Post Steps 页签下添加类型为 "archive the artifacts" 的构建后动作,输入要打包文件为 '**/*.war'.
图6. 添加构建后动作
单击 "Save" 保存配置, 然后单击 "Build Now" 启动构建,验证构建结果。
创建部署任务
在 Jenkins 主页面点击 "New Item" 或 "create new jobs", 输入任务名称 "test-maven-deploy-to-staging",选择 "Freestyle project", 然后单击 "OK"。
图7. 创建部署任务
在 Build 页签下增加一个类型为 "copy artifacts from another project" 的构建步骤,输入源项目,选择构建和要复制的工件。
图8. 添加构建步骤
在 Post Steps 页签下添加类型为 "deploy war/ear to a container" 的构建后动作,配置 WAR 包文件,路径,增加类型为 Tomcat 8.x 的 Container, 并配置其地址和认证信息。
图9. 添加构建后动作,部署到 tomcat
单击 "Save" 保存配置, 然后单击 "Build Now" 启动构建,验证构建结果,并在浏览器中输入应用 URL 查看应用结果, 在本例子中, URL 为 http://114.111.111.222:8050/test-maven/.
创建代码风格检查任务
在 Jenkins 主页面点击 "New Item", 类似图 7, 输入任务名称 "test-maven-checkstyle", 选择 "Freestyle project", 然后单击 "OK"。
转到 Source Code Management 页签,如同图 4, 选择源代码管理方式为 Git, 并填写 Repository URL, Credentials, Branch Specifier 等信息。
在 Build 页签下增加一个类型为 "Invoke top-level Maven targets" 的构建步骤, Maven version 选择图 2 中配置的 localMaven, Goals 中输入 checkstyle:checkstyle.
单击 "Save" 保存配置, 然后单击 "Build Now" 启动构建,验证构建结果。
创建部署到生产环境任务
该步骤与前面的 "创建部署任务" 一致,只是 Container 的配置为生产环境,任务名称为 "test-maven-deploy-to-prod".
一般来说,生产环境的软件版本应与测试环境一致。为了简便配置,此处选择同一云主机下的 tomcat9 作为生产环境。看起来 "Deploy to container" 插件的 Tomcat 8.x 选项也可用于 Tomcat 9 实例。
创建 Folder 并把以上相关任务移动到其中(可选)
任务太多看起来就会比较混乱。在 Jenkins 主页面点击 "New Item", 类似图 7, 输入名称 "test-maven", 选择 "Folder", 然后单击 "OK" 并单击 "Save" 保存。把上面建立的 4 个任务移动到 test-maven 下。
建立 Jenkins 流程
上面建立的 4 个任务现在都是手动触发的,一般情况下,我们希望:
- 代码库的某个分支出现改动后,自动触发 test-maven-package.
- test-maven-package 成功后自动启动 test-maven-checkstyle 和 test-maven-deploy-to-staging.
- 代码评审和测试通过后,由部署经理手工启动 test-maven-deploy-to-prod.
首先修改 test-maven-package 的配置, 在 Post-build Actions 中添加 Build other projects, 输入下游任务名称 test-maven-checkstyle, test-maven-deploy-to-staging 后单击 "Save" 保存。现在手动触发 test-maven-package, 可以看到 test-maven-package 成功完成后,会触发 test-maven-checkstyle 和 test-maven-deploy-to-staging.
然后修改 test-maven-deploy-to-staging 的配置, 在 Post-build Actions 中添加 Build other projects (manual step), 输入下游任务名称 test-maven-deploy-to-prod 后单击 "Save" 保存。
最后,修改 test-maven-package 的配置, 在 Build Triggers 中勾选 "GitHub hook trigger for GITScm polling", 并且在 https://github.com/cuilongbo/devops-maven/settings/hooks 中增加一个 Webhook. 按照 GitHub Plugin 中的说明, Webhook URL 的格式是 $JENKINS_BASE_URL/github-webhook/, 在本例中 为 http://114.111.111.111:8080/github-webhook/.
现在,合并代码库 https://github.com/cuilongbo/devops-maven 描述信息为 "Update main page" 的那次提交到 test 分支,并 push 到 GitHub:
git merge a980c76
git push origin test
push 成功后就可以看到 test-maven-package, test-maven-checkstyle 和 test-maven-deploy-to-staging 依次被触发,访问测试环境 http://114.111.111.222:8050/test-maven/ 也可以看到代码变更后的效果。
Build Pileline 视图
在 Folder test-maven 下单击 New View 输入视图名称 test-maven-pipeline, 选择 Build Pipeline View, 单击 "OK" 创建 Build Pileline 视图。
在接下来的视图配置页面中,选择 test-maven-package 作为 Initial Job.
图10. 选择 Initial Job
单击 "Save" 保存配置后可以看到创建好的 Build Pileline 视图。
图11. Build Pileline 视图
在 Build Pileline 视图下,可以清楚地看到与项目相关的所有任务以及每项任务的最近一次构建时间、消耗时间、构建状态等信息,并且可以通过点击任务卡片右下角的图标触发重新运行 (re-run) 或触发手工运行 (trigger).
在 CI/CD 的最后一步,部署到生产环境,一般都需要由授权人员确认测试通过手工执行。在 Build Pileline 视图中,单击 test-maven-deploy-to-prod 卡片右下角的 trigger 图标,即可完成生产环境部署。
致谢
感谢刘征老师和在中国DevOps社区济南社区的组织者,让我重新体验到 Jenkins 的魅力。
以上步骤参考刘征老师在中国DevOps社区济南 Meetup 活动上分享的 "用Jenkins实施CI/CD工作坊" 和济南社区的同学分享的笔记整理。