之前项目刚刚起步,所有的前后端项目上测试环境,上正式环境都是在本地去打包,然后传到服务器上去启动。这就非常麻烦,这样的一个很大的缺点是不方便代码的管理,在本地打包,如果打包的人代码没提交,下次上线,另外一个人打包可能就有代码缺失的风险,多搞几次,都不知道线上代码到底是什么样了。而且有的是要横向部署多个,手动传包就更麻烦。于是我这边就研究了自动部署的方法,然后就可以省些这种麻烦的事。
首先什么是CI,CD
- CI : Continuous Integration
持续集成,主要是在代码提交后,自动执行一些测试案例,和代码质量扫描。
保证本次代码提交没问题
- CD : Continuous Deployment
自动部署,主要是代码检查过后,然后就会自动部署到测试环境,或者正式环境。
把打包,备份,停止,启动等等操作让机器自动执行。
这篇文章的目的,就是让大家了解自动部署,然后可以手动搭建一套包括代码质量扫描,自动部署的一套代码管理平台应用(通过gitlab-ci
),以及了解自动部署相关代码分支管理的东西。(在提交代码的时候,使用sonar
扫描java
代码,生成代码质量分析报告,然后再自动部署项目的方法。)
代码管理
我们所有的代码都是基于 gitlab
去管理的,所以这里默认你有一个搭建好的 gitlab
服务。
技术选型
现在最主流的ci,cd软件是jenkins
, 以前的方案也是使用jenkins
,我觉得它很好,功能齐全,插件很多,但是我觉得他比较重量级,如果团队规模大,运维测试团队分离,使用jenkins
会更合适。而我们团队规模不大,上线,上测试基本都是开发自己去完成,基本是 dev-ops
的开发模式,我这里经过调研后就选择了更轻量级的gitlab-ci
,在能完成我们所需所有功能的前提下更方便我们使用。
gitlab-ci的优点
- 和
gitlab
高度耦合,支持非常好(gitlab上就有ci-cd和脚本执行过程等等很多写好的页面,直接使用) - 只需要安装一个
gitlab-ci-runner
, 安装非常简单 - 所有部署的脚本都是基于
.gitlab-ci.yml
去执行,只要会写脚本,那么这里可以通过shell
脚本做任何事情,控制感非常强
在开始部署使用之前,我想说一下自动部署的原理和流程
先手动部署的流程
- 我们开发,写代码
- 可能这里需要跑测试用例以及代码扫描
- 本地执行命令打包(例如jar包,这里需要有相关的软件环境如maven)
- 手动传包到服务器的对应地方
- 然后手动执行重启脚本
- 部署完成
我们就是要把上面的一系列的动作全部自动交给机器去执行。然后触发的机制就gitlab
上代码的变动。(把本地打包,传包,停止应用,启动应用的步骤交给机器脚本执行)
代码管理机制
当使用自动部署以后,代码就得比较严格的管理起来,因为自动部署都是通过分支上代码的变动来触发的,如果代码随意变动,就会导致自动部署的误触。
-
gitlab
上dev
和master
的分支的代码都需要被保护起来,只能通过merge-request
合并。不能直接push,而且合并只能是有权限的管理员才能操作,需要审核代码。 -
dev
的代码merge
了以后,自动部署到测试环境,master
的代码merge
了以后,自动部署到正式环境。
接下来就开始搭建自动部署平台的步骤
- 1.安装
gitlab-ci-runner
- 2.把
runner
注册到gitlab
- 3.在项目根目录添加一个
.gitlab-ci.yml
- 4.搭建
sonar
扫描平台 - 5.完成的
.gitlab.yml
的演示
1.安装gitlab-ci-runner
首先要明白runner
的概念,当代码提交后,需要执行一段代码,去完成自动部署的逻辑。那么如果执行这段逻辑呢,就得通过 runner
,也就是为每个项目配置一个runner
,提交了项目代码后,runner
就会去触发那段逻辑。
安装
#安装依赖
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
# 安装 gitlab-ci-runner
yum install gitlab-ci-multi-runner
# 常用命令
gitlab-ci-multi-runner status -- 查看安装状态
gitlab-ci-multi-runner list -- 目前已经有的runner
gitlab-ci-multi-runner register -- 注册新的runner
把runner注册到gitlab
每个项目都得有一个runner
,需要在安装gitlab-ci-runner
的机器上去去注册,所谓的注册,就是把runner
和项目关联起来,让一个项目能找到自己对应的runner
1.首先在gitlab上选一个你需要自动部署的项目
2.进入setting去设置
3.在安装gitlab-ci-runner的机器上去执行 `gitlab-ci-multi-runner register`
4.输入gitlab的地址和token(下图所示)
5.成功后,下图所示位置多一个runner标志
在项目根目录添加一个.gitlab-ci.yml
.gitlab-ci.yml
是核心的脚本,当触发代码变动的时候,runner
就会执行.gitlab-ci.yml
的命令,所有执行的命令都在里面,下面结合示例讲解。
首先还需在那台机器上去
# 定义两个阶段 ,测试阶段和发布部署阶段
stages:
- test
- deploy
# sonar-check是一个任务。属于测试阶段,script下面是这个阶段要执行的脚本,
# tags是这个项目注册的runner
# only:代表dev分支代码变动,就执行个job
sonar-check:
stage: test
script:
- echo "暂时不做代码扫描~"
tags:
- service-ipo-schedules
only:
- dev
# 同上,主要核心在于 script 的内容
jar-deploy:
stage: deploy
script:
- mvn clean package -Dmaven.test.skip=true
- echo "打包完成~"
- scp -P 10086 ./target/hk-ipo-schedules.jar root@127.0.0.1:/data/ipo-service/ipo_schdules/
- echo "传包完成~"
- ssh -p 10086 root@127.0.0.1 "cd /data/ipo-service/ipo_schdules/&& ./kill.sh && ./start.sh"
- echo "启动完成~"
tags:
- service-ipo-schedules
only:
- dev
可以在下面这个页面去查看ci-cd的执行日志。
搭建代码质量管理平台
到上面为止,基本ci和cd的功能就有了,但是这还不够,因为我们还需要一个代码审核平台,当提交代码,会扫描一遍代码,提示出有多少bug
,多少code smells
。这里我选择使用 snoar
这个代码管理平台。首先就搭建好 snoar
,然后就配合gitlab-ci
一起使用。我们都是用docker
去搭建。
首先搭建一个postgres
,是一个关系型数据库,提供给sonar
使用,步骤如下:
# 拉取镜像
docker pull postgres
# 启动容器脚本
docker run --name postgresqldb -e POSTGRES_USER=root -e POSTGRES_PASSWORD=root -d postgres
# 启动后,使用idea里面数据库工具,或者其他数据库工具测试能不能连上,账号root,密码root
然后安装 sonarqube
# 拉取镜像
docker pull sonarqube
# 启动容器脚本
docker run --name sonarqube --link postgresql -e sonar.jdbc.password=sonar -e sonar.jdbc.username=sonar -e SONARQUBE_JDBC_URL=jdbc:postgresql://192.168.40.90:5432/sonar -p 9001:9000 -d -v sonar_data:/opt/sonarqube/data -v sonar_extensions:/opt/sonarqube/extensions sonarqube
我安装sonarqube的时候我会报个错
ERROR: [1] bootstrap checks failed
[1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
主要原因是系统默认分配的最大内存映射区域数不够大。
解决方案:https://blog.csdn.net/xaioAdmin/article/details/107039989
我搭建sonar机器的内网ip为192.168.40.90
,映射端口为9001
,所以我登陆http://192.168.40.90:9001
账号admin,密码admin。如果能够访问到页面,说明搭建成功。如果有中文的需求,可以在页面的应用上面安装 Chinese Pack
这个插件,但是有些名词翻译的奇奇怪怪,我安装了又卸载了。
下面说一下sonar的基本使用:
1.在maven的setting中添加profile
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.host.url>
http://192.168.40.90:9001
</sonar.host.url>
</properties>
</profile>
2.在java项目的pom文件中添加一个sonar的plugin
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.4.0.905</version>
</plugin>
</plugins>
</build>
3.在项目下执行 使用 mvn clean install sonar:sonar 执行
4.扫描后,就会在http://192.168.40.90:9001这个网址上生成一个项目的报告,指出有多少bug,多少code smell。点进去查看是哪行代码。
4..gitlab-ci.yml
文件配合sonar
stages:
- test
- deploy
sonar-check:
stage: test
script:
- mvn clean package -Dmaven.test.skip=true
- echo "打包完成~"
- mvn sonar:sonar
- echo "代码扫描完成~"
tags:
- service-ipo-schedules
only:
- dev
# start.sh 和 kill.sh 是启停脚本,里面内容是jara -jar 和 kill
-9 之类的
jar-deploy:
stage: deploy
script:
- mvn clean package -Dmaven.test.skip=true
- echo "打包完成~"
- scp -P 10086 ./target/hk-ipo-schedules.jar root@127.0.0.1:/data/ipo-service/ipo_schdules/
- echo "传包完成~"
- ssh -p 10086 root@127.0.0.1 "cd /data/ipo-service/ipo_schdules/&& ./kill.sh && ./start.sh"
- echo "启动完成~"
tags:
- service-ipo-schedules
only:
- master
上面脚本实现的功能就是代码提交到dev后,首先使用sonar扫描代码,然后maven打包,通过scp传包,然后使用kill.sh去杀掉之前的进程,然后start.sh脚本启动新的jar包的过程。如果想做的更好,可以自己搭建一个docker私服,可以结合Dockerfile
把jar包打成image
传到私服,然后拉取镜像,通过容器去部署。
踩坑
- gitlab-ci的runner中执行命令的用户不是root,是gitlab-runner。导致ssh登不上,执行命令没权限。