“本文用图文示例了一个从零开始以 Linux + Jenkins + Gitee 为组合的持续化集成的部署实践,包括软件安装、项目权限、任务搭建、脚本编写等。
手里有一个项目,最开始只有我自己维护,由 开发->部署->上线
均由我一个人完成。实际的应用场景为:本地开发、gitee 源码存储 + 版本控制、服务器 git 获取源码、服务器编译代码、项目正式上线可访问。
慢慢的随着项目的发展,开发人员多了一个,这个时候就涉及到两个人分别开发不同功能分别上线的情况,流程变成了 开发(并行)->测试(并行)->部署(随时)->上线(随时)
,不再完全由一个人来决定每一个路径的执行(当然强制由一个人也不是不行),因为完全取决于一个人来控制部署->上线
的流程,会严重影响协作的流畅性。比如,当开发者需要部署时,就必须要另一个流程控制人实时能够进入服务器、拉取代码、执行编译命令。而这个流程控制人,完全没有了独立的时间去做别的事,被绑定在了当前迭代上,尤其是短时间内需要频繁操作时,会很占用资源。
这是我在个人小项目中体会到的实实在在的痛点,这也加深了我对团队中引入持续集成(CI)的理解和认知。但本篇不对原理性的内容做过多说明,而更多注重实践,即如何从零搭建一个可正常使用的 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/)
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
,设置完后 保存
9、测试对应权限是否正常
lisi
分配权限( 注意:如果不分配 base roles
,则会发现,lisi
登录之后不可查看任何数据 )
lisi
分配权限
zhangsan
的账号,查看其对应的任务
lisi
的账号,查看其对应的任务
安装 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
服务器和目标服务器之间的免密登录
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 国际许可协议进行许可。