为了更深入了解 SDLC 流程,更好的将安全融入 SDLC 开发生命周期过程中,近期研究了下基于 Jenkins 搭建一套简易 CI/CD 平台,可以实现代码修改后自动化完成构建和部署的过程。并且将 sonarqube 代码质量管理平台嵌入其中。整个过程做了一遍,对这其中的概念、流程和套路更加清晰了。希望对大家也有帮助。
0x01:SDLC 及软件开发模型
软件开发生命周期(Software Development Life Cycle,SDLC)包含了软件从开始到发布的不同阶段。它定义了一种用于提高待开发软件质量和效率的过程。因此,SDLC 旨在通过最少的资源,交付出高质量的软件。
软件开发生命周期 SDLC 通常被划分为如下六个阶段,如下图:
需求阶段–>设计阶段–>实现阶段–>测试阶段–>发布阶段–>维护阶段
具体每个阶段定义和做的事情就不赘述了。
而软件开发模型的更迭,从最初的瀑布模型,到后来的敏捷开发,再到今天的 DevOps,这是现代开发人员构建出色产品的技术路线。下面快速介绍下这三个软件开发模型以及优缺点。
1)瀑布模型
作为最古老、也是最直接的 SDLC 方法,瀑布方法遵循的是线性执行顺序。如下图所示,从需求收集到维护,逐步依次推进,且不存在任何逆转或倒退的步骤。也就是说,只有当上一步完成后,才能继续下一步。
瀑布模型的优点:
-
需求在初始阶段就能够被精心设计。
-
具有容易理解的线性结构。
-
易于管理。
- 瀑布模型的缺点:
-
既不灵活,又不支持变更。
-
任何阶段一旦出现延迟,都会导致项目无法推进。
-
由于较为死板,因此项目总体时间较长。
-
并不鼓励在初始阶段之后,利益相关者进行积极地沟通。
这样的模型仅适用于那些简单的软件开发, 但是已经不适合现在的开发了。
2)敏捷开发模型
敏捷开发将软件开发分成多个迭代,但是也要求,每次迭代都是一个完整的软件开发周期,必须按照软件工程的方法论,进行正规的流程管理。
敏捷的优势
-
适合不断变化的需求。
-
鼓励利益相关者之间的反馈和持续沟通。
-
由于采用了增量式方法,因此更易于管理各种潜在风险。
敏捷的缺点
-
需要具有高技能的资源。
-
如果沟通低效,则可能拖慢项目的速度。
-
如果过度依赖客户的互动,则可能会导致项目走向错误的方向。
3)DevOps 模型
在传统的软件开发方法中,开发人员和运维人员之间几乎没有协作。特别是在运营过程中,开发人员往往被视为“构建者”的角色。这就造成了沟通和协作上的差距,以及在反馈过程中出现混淆 DevOps 是 Development 和 Operations 的组合,是一种方法论,是一组过程、方法与系统的统称,用于促进应用开发、应用运维和质量保障(QA)部门之间的沟通、协作与整合。以期打破传统开发和运营之间的壁垒和鸿沟。通常,DevOps 方法会被划分为如下 5 个阶段:持续开发、持续集成、持续测试、持续部署和持续监控。
DevOps 的优势
-
促进了合作。
-
通过持续开发和部署,更快地向市场交付软件。
DevOps 的缺点
-
当各个团队使用不同的环境时,将无法保证软件的安全。
-
涉及到人工输入的过程时,可能会减慢整体运营的速度。
0x02:什么是 CI/CD
CI/CD 的核心概念是持续集成、持续交付和持续部署。CI 持续集成(Continuous Integration)、CD 持续交付(Continuous Delivery)、CD 持续部署(Continuous Deployment)。
1)持续集成(CI)
CI 的目标是将集成简化成一个简单、易于重复的日常开发任务, 这样有助于降低总体的构建成本并在开发周期的早期发现缺陷。
完成 CI 中构建及单元测试和集成测试的自动化流程后,持续交付可自动将已验证的代码发布到存储库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。持续交付的目标是拥有一个可随时部署到生产环境的代码库。
3)持续部署(CD)
0x03:CI/CD 环境介绍
本次要实现如下效果,开发人员完成功能开发并提交代码到 gitlab 仓库,jenkins 自动完成拉取代码、编译构建、代码扫描(sonarqube)、打包,再自动化完成部署到 Tomcat 服务器提供访问。
环境准备三台 Centos7.6 机器:
服务器 |
IP 地址 |
配置 |
包含功能及版本 |
Gitlab |
192.168.220.170 | 2 核 2G |
Gitlab:12.4.2 (393a5bdafa2) |
Jenkins |
192.168.220.172 | 2 核 2G | Jenkins:2.364
Maven:3.8.6 Sonarqube:7.9.6 (build 41879) JDK:11.0.16 Git:1.8.3.1 |
Tomcat |
192.168.220.173 | 2 核 2G | Tomcat:8.5.82
JDK:1.8.0_342 |
部署过程中踩过不少坑,这套 Jenkins 因为需要安装较多插件,而 Jenkins 上的插件版本要求比较严格,所以最好实验情况下直接安装最新的 Jenkins 版本,这样上面的插件基本都能安装,包括 Pipeline、gitlab、SSH Server 等。不然遇到 Jenkins 插件安装不顺畅对新人挺麻烦的。
Jenkins 安装最新版,那 JDK 也必须 11 以上,那也就要求 sonarqube 也得 7.8 以上,三者之间都是有依赖关系的。
看下效果:
自动 git 拉取代码:
maven 自动构建:
sonarqube 自动扫描:
自动部署:
sonarqube 扫描结果:
0x04:CI/CD 平台搭建
1)安装 gitlab
1. 安装相关依赖
yum -y install policycoreutils openssh-server openssh-clients postfix
2. 启动 ssh 服务&设置为开机启动
systemctl enable sshd && sudo systemctl start sshd
3. 设置 postfix 开机自启,并启动,postfix 支持 gitlab 发信功能
systemctl enable postfix && systemctl start postfix
4. 开放 ssh 以及 http 服务,然后重新加载防火墙列表
firewall-cmd --add-service=ssh --permanent
firewall-cmd --add-service=http --permanent
firewall-cmd --reload
如果关闭防火墙就不需要做以上配置
5. 下载 gitlab 包,并且安装
在线下载安装包:
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el6/gitlab-ce-12.4.2-ce.0.el6.x
86_64.rpm
安装:
rpm -i gitlab-ce-12.4.2-ce.0.el6.x86_64.rpm
6. 修改 gitlab 配置
vi /etc/gitlab/gitlab.rb
修改 gitlab 访问地址和端口,默认为 80,我们改为 82
external_url 'http://192.168.220.170:82'
nginx['listen_port'] = 82
7. 重载配置及启动 gitlab
gitlab-ctl reconfigure
gitlab-ctl restart
8. 把端口添加到防火墙
firewall-cmd --zone=public --add-port=82/tcp --permanent
firewall-cmd --reload
启动成功后,看到以下修改管理员 root 密码的页面,修改密码后,然后登录即
添加组、创建用户、创建项目
这样用户 zhangsan 就拥有了 itheima_group 组的权限。接下来使用 zhangsan 用户进入组创建一个新的项目,项目名称:hello_demo
该项目仓库地址是:
http://192.168.220.170:82/itheima_group/hello-demo.git
git@192.168.220.170:itheima_group/hello-demo.git
接下来将本地的 maven 工程代码上传到 gitlab 仓库,上传成功后如下:
到这 gitlab 就准备好了!
2)安装 jenkins
1)安装 JDK
Jenkins 需要依赖 JDK,所以先安装 JDK11
yum install -y java-11-openjdk*
安装目录为:/usr/lib/jvm
2)获取 jenkins 安装包
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo --no-check-certificate
rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
yum install jenkins
3)启动 Jenkinssystemctl start jenkins
4)打开浏览器访问
http://192.168.220.172:8080
注意:本服务器把防火墙关闭了,如果开启防火墙,需要在防火墙添加端口
5)获取并输入 admin 账户密码
cat /var/lib/jenkins/secrets/initialAdminPassword
6)跳过插件安装
因为 Jenkins 插件需要连接默认官网下载,速度非常慢,而且经过会失败,所以我们暂时先跳过插件安
Jenkins 安装完成后,需要替换插件更新源:需要执行以下步骤:
sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && sed -i 's/https:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
在 Manage Jenkins -- Plungin Manager -- Update Site:将 url 替换为清华大学的 url:
https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
提交后,在浏览器输入:http://192.168.220.172.:8080/restart 重启 jenkins 生效。
Jenkins 准备好后,就是与 gitlab 集成,完成代码自动拉取的动作了。但是需要先准备如下:
安装 Credentials Binding 插件
要在 Jenkins 使用凭证管理功能,需要安装 Credentials Binding 插件,拉取 gitlab 代码需要使用凭证的方式拉取:
再去添加 gitlab 认证的凭证:
还要再 jenkins 服务器上安装 git 工具和 git 插件:
在 jenkins 上准备一个项目:
到这里,jenkins 拉取 gitlab 代码的准备条件都 ok 了。开始与 gitlab 集成吧。
保存,然后回到项目点“Build Now”:
如上图,jenkins 自动去 gitlab 拉取代码,并且将代码工程放在如上路径下:
好了,到这里说明 jenkins 已经安装成功了,也安装了相关的插件和配置了 jenkins 的基本配置,并且完成了与 gitlab 的集成,完成构建自动触发代码拉取到本地。
3)部署 Tomcat 服务器
把 Tomcat 压缩包上传到 192.168.66.102 服务器
yum install java-1.8.0-openjdk* -y 安装 JDK(已完成)
tar -xzf apache-tomcat-8.5.47.tar.gz 解压
mkdir -p /opt/tomcat 创建目录
mv /root/apache-tomcat-8.5.47/* /opt/tomcat 移动文件
/opt/tomcat/bin/startup.sh 启动 tomcat
注意:服务器已经关闭了防火墙,所以可以直接访问 Tomcat 啦
地址为:http://192.168.66.102/8080
# 对 tomcat 做些基本配置,包括用户角色权限配置等
/opt/tomcat/bin/shutdown.sh 停止
/opt/tomcat/bin/startup.sh 启动
tomcat 已经部署成功!
4)配置 jenkins 与 tomcat 集成,完成 CD 持续部署功能
同样的,也是需要在 jenkins 上做大量的配置:
Maven 安装和配置
tar -xzf apache-maven-3.6.2-bin.tar.gz 解压
mkdir -p /opt/maven 创建目录
mv apache-maven-3.6.2/* /opt/maven 移动文件
配置环境变量
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export MAVEN_HOME=/opt/maven
export PATH=$PATH:$JAVA_HOME/bin:$MAVEN_HOME/bin
Jenkins 全局工具配置,关联 JDK 和 Maven
添加 Jenkins 全局变量
准备好后,来测试 Maven 构建是否生效,还是用刚刚的项目:hello_web
可以看到,项目构建成功。可以去服务器上看到 war 包已经生成。
war 可以自动编译,还差自动部署了,有需要配置一些步骤:
安装 Deploy to container 插件
添加 Tomcat 凭证
jenkins 项目配置构建后操作
保存配置,点“Build Now”:
可以看到项目成功部署,可以正常访问。