DevOps实战系列【第九章】:详解Sonarqube搭建及集成Jenkins环境

个人亲自录制全套DevOps系列实战教程手把手教你玩转DevOps全栈技术

在这里插入图片描述

质量安全审计:Sonarqube

Sonarqube(声呐)大家应该不陌生,通过扫描代码分析代码质量与代码安全,方便我们快速定位代码缺陷、潜在风险。

个人建议: 作为项目质量智能分析工具,他是个双刃剑,在公司规模足够大并且足够重视代码质量时,sonar会有一个不错的位置;当如果公司规模小型,并且公司不足以把重点放在代码质量上,那么sonar可能会成为拖后腿的工具,一句话就是是否有必要上sonar完全看公司的需求以及成本。

作用阶段: 我们讨论下sonar应该在什么阶段起作用

  • 代码开发阶段实时检测【sonarlint插件,为sonar 8.5版本后提供,需要集成到开发工具如Idea,配置时需要sonarqube服务支持,分析结果会提示在控制台,类似前端eslint作用】
  • 代码提交前进行sonar扫描【需集成到本地开发工具,如Idea或Eclipse】
  • 提交代码时进行sonar扫描【需集成到gitlab,如sonar-gitlab-plugin,也可结合Gitlab CI进行提交流程控制】
  • 构建代码时进行sonar扫描【需集成到jenkins,如SonarQube Scanner插件】
  • 由sonar定期自主扫描代码生成报告【可以用jenkins的定时job】

具体应该部署哪种方案,也需要大家根据自身情况适当选择,没有完美的方案,选择最适合自己的方案即可。

此处我们集成到jenkins做演示。其他方式大家有兴趣可以找我咨询。

Docker容器部署

官网:https://docs.sonarqube.org/latest/setup/install-server/

根据官方文档可知,sonar是支持docker部署的,并且非常简单,sonar默认使用H2数据库,我们也可以指定自己的mysql等数据库。

选用版本:8.9 该版本为LTS长期支持版本,从7.9版本开始sonar必须有jdk11支持并且不再支持Mysql数据库。sonar默认采用H2数据库。

官方推荐配置:SonarQube扫描器需要版本8或11的JVM,SonarQube服务器需要版本11和最少2G内存,具体大家可以官网看。

Sonar的社区版免费
在这里插入图片描述
Sonar包括3个组件: Scanner负责扫描代码并分析生成报告->报告交给Sonar服务进行计算->最终结果存入数据库。下边我们通过docker-compose方式启动sonar容器。

注意:sonar不能以root身份运行在基于Unix系统上,我们这里使用的是基于Debian内核,所以没问题。

# vi /docker/sonarqube/docker-compose.yml
# 此处我们使用默认的H2数据库,如果外接数据库,可参考官网docker-compose.yml文件
version: "3"
services:
  sonarqube:
    # 使用一下私服拉取
    image: 10.10.1.199:9083/sonarqube:8.9-community
    restart: always
    container_name: 'sonarqube'
    hostname: 'sonarqube'
    networks:
      - 'exist-net-bloom'
    volumes:
      # 配置文件
      - '/docker/sonarqube/conf:/opt/sonarqube/conf'
      # 保存H2数据和ES索引文件
      - '/docker/sonarqube/data:/opt/sonarqube/data'
      # 保存第三方插件
      - '/docker/sonarqube/extensions:/opt/sonarqube/extensions'
      # 日志
      - '/docker/sonarqube/logs:/opt/sonarqube/logs'
    ports:
      - "9097:9000"
networks:
  exist-net-bloom:
    external:
      name: devops
      
# 如果需要自行修改配置,比如使用其他数据库等,可以在conf目录增加sonar.properties配置文件,具体可到官方获取
# 官方下载地址:https://www.sonarqube.org/downloads/

访问:10.10.1.199:9097,注意以上docker-compose.yml并未指定上下文,默认为/,可以自行指定。

在这里插入图片描述
输入:admin,admin即可
在这里插入图片描述
不过下边有一个黄色警告,他的意思是嵌入式数据库应该只用于测试不能用于生产,那样不利于扩展,并且不支持升级到最新版本的sonarqube,我们这里用的默认H2所以会有提示,如果大家想尝试连接自己的数据,当然不能是Mysql,如果要用mysql可以使用7.9以下的版本,如果要使用单独数据库,通过docker-compose.yml指定几个环境变量就行了:

environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar

中文插件安装:

在这里插入图片描述
结果安装失败了,点击按钮后,页面无反应
在这里插入图片描述
报错原因是到github上下载插件失败,超时了:docker logs -f sonarqube 可看到报错日志,那理所当然我们认为是网络问题,手动下载,地址如下:https://github.com/xuhuisheng/sonar-l10n-zh/releases/download/sonar-l10n-zh-plugin-8.9/sonar-l10n-zh-plugin-8.9.jar

