Jenkins 系列3 --- pipeline
一、概要
1. 承上启下
2. 概念
Pipeline用于顺序执行应用部署所需的任务,比如Build(编译)、Test(编译)和Deploy(部署)等。Pipeline是Jenkins的核心组成部分。
Pipeline定义在Jenkinsfile中,它支持两种语法定义,一种是Declarative Pipeline syntax(声明式管道语法),另一种是Scripted Pipeline syntax(脚本式管道语法)。
Pipeline包含以下重要概念:
a. Node(节点)
节点是Jenkins环境的一部分,它用于执行Pipeline。
b. Stage(阶段)
一个Pipeline由若干Stage组成,比较通用的阶段有Build、Test和Deploy。
c. Step(步骤)
Step是Stage的组成部分,一个Step是一个具体的Task,比如执行Shell命令。
3. 官方最佳实践
a. 将JenkinsFile保存在专门的SCM中,Pipeline运行时先签出SCM,加载,然后再按照其中的定义执行;
b. Pipeline中的Stage使用脚本执行,如果全部使用Script则会使Pipeline定义过于复杂且运行时导致资源占用高的问题。
4. 方案设计
(1) Stage(阶段)设计
共设计以下几个阶段:
0. Declarative: Checkout SCM,该阶段是系统自动生成的阶段,用于签出Pipeline定义文件;
a. Initialization: 初始化阶段,工作目录清理,源代码迁出;
b. Build: 源代码编译;
c. Test: 测试阶段,该阶段可以执行TA测试,也可以运行工程师编写的单元测试;
d. Deploy: 部署阶段,该阶段读取配置文件,读取正在运行的服务端口计算出新服务端口,将应用部署至目标服务器,绑定固定端口并运行;
e. Post: 部署完成后阶段,该阶段将修改Nginx配置,将新请求转发至新服务(端口),由前向后(Nginx->Node.js->Java)执行优雅退出;
f. Clear: 清理阶段,将原有服务下线,清理工作目录。
(2) 部署文件
a. 在GitLab中创建一个单独的项目,用于存放以下文件:
i. Pipeline定义文件;
ii. 各个阶段的Shell脚本;
iii. 配置文件;
二、配置
1. 与GitLab集成
(1) 安装插件
a. 登录Jenkins;
b. 进入Dashboard->Manage Jenkins->Plugins,点击"Available plugins",搜索GitLab;
c. 点击"Install without restart",安装GitLab插件,安装完需要重启Jenkins。
(2) Personal Access Tokens
a. 登录GitLab,点击右上角的头像->Edit Profile->Access Token;
b. 设置Token name, Expiration date, Select scopes选择api,点击"Create personal access token";
c. 将顶部的Your new personal access token文本框中的内容保存下来,下面配置Jenkins需要用到;
d. 登录Jenkins,进入Dashboard->Manage Jenkins->Credentials,在Stores scoped to Jenkins下面选择System,再选择Global credentials (unrestricted),点击页面右上角"Add Credentials"按钮:
e. 设置Kind,API Token,ID,其中API Token为上面在GitLab中获取的Personal Access Token,点击"Create"。
(3) SSH Key
a. 在Jenkins的Node/Agent所在的机器上生成SSH密钥对,参考Linux Tools --- SSH;
注意:理论上,所有Node/Agent所在的机器均要生成SSH密钥对,以便访问GitLab签出代码。
b. 分别获取公钥和私钥字符串,并保存下来,后续配置会用到:
cat ~/.ssh/id_rsa #私钥 cat ~/.ssh/id_rsa.pub #公钥
c. 登录GitLab,点击右上角的头像->Edit Profile->SSH Keys:
i. 设置Key为公钥;
ii. 设置Title为生成该公钥的主机名称,比如192.168.0.1部署了Jenkins的Node1,此处可以设置Title为:
<登录名>@<IP> #格式 example@192.168.0.1 #例子
iii. 点击"Add Key"。
注意:理论上,所有Node/Agent所在的机器均要配置,以便访问GitLab签出代码。
d. 登录Jenkins,进入Dashboard->Manage Jenkins->Credentials->System->Global credentials (unrestricted),点击"Add credentials":
Kind选择"SSH Username with private key";
Username是你在GitLab登录并设置公钥的那个账户名;
Key设置为私钥。
(4) 配置Jenkins的GitLab模块
a. 登录Jenkins,进入Dashboard->Manage Jenkins->System,找到GitLab配置节
可点击该配置节右下角的"Test Connection"按钮来测试配置是否正确。
(5) Pipeline
a. 登录Jenkins,进入"Dashboard"页面,点击左上角的"+ New Item"按钮:
点击"OK"进入"Configure"页面。
b. 在"Configure"页面,找到"Pipeline"配置节:
i. Definition选择Pipeline script from SCM,意思是使用存放在GitLab中的Pipeline脚本(Jenkinsfile);
ii. Repository URL填写GitLab中存储Jenkinsfile的项目地址,本例中是jenkins/springboot;
iii. Credentials选择上面"(3) SSH Key"中配置的凭据;
IV: Branches to build填写分支名称;
V: Script Path:是Jenkinfile在项目内的路径。
(6) 测试
a. 登录Jenkins,进入Dashboard->My First Pipeline,点击"Build Now":
2. SSH、GitLab、Jenkins之间的关系
(1 ) SSH
SSH的密钥是主机的凭证,SSH密钥与主机登录账户相对应,比如root账户创建的SSH密钥与jenkins账户创建的SSH密钥完全不同。
在Jenkins系统搭建过程中会多次用到SSH密钥:
a. Jenkins的Master与Node通信需要SSH的配置,上文已经介绍;
b. 主机需要下载源代码或者Jenkinsfile,则需要在GitLab上配置SSH的公钥并在Jenkins中配置对应的私钥,本文2.1.3已介绍;
(2) GitLab
GitLab需要注意账户、项目和SSH之间的关系,总结成一句话就是“配置SSH时的账户需要拥有Jenkins需要部署的项目的权限”。
a. 假设我们用admin这个账号登录GitLab,我们希望配置Jenkins部署test-java这个项目,那么admin账户就需要具备test-java项目的访问权限。
b. 满足a后,使用admin登录GitLab,然后配置Jenkins Master和Node的密钥;
c. 满足a和b之后,使用admin登录GitLab,生成Access Token并配置到Jenkins中。
(3) Jenkins
Jenkins Master节点会在Pipeline执行时下载Jenkinsfile,然后交给Node执行源代码下载、编译和部署。所以必要的配置如下:
a. Jenkins Master
i. 安装Git;
ii. 在Jenkins用户下生成SSH密钥;
iii. 将Jenkins用户下的SSH私钥配置到Jenkins中以便与Node交互;
iv. 将Jenkins用户下的SSH公钥配置到GitLab以便获取Jenkinsfile代码。
b. Jenkins Node
i. 安装Git;
ii. 搭建编译环境,如Java,Node.js,Python等;
iii. 创建专用账户比如jagent并赋予其必要的权限;
iv. 在jagent用户下生成SSH密钥;
v. 将jagent用户下的SSH公钥配置到GitLab中以便获取项目源码。
三、参考
1. 官方
https://www.jenkins.io/doc/book/pipeline/
https://www.jenkins.io/doc/book/pipeline/jenkinsfile/
https://www.jenkins.io/doc/pipeline/examples/
https://www.jenkins.io/doc/book/pipeline/pipeline-best-practices/
https://wiki.jenkins.io/display/JENKINS/Building+a+software+project
https://www.jenkins.io/doc/pipeline/tour/environment/
2. 其他
(1) 获取Shell返回值
https://www.baeldung.com/ops/jenkins-pipeline-output-shell-command-variable
(2) 获取Version信息