Jenkins是一个广泛用于持续构建的可视化web工具,持续构建说得更直白点,就是各种项目的"自动化"编译、打包、分发部署。jenkins可以很好的支持各种语言(比如:java, c#, php等)的项目构建,也完全兼容ant、maven、gradle等多种第三方构建工具,同时跟svn、git能无缝集成,也支持直接与知名源代码托管网站,比如github、bitbucket直接集成
Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行(这个比较抽象,暂且写上,不做解释)。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle
Jenkins 能实施监控集成中存在的错误,提供详细的日志文件和提醒功能,还能用图表的形式形象地展示项目构建的趋势和稳定性
简单点说:Jenkins其实就是大的框架集,可以整个任何你想整合的内容,实现公司的整个持续集成体系!如:自动化,性能,打包,部署,发布&发布结果自动化验证,接口测试,单元测试
Jenkins可自由部署在各平台:Windows, Linux, Mac
CI / CD的采用改变了开发人员和测试人员如何发布软件
最初是瀑布模型,后来是敏捷开发,现在是DevOps,这是现代开发人员构建出色的产品的技术路线。随着DevOps的兴起,出现了持续集成(Continuous Integration)、持续交付(Continuous Delivery) 、持续部署(Continuous Deployment) 的新方法。传统的软件开发和交付方法正在迅速变得过时。从历史上看,在敏捷时代,大多数公司会每月,每季度,每两年甚至每年发布部署/发布软件。然而,现在,在DevOps时代,每周,每天,甚至每天多次是常态。当SaaS正在占领世界时,尤其如此,您可以轻松地动态更新应用程序,而无需强迫客户下载新组件。很多时候,他们甚至都不会意识到正在发生变化。开发团队通过软件交付流水线(Pipeline)实现自动化,以缩短交付周期,大多数团队都有自动化流程来检查代码并部署到新环境。今天,我们将介绍什么是CI / CD / CD,以及现代软件公司如何使用工具将部署代码的流程自动化
持续集成的重点 是将各个开发人员的工作集合到一个代码仓库中。通常,每天都要进行几次,主要目的是尽早发现集成错误,使团队更加紧密结合,更好地协作。
持续交付的目的 是最小化部署或释放过程中固有的摩擦。它的实现通常能够将构建部署的每个步骤自动化,以便任何时刻能够安全地完成代码发布(理想情况下)。
持续部署 是一种更高程度的自动化,无论何时对代码进行重大更改,都会自动进行构建/部署
缩略词 CI / CD 具有几个不同的含义。CI/CD 中的“CI”始终指持续集成,它属于开发人员的自动化流程。成功的 CI 意味着应用代码的新更改会定期构建、测试并合并到共享存储库中。该解决方案可以解决在一次开发中有太多应用分支,从而导致相互冲突的问题。
CI/CD 中的“CD”指的是持续交付和/或持续部署,这些相关概念有时会交叉使用。两者都事关管道后续阶段的自动化,但它们有时也会单独使用,用于说明自动化程度。
持续交付通常是指开发人员对应用的更改会自动进行错误测试并上传到存储库(如 GitHub 或容器注册表),然后由运维团队将其部署到实时生产环境中。这旨在解决开发和运维团队之间可见性及沟通较差的问题。因此,持续交付的目的就是确保尽可能减少部署新代码时所需的工作量。
持续部署(另一种“CD”)指的是自动将开发人员的更改从存储库发布到生产环境,以供客户使用。它主要为了解决因手动流程降低应用交付速度,从而使运维团队超负荷的问题。持续部署以持续交付的优势为根基,实现了管道后续阶段的自动化。
持续集成(CI)可以帮助开发人员更加频繁地(有时甚至每天)将代码更改合并到共享分支或“主干”中。一旦开发人员对应用所做的更改被合并,系统就会通过自动构建应用并运行不同级别的自动化测试(通常是单元测试和集成测试)来验证这些更改,确保这些更改没有对应用造成破坏。这意味着测试内容涵盖了从类和函数到构成整个应用的不同模块。如果自动化测试发现新代码和现有代码之间存在冲突,CI 可以更加轻松地快速修复这些错误
要求
优点
完成 CI 中构建及单元测试和集成测试的自动化流程后,持续交付可自动将已验证的代码发布到存储库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。持续交付的目标是拥有一个可随时部署到生产环境的代码库
CD 集中依赖于部署流水线,团队通过流水线自动化测试和部署过程。此流水线是一个自动化系统,可以针对构建执行一组渐进的测试套件。CD 具有高度的自动化,并且在一些云计算环境中也易于配置。在流水线的每个阶段,如果构建无法通过关键测试会向团队发出警报。否则,将继续进入下一个测试,并在连续通过测试后自动进入下一个阶段。流水线的最后一个部分会将构建部署到和生产环境等效的环境中。这是一个整体的过程,因为构建、部署和环境都是一起执行和测试的,它能让构建在实际的生产环境可部署和可验证
要求
优点
对于一个成熟的 CI/CD 管道来说,最后的阶段是持续部署。作为持续交付——自动将生产就绪型构建版本发布到代码存储库——的延伸,持续部署可以自动将应用发布到生产环境。由于在生产之前的管道阶段没有手动门控,因此持续部署在很大程度上都得依赖精心设计的测试自动化。
实际上,持续部署意味着开发人员对应用的更改在编写后的几分钟内就能生效(假设它通过了自动化测试)。这更加便于持续接收和整合用户反馈。总而言之,所有这些 CI/CD 的关联步骤都有助于降低应用的部署风险,因此更便于以小件的方式(而非一次性)发布对应用的更改。不过,由于还需要编写自动化测试以适应 CI/CD 管道中的各种测试和发布阶段,因此前期投资还是会很大
// 关闭防火墙
[root@localhost ~]# systemctl stop --now firewalld
[root@localhost ~]# vi /etc/selinux/config
SELINUX=disabled
[root@localhost ~]# setenforce 0
[root@localhost ~]# getenforce
Disabled
// jenkins基于网页服务,所以先部署tomcat
[root@localhost ~]# yum -y install java-17-openjdk* // 安装jdk环境
[root@localhost ~]# wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.54/bin/apache-tomcat-9.0.54.tar.gz // 下载tomcat
[root@localhost ~]# tar xf apache-tomcat-9.0.54.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/
[root@localhost local]# ls
apache-tomcat-9.0.54 etc include lib64 sbin src
bin games lib libexec share
[root@localhost local]# mv apache-tomcat-9.0.54 tomcat
[root@localhost local]# ls
bin etc games include lib lib64 libexec sbin share src tomcat
[root@localhost ~]# /usr/local/tomcat/bin/catalina.sh start
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 1 [::ffff:127.0.0.1]:8005 *:*
LISTEN 0 100 *:8080 *:*
LISTEN 0 128 [::]:22 [::]:*
// 下载jenkins
[root@localhost ~]# wget https://get.jenkins.io/war-stable/2.303.2/jenkins.war
[root@localhost ~]# ls
anaconda-ks.cfg jenkins.war
// 将webapps下的其他项目删除
[root@localhost tomcat]# mv webapps/ROOT/ /opt/
[root@localhost tomcat]# rm -rf webapps/*
[root@localhost webapps]# mv /opt/ROOT .
[root@localhost webapps]# ls
ROOT
[root@localhost local]# mv tomcat jenkins // 将tomcat重命名为jenkins
[root@localhost local]# ls
bin etc games include jenkins lib lib64 libexec sbin share src
[root@localhost local]# cd jenkins/webapps/ROOT/
[root@localhost ROOT]# ls
asf-logo-wide.svg bg-nav.png index.jsp tomcat.svg
bg-button.png bg-upper.png RELEASE-NOTES.txt WEB-INF
bg-middle.png favicon.ico tomcat.css
[root@localhost ROOT]# rm -rf *
[root@localhost ROOT]# ls
[root@localhost ROOT]#
[root@localhost webapps]# ls // 将jenkins的war包放到webapps
jenkins.war ROOT
[root@localhost webapps]# ../bin/catalina.sh start // 直接启动服务
Using CATALINA_BASE: /usr/local/jenkins
Using CATALINA_HOME: /usr/local/jenkins
Using CATALINA_TMPDIR: /usr/local/jenkins/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/jenkins/bin/bootstrap.jar:/usr/local/jenkins/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
[root@localhost webapps]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 100 *:8080 *:*
LISTEN 0 128 [::]:22 [::]:*
[root@localhost webapps]# ls
jenkins jenkins.war ROOT
// 密码文件
[root@localhost ~]# cat /root/.jenkins/secrets/initialAdminPassword
a9ee7d265d10436894bae0ff9af9e49b
mvn clean package // 将代码打包成war
// 从代码仓库拉取代码
[root@jenkins ~]# git clone https://gitee.com/forgotten/tomcat-java-demo.git
[root@jenkins ~]# git clone https://gitee.com/forgotten/tomcat-java-demo.git
正克隆到 'tomcat-java-demo'...
remote: Enumerating objects: 558, done.
remote: Counting objects: 100% (558/558), done.
remote: Compressing objects: 100% (316/316), done.
remote: Total 558 (delta 217), reused 558 (delta 217), pack-reused 0
接收对象中: 100% (558/558), 5.08 MiB | 704.00 KiB/s, 完成.
处理 delta 中: 100% (217/217), 完成.
[root@jenkins ~]# ls
anaconda-ks.cfg apache-tomcat-9.0.54.tar.gz jenkins.war tomcat-java-demo
// 把代码打包
[root@jenkins opt]# ls
tomcat-java-demo
[root@jenkins opt]# cd tomcat-java-demo/
[root@jenkins tomcat-java-demo]# ls
db deploy.yaml Dockerfile jenkinsfile LICENSE pom.xml README.md src
[root@jenkins tomcat-java-demo]# yum -y install maven
[root@jenkins tomcat-java-demo]# mvn clean package // 打包
[root@jenkins tomcat-java-demo]# ls
db Dockerfile LICENSE README.md target //刚刚的打包文件
deploy.yaml jenkinsfile pom.xml src
[root@jenkins tomcat-java-demo]# ls target/
classes ly-simple-tomcat-0.0.1-SNAPSHOT maven-archiver
generated-sources ly-simple-tomcat-0.0.1-SNAPSHOT.war maven-status
// 做jenkins和tomcat的免密登录
[root@jenkins ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:WdJ92NrXDS8K2fOIOmENEoLSZ07p39V/Km8Mq2Dzr4I root@jenkins
The key's randomart image is:
+---[RSA 3072]----+
| . . . |
|. o * . . . o |
| . * . .. o.o + |
| o . .+.o.+ oo|
| . oS+o +.o =|
| . + .o.=.o.|
| o+.. o+.o |
| E.o= o + |
| .o++.+. |
+----[SHA256]-----+
[root@jenkins ~]# ssh-copy-id [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.25.147 (192.168.25.147)' can't be established.
ECDSA key fingerprint is SHA256:1RKF1dDMiNk1NgpQCf2BP231oK3MOjFXoSDgRJ2FeS4.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
// 将jenkins中要发布的ly-simple-tomcat-0.0.1-SNAPSHOT.war传到tomcat的/usr/local/tomcat/webapps中
[root@jenkins target]# mv ly-simple-tomcat-0.0.1-SNAPSHOT.war myapp.war
[root@jenkins target]# ls
classes ly-simple-tomcat-0.0.1-SNAPSHOT maven-status
generated-sources maven-archiver myapp.war
[root@jenkins target]# scp myapp.war [email protected]:/usr/local/tomcat/webapps
myapp.war 100% 17MB 138.3MB/s 00:00
[root@tomcat webapps]# ls
docs examples host-manager manager myapp myapp.war ROOT test
// 备份目标服务
[root@tomcat ~]# mkdir /opt/backup // 创建备份目录
[root@jenkins ~]# ssh [email protected] 'tar Jcf /opt/backup/myapp-$(date +%Y%m%d).tar.xz /usr/local/tomcat/webapps/myapp' // 备份是在源服务器上进行
tar: 从成员名中删除开头的“/”
[root@tomcat ~]# ls /opt/backup/
myapp-20211019.tar.xz
创建一个项目测试
jenkins拉取代码并打包
直接完整部署
从私有仓库拉取代码
将生成的用户名和密码脚本加入到流水线脚本中即可
pipeline {
agent any
stages {
stage('Build') {
steps {
// Get some code from a GitHub repository
//git 'https://gitee.com/forgotten/tomcat-java-demo.git'
git credentialsId: '9d96942c-7a82-49b7-8fcb-c593b42456e1', url: 'https://gitee.com/jj1310/tomcat-java-demo.git'
// Run Maven on a Unix agent.
sh "mvn -Dmaven.test.failure.ignore=true clean package"
sh "mv target/ly-simple-tomcat-0.0.1-SNAPSHOT.war target/myapp.war"
// To run Maven on a Windows agent, use
// bat "mvn -Dmaven.test.failure.ignore=true clean package"
}
}
stage('publish'){
steps{
sh "ssh [email protected] 'tar Jcf /opt/backup/myapp-\$(date +%Y%m%d).tar.xz /usr/local/tomcat/webapps/myapp'"
sh "scp target/myapp.war [email protected]:/usr/local/tomcat/webapps/"
sh "ssh [email protected] '/usr/local/tomcat/bin/catalina.sh stop;sleep 3;/usr/local/tomcat/bin/catalina.sh start'"
}
}
}
}