诡异的事情:出于好奇,想到当前用的H2,会不会跟这个有关呢?于是我尝试了使用postgresql[结果出乎意料]

version: "3"
services:
sonarqube:
 # 使用一下私服拉取
 image: 10.10.1.199:9083/sonarqube:8.9-community
 restart: always
 container_name: 'sonarqube'
 hostname: 'sonarqube'
 networks:
      - 'exist-net-bloom'
    volumes:
      # 配置文件
      - '/docker/sonarqube/conf:/opt/sonarqube/conf'
      # 保存H2数据和ES索引文件
      - '/docker/sonarqube/data:/opt/sonarqube/data'
      # 保存第三方插件
      - '/docker/sonarqube/extensions:/opt/sonarqube/extensions'
      # 日志
      - '/docker/sonarqube/logs:/opt/sonarqube/logs'
    depends_on:
      - postgressql
    environment:
      # 避免ip变更,使用hostname连接
      SONAR_JDBC_URL: jdbc:postgresql://postgressql:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar
    ports:
      - "9097:9000"

  postgressql:
    image: 10.10.1.199:9083/postgres:12
    restart: always
    container_name: 'postgressql'
    hostname: 'postgressql'
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar
    volumes:
      - '/docker/sonarqube/postgresql:/var/lib/postgresql'
      - '/docker/sonarqube/postgresql/data:/var/lib/postgresql/data'
    networks:
      - 'exist-net-bloom'
networks:
  exist-net-bloom:
    external:
      name: devops


# 删除原有容器
docker-compose down
# 重新启动容器
docker-compose up -d

启动sonar报错:

ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.
bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
ERROR: Elasticsearch did not exit normally - check the logs at >/opt/sonarqube/logs/sonarqube.log

解决方法: 在宿主机的/etc/sysctl.conf中增加该配置即可,注意因为容器也是复用宿主的系统配置,所以直接改宿主机即可。

vi /etc/sysctl.conf  # 新增如下配置
vm.max_map_count=262144

# 更新启动容器
docker-compose up -d

在这里插入图片描述
出乎意料,安装成功了!!!

这。。。,就不是github网络问题吧?

推测:其实还有一个问题,就是下载插件后无法保存到插件目录,即无法保存到/opt/sonarqube/extensions/plugins,因为被映射到宿主机了,如果无权写数据也可能会超时,所以修改宿主机目录权限:chmod -R 777 /docker/sonarqube/extensions
在这里插入图片描述
那为什么H2数据库就不行,PostgreSQL就可以呢?

我查了下文档,并没有找到答案,可能这就是亲儿子效应吧,H2都不推荐你用你非要用,出问题了吧 。。。,还是乖乖用PostgreSQL才是王道啊!

Sonar客户端配置

由官网文档得知,客户端需要使用Scanner工具完成扫描和上报(sonar早期版本还单独提供有sonarqube runner工具,和scanner类似),并且Scanner有多重实现方式

官方地址:https://docs.sonarqube.org/8.9/analysis/overview/

在这里插入图片描述

我们这里演示两种方式:Maven和Jenkins

  • Springboot工程本地集成Scanner插件
  • Jenkins集成Scanner插件
Maven配置

既然是maven当然可以配置到全局settings.xml,也可以配置到springboot项目的pom.xml中。

注意:我们的sonar是需要登录的,所以事先我们先把token生成一下,直接使用用户名密码也可以,用token可以防止密码泄露
在这里插入图片描述
配置到settings.xml

<settings>
    <pluginGroups>
        <pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
    </pluginGroups>
    <profiles>
        <profile>
            <id>sonar</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                # 指定token,如果使用用户名密码,需要增加<sonar.password>属性
                <sonar.login>0226e22e60902a670f8c706e12e5ceee86c51f9e</sonar.login>
                <sonar.host.url>http://10.10.1.199:9097</sonar.host.url>
            </properties>
        </profile>
     </profiles>
</settings>

配置到Springboot项目的pom.xml

<build>
  <pluginManagement>
    <plugins>
      <plugin>
        <groupId>org.sonarsource.scanner.maven</groupId>
        <artifactId>sonar-maven-plugin</artifactId>
        <version>3.7.0.1746</version>
      </plugin>
    </plugins>
  </pluginManagement>
</build>
<profiles>
  <profile>
    <id>sonar</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
       <sonar.login>0226e22e60902a670f8c706e12e5ceee86c51f9e</sonar.login>
       <sonar.host.url>http://10.10.1.199:9097</sonar.host.url>
    </properties>
  </profile>
</profiles>

测试: 在工程根目录执行 mvn sonar:sonar
在这里插入图片描述
错误:你的工程包含java文件,请使用sonar.java.binaries属性指定class文件目录或使用sonar.exclusions属性排除java文件。

# 修正后执行命令,也可以在pom.xml中增加该属性
mvn sonar:sonar -Dsonar.java.binaries=target/

# 关于属性大家可以到官网查看:https://docs.sonarqube.org/8.9/analysis/analysis-parameters/

