惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

博客园 - 白马黑衣

网络安全3 - Easy RSA重新签发客户端证书 RHEL - 笔记本合盖不休眠 RHEL - yum cache JFrog Artifactory 系列6 --- 其他配置 Node.js - 配置npm Rocky Linux 升级失败 Nginx 系列2 --- 配置 Linux --- firewalld 2 - nfttables Linux - DNS Apache HTTP Server 关闭SELinux RHEL - 设置hostname和IP地址 Linux --- 查看PID 判断端口是否已经被占用 Maven 常用命令 Git自签名证书的验证 iptables Jenkins 系列2 --- Node/Agent Jenkins 系列1 --- 安装与配置
Jenkins 系列3 --- pipeline
白马黑衣 · 2023-07-16 · via 博客园 - 白马黑衣

一、概要

1. 承上启下

Jenkins系列

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信息

https://stackoverflow.com/questions/37603619/how-do-i-extract-version-id-from-pom-inside-jenkins-declarative-and-scripted-pip