使用gitlab-ci搭建CI,CD平台

之前项目刚刚起步,所有的前后端项目上测试环境,上正式环境都是在本地去打包,然后传到服务器上去启动。这就非常麻烦,这样的一个很大的缺点是不方便代码的管理,在本地打包,如果打包的人代码没提交,下次上线,另外一个人打包可能就有代码缺失的风险,多搞几次,都不知道线上代码到底是什么样了。而且有的是要横向部署多个,手动传包就更麻烦。于是我这边就研究了自动部署的方法,然后就可以省些这种麻烦的事。

首先什么是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上代码的变动。(把本地打包,传包,停止应用,启动应用的步骤交给机器脚本执行)

代码管理机制

当使用自动部署以后,代码就得比较严格的管理起来,因为自动部署都是通过分支上代码的变动来触发的,如果代码随意变动,就会导致自动部署的误触。

  • gitlabdevmaster的分支的代码都需要被保护起来,只能通过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标志
进入cicd页面.png

runner注册成功就多一个runner.png

在项目根目录添加一个.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的执行日志。


runner执行的job.png

点击job,查看日志.png

搭建代码质量管理平台

到上面为止,基本ci和cd的功能就有了,但是这还不够,因为我们还需要一个代码审核平台,当提交代码,会扫描一遍代码,提示出有多少bug,多少code smells。这里我选择使用 snoar 这个代码管理平台。首先就搭建好 snoar ,然后就配合gitlab-ci一起使用。我们都是用docker去搭建。

sonar项目列表.png

sonar项目扫描详情.png

扫描具体代码的问题.png

首先搭建一个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登不上,执行命令没权限。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342