在这里插入图片描述

覆盖率:

这里延伸一下sonar覆盖率的概念,他会在scanner之前将汇总报告生成到target目录,然后由scanner一起上报给sonar服务。

覆盖率的概念是单元测试的覆盖面囊括了我们源代码的比例,更多的在测试中使用。

我们看图中覆盖率是0,其实覆盖率要生效需要使用另一个插件,对于java代码的统计汇总需要的是jacoco,其他语言大家也可参考官网:https://docs.sonarqube.org/8.9/analysis/coverage/

<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
<configuration>
 <!--指定生成.exec文件的存放位置-->
 <destFile>target/coverage-reports/jacoco-unit.exec</destFile>
 <!--Jacoco是根据.exec文件生成最终的报告,所以需指定.exec的存放路径-->
 <dataFile>target/coverage-reports/jacoco-unit.exec</dataFile>
 <!-- 如果以上都不指定,默认jacoco-unit.exec会存入target/目录,report也会从target目录读取-->
 <!-- 并且report会将报告存入target/site/jacoco/index.html -->
</configuration>
<executions>
 <execution>
   <id>jacoco-prepare-agent</id>
   <goals>
     <goal>prepare-agent</goal>
   </goals>
 </execution>
 <execution>
   <id>jacoco-report</id>
   <!-- 指定生成报告的maven目标 -->
   <phase>verify</phase>
   <goals>
     <goal>report</goal>
   </goals>
 </execution>
</executions>
</plugin>


# 执行先生成覆盖率报告,在scanner扫描
mvn clean verify sonar:sonar
Jenkins改造

在这里我们主要演示让sonar集成到jenkins,这样jenkins不论是单独的定时任务job还是目前我们demo项目的job,都可以进行按需的分析代码。

我们还是以demo为例,目标:maven构建打包的同时进行sonar分析完成扫描代码并上报。

思考:jenkins需要修改吗?要怎么修改?有几种方案?不修改行吗?

  • 不修改: 当然行,因为demo工程的pom.xml已经配置了Sonar Scanner,可以通过mvn命令直接使用
    缺点:没有配置Scanner的其他job无法实现通过Scanner扫描上报
  • 修改方案1: 给jenkins中的maven配置文件settings.xml做全局配置
    缺点:由于settings.xml配置能力有限,有些特殊配置无法实现
  • 修改方案2: 与Maven集成Jenkins类似,将Sonarqube-Scanner的安装包装入容器,然后全局工具中配置,再安装对应的jenkins插件,这样在job中就可以单独去使用Scanner功能了,而不必依赖于job个体。
第一个方案很简单:

只需要将job的Maven构建脚本改成:-DskipTests=true clean package verify sonar:sonar

打包后进行Scanner扫描上报Sonar。
在这里插入图片描述

根据jenkins日志片段可知,Scanner已经生效了,并且将代码扫描后上传到了Sonar服务器,此时我们打开Sonar控制台也可以看到上报的demo工程。

我们可以修改下工程中代码并且提交gitlab,在用jenkins重新构建,可以发现sonar的新上报。

第三种方案:

Jenkins中彻底集成Scanner 【第二种也比较简单,大家自行验证下,我试了是没问题的

①首先下载Scanner安装包:
以下哪个地址能下用哪个,我下载的是:sonar-scanner-cli-4.7.0.2747-linux.zip

官方地址:https://docs.sonarqube.org/8.9/analysis/scan/sonarscanner/

二进制地址:https://binaries.sonarsource.com/?prefix=Distribution/sonar-scanner-cli/

注意需要使用:unzip解压,如果要构建到Dockerfile,则需先通过yum install -y unzip,我这里直接贴出来Dockerfile文件

这里我们就不把他构建到Dockerfile了,而是直接解压到jenkins根目录,根目录已经映射出来,所以操作也很方便

包括jdk、git、maven如果大家觉得没必要打入镜像,都可以这样操作。

②将安装包解压到/docker/jenkins/home目录

# apt install unzip 我用的omv是基于Debian
yum install -y unzip 
# 解压
unzip sonar-scanner-cli-4.7.0.2747-linux.zip
# 改下文件夹名字
mv sonar-scanner-4.7.0.2747-linux sonar-scanner


③Jenkins中安装sonar插件:【SonarQube Scanner For Jenkins】
在这里插入图片描述
配置sonar路径:系统管理 -> 系统配置 -> SonarQube servers
在这里插入图片描述
④全局配置工具:设置sonar-scanner环境目录
在这里插入图片描述
⑤修改job配置:在maven构建之后增加sonar scanner,即放在推送镜像到私服环节之前
在这里插入图片描述
添加后我们什么都不配运行看下效果:
在这里插入图片描述
依次尝试后,我们把必要参数全部配置好:
在这里插入图片描述
再看sonarqube控制台,已经发布上来了。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上树的蜗牛儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值