全栈应用指南 | 图文实战 Linux + Jenkins + Gitee 落地持续集成部署

2,850 阅读8分钟

本文用图文示例了一个从零开始以 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

  • 设置好之后,点击对应的构建任务,即可正常拉取分支至 Jenkinsworkspace

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/bashyum 安装的时候变成了 /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 国际许可协议进行许可。