“本文用图文示例了一个从零开始以 Linux + Jenkins + Gitee 为组合的持续化集成的部署实践,包括软件安装、项目权限、任务搭建、脚本编写等。
背景
手里有一个项目,最开始只有我自己维护,由 开发->部署->上线
均由我一个人完成。实际的应用场景为:本地开发、gitee 源码存储 + 版本控制、服务器 git 获取源码、服务器编译代码、项目正式上线可访问。
慢慢的随着项目的发展,开发人员多了一个,这个时候就涉及到两个人分别开发不同功能分别上线的情况,流程变成了 开发(并行)->测试(并行)->部署(随时)->上线(随时)
,不再完全由一个人来决定每一个路径的执行(当然强制由一个人也不是不行),因为完全取决于一个人来控制部署->上线
的流程,会严重影响协作的流畅性。比如,当开发者需要部署时,就必须要另一个流程控制人实时能够进入服务器、拉取代码、执行编译命令。而这个流程控制人,完全没有了独立的时间去做别的事,被绑定在了当前迭代上,尤其是短时间内需要频繁操作时,会很占用资源。
这是我在个人小项目中体会到的实实在在的痛点,这也加深了我对团队中引入持续集成(CI)的理解和认知。但本篇不对原理性的内容做过多说明,而更多注重实践,即如何从零搭建一个可正常使用的 Jenkins 环境及构建任务。
目录
环境简介
- Jenkins 最新版本
- 腾讯云服务器(标准型SA2)(最便宜的那档就可以,阿里云也可)
- Linux 系统:CentOS Linux release 7.6.1810 (Core)
- 代码仓库:Gitee 服务(也可用 Github,对应配置方法类似)
安装 Jenkins
1、 选择清华大学镜像下载(其他版本请查看:https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/)
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.222.3-1.1.noarch.rpm
2、yum 安装
yum install -y jenkins-2.222.3-1.1.noarch.rpm
3、java 安装
yum -y install java-1.8.0-openjdk
4、启动 jenkins 服务
systemctl start jenkins
5、访问 jenkins
// 在浏览器中默认打开如下地址即可,如果你有单独配置对应的域名,也可直接访问域名
http://你的服务器ip:8080/
6、获取 jenkins 密码
cat /var/lib/jenkins/secrets/initialAdminPassword
7、配置插件安装的国内镜像地址(为了加快在安装拓展的速度)
vi /var/lib/jenkins/hudson.model.UpdateCenter.xml
// 打开文件直接修改为:<url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>
// 重启服务即可
// 此处依然用的清华大学的,如果有特殊需求,可以考虑其他镜像地址
8、安装权限管理插件,Role-based Authorization Strategy
“上述步骤省略了如何操作 Jenkins 界面,原因是由于 Jenkins 已然是一个比较完善的系统,如果需要 Jenkins 细节操作说明,可以参考官方文档 (https://www.jenkins.io/zh/doc/)
配置 Jenkins (角色、项目权限)
1、进入系统管理 -> 全局安全配置->授权策略(Strategy)
2、选择 Role-Based Strategy
,点击保存
3、进入系统管理 -> Manage And Assign Roles
4、管理角色:进入 Manage Roles
5、配置一个 Global Roles -> base roles
,仅配置 全部 -> Read 权限
,用于基础用户的查看视图权限
6、配置一个 Project Roles (新版本的 Jenkins 改名为 Item roles ) ,作用一样 ,设置完后保存
- 添加一个项目权限
JenkinsTestProject
- 正则匹配所有
JenkinsTestProject
开头的项目,写法为Pattern : JenkinsTestProject.*
7、创建角色:进入系统管理 -> 管理用户 -> 创建对应的角色
即可
8、分配角色:进入系统管理 -> Manage And Assign Roles -> Assign Roles
,设置完后 保存
- 分配 Global roles ,全局权限
- 分配 Item roles ,项目权限
9、测试对应权限是否正常
- 新建一个任务
- 再创建项目权限,用于对比测试
- 给
lisi
分配权限( 注意:如果不分配base roles
,则会发现,lisi
登录之后不可查看任何数据 )
- 给
lisi
分配权限
- 登录
zhangsan
的账号,查看其对应的任务
- 登录
lisi
的账号,查看其对应的任务
- 至此角色权限、项目权限的配置已配置完毕
配置 Gitee
安装 Git : yum -y install git
安装 Gitee 插件
“详细配置及解答,参考 gitee 官方教程 :(https://gitee.com/help/articles/4193)
核心步骤如下:
1、前往 Jenkins -> Manage Jenkins -> Configure System -> Gitee Configuration -> Gitee connections
2、在 Connection name
中输入 Gitee
或者你想要的名字
3、Gitee host URL
中输入码云完整 URL 地址: https://gitee.com
(码云私有化客户输入部署的域名)
4、Credentials
中如还未配置码云 APIV5 私人令牌
,点击 Add - > Jenkins
Domain
选择Global credentials
Kind
选择Gitee API Token
Scope
选择你需要的范围Gitee API Token
输入你的码云私人令牌,获取地址:https://gitee.com/profile/personal_access_tokens
ID
Descripiton
中输入你想要的ID
和描述
即可
5、Credentials
选择配置好的 Gitee APIV5 Token
6、点击 Advanced
,可配置是否忽略 SSL
错误(适您的 Jenkins 环境是否支持),并可设置链接测超时时间(适您的网络环境而定)
7、点击 Test Connection
测试链接是否成功,如失败请检查以上 3,5,6 步骤。
配置任务(任务搭建、脚本编写)
1、拉取代码至 workspace
新建任务->配置->源码管理
- 选择
Git
- 输入对应的
Repository URL
- 设置好之后,点击对应的构建任务,即可正常拉取分支至
Jenkins
的workspace
2、设置 Jenkins
服务器和目标服务器之间的免密登录
- 在 jenkins 服务器上操作如下:
ssh-keygen -t rsa -P ''
ssh-copy-id -i ~/.ssh/id_rsa.pub <IP>
- 其中,
<IP>
为目标服务器 - 验证,在
Jenkins
所在服务器上,直接通过ssh <IP>
的方式即可正常登录目标服务器
3、设置 jenkins shell
4、执行任务,点击立即构建
5、查看控制台输出
6、此时会有对应的报错信息
错误原因是
Jenkins
默认使用Jenkins
用户去启动,然而Jenkins
用户没有权限去执行ssh
免密登陆进入
Jenkins
服务器,切换Jenkins
系统用户,发现切换失败,仍然是root
账号查看无法切换
Jenkins
用户的问题,猜测是/etc/passwd
文件中的/bin/bash
被yum
安装的时候变成了/bin/false
修改
Jenkins
的/bin/false` 为
/bin/bash`- 执行
vim /etc/passwd
- 修改
Jenkins
的 ``/bin/false为
/bin/bash`
- 执行
再次执行
su jenkins
,输出如下,原因是在安装Jenkins
时,Jenkins
只是创建了Jenkins
用户,并没有为其创建home
目录
- 解决方法如下:
- 执行
vim ~/.bash_profile
- 在最后一行加入
export PS1='[\u@\h \W]\$'
- 保存后执行
source ~/.bash_profile
- 执行
- 验证是否成功,
su jenkins
- 此时
Jenkins
用户还不能进行ssh
免密登录,所以后续需要对Jenkins
用户添加免密登录 Jenkins
用户使用sudo
命令的配置- 切换
root
用户:su root
- 执行命令
sudo visudo
- 在文件末尾加上一行
jenkins ALL=(ALL) NOPASSWD: ALL
- 此时
Jenkins
用户可支持使用sudo
命令
- 切换
- 生成
Jenkins
用户的密钥对,切换用户为Jenkins
ssh-keygen -t rsa -P ''
ssh-copy-id -i ~/.ssh/id_rsa.pub <user>@<IP>
- 其中
<user>@<IP>
示例为:root@192.168.1.1
- 再次执行
Jenkins
构建任务,仍会报错
- 原因是,
Jenkins
服务器上,Jenkins
用户设置的免密登录,是对目标服务器的root
用户而言,所以需要在对应的命令中都加入root
用户,否则会默认进行目标服务器的Jenkins
用户登录 - 修改构建任务的
shell
如下
- 再次构建,任务成功
建议
- 在上述步骤中,配置
Jenkins
用户的相关免密权限时,如果不修改shell
,则可以将Jenkins
的默认启动用户由Jenkins
用户改为root
,也可以正常启动 - 上述示例中,使用的是单点服务的
node
服务构建任务配置,如果有集群需求,则应该考虑多点集群、负载等构建方案 - 如果仅为纯静态的前端项目,可以将打包(
npm run build
) 类似的操作写入shell
中,打包完成后,再使用类似示例最开始的文件推送一样同步到目标服务器
杂谈
以下的内容均为个人观点,仅供参考
由于本人自身是做前端开发的,所以很多相关的示例都是基于前端考虑。针对 server 相关的部署策略,还有更多挖掘的空间。比如如何考虑集群部署、负载部署等等。
就个人经验而言,其实 Jenkins 所解决的问题本质上是让更多原来由人工操作的流程,完全变为简单的 UI 交互系统,通过脚本化的实现方案,代替了人工的手动输入。在解放开发&运维人员双手的同时也避免了人工操作容易出现错误的场景。
在软件工程中,我们常常会引入 CI/CD (持续集成/持续交付) 的概念,在我看来它们并不神秘,相反它们有着实打实的应用空间。但只有当我们在软件工程中遭遇了其相对应的痛点,才会有更深刻的体会和理解。
浏览知识共享许可协议
本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。