# Jenkins SonarQube 实践

# 1. SonarQube 基本概述

# 1.1 什么是 SonarQube

SonarQube 是⼀个开源的代码质量管理系统,⽤于检测代码中的错误、漏洞。它可以与 Jenkins 集成,让我们进⾏⾃动化代码质量扫描。

1.png

# 1.2 Sonarqube 服务架构

2.png

# 1.3 使⽤ Sonarqube 前提
  • SonarQube 基于 Java 开发,版本⾄少需要安装 Open JDK17 版本。
  • SonarQube 依赖数据库,不在是 MySQL ,⽽是 PostgreSQL(11-15 版本)、Oracle、SQLServer 等。
  • SonarQube 的⼩型实例⾄少需要 4GB 内存,如果是⼤型实例需要 16GB 依赖的硬件版本、java 版本、数据库版本等参考地址

# 2. SonarQube 服务安装

# 2.1 环境准备

1、关闭防⽕墙

[root@sonarqube ~]# systemctl stop firewalld
[root@sonarqube ~]# systemctl disable firewalld
[root@sonarqube ~]# setenforce 0

2、修改内核参数(必选)

[root@sonarqube ~]# cat >>/etc/sysctl.conf<<-EOF
vm.max_map_count=524288
fs.file-max=131072
EOF
[root@sonarqube ~]# sysctl -p
# 操作系统级别对每个⽤户创建的进程数的限制
[root@sonarqube ~]# cat >> /etc/security/limits.conf <<-EOF
* soft nproc 8192
* hard nproc 8192
EOF
# 重新打开⼀个新的窗⼝⽣效
[root@sonarqube ~]# ulimit -a
max user processes (-u) 8192

3、安装 java 环境

[root@sonarqube ~]# wget https://download.oracle.com/java/17/archive/jdk-17.0.12_linux-x64_bin.tar.gz
[root@sonarqube ~]# tar xf jdk-17.0.12_linux-x64_bin.tar.gz  -C /usr/local/
[root@sonarqube ~]# ln -s /usr/local/jdk-17.0.12/ /usr/local/jdk
#添加环境变量
[root@sonarqube ~]# cat /etc/profile.d/jdk.sh
export JAVA_HOME=/usr/local/jdk
export PATH=$PATH:$JAVA_HOME/bin
export JRE_HOME=$JAVA_HOME
export CLASSPATH=$JAVA_HOME/lib/:$JRE_HOME/lib/
[root@sonarqube ~]# source /etc/profile
[root@sonarqube ~]# java -version
# 2.2 部署 postgresql 数据库

1、安装 postgresql ,默认 RockyLinux 提供的版本为 13,如果需要其他版本可以参考 postgresql 官⽹下载

[root@sonarqube ~]# yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
[root@sonarqube ~]# yum install postgresql15 postgresql15-server

2、初始化 postgresql

[root@sonarqube ~]# /usr/pgsql-15/bin/postgresql-15-setup initdb

3、编辑 postgresql 的配置⽂件。默认 pgsql 的认证是基于操作系统⽤户认证机制,不需要使⽤数据库密码,因此需要修改为⽀持⽤户名密码的认证⽅式。 将 peer 改为 scram-sha-256(推荐的加密方式),或者 md5(如果需要兼容旧客户端)

[root@sonarqube ~]#cat /var/lib/pgsql/15/data/pg_hba.conf 
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     peer
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-25
# 将 peer 改为 scram-sha-256(推荐的加密方式),或者 md5(如果需要兼容旧客户端)
# TYPE  DATABASE        USER            ADDRESS                 METHOD
# "local" is for Unix domain socket connections only
local   all             all                                     scram-sha-256
# IPv4 local connections:
host    all             all             127.0.0.1/32            scram-sha-256
# IPv6 local connections:
host    all             all             ::1/128                 scram-sha-256

4、启动 postgresql 数据库

[root@sonarqube ~]# systemctl enable postgresql-15 --now
# 检查端⼝
[root@jenkins ~]# netstat -lntp|grep postmaster
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      31973/postmaster    
tcp6       0      0 ::1:5432                :::*                    LISTEN      31973/postmaster

5、在 PostgreSQL 中,初始管理员⽤户名为 postgres 的⽤户

[root@sonarqube ~]# su - postgres -c "psql"
postgres=#
postgres=# ALTER USER postgres WITH PASSWORD '123456'; # 设定 postgres 账户
密码为123456
# 使⽤⽤户名密码登录测试
[root@sonarqube ~]# su - postgres -c "psql -h localhost -U postgres -W"
Password:
postgres=#

6、创建 sonarqube 库,设定字符集为 utf8

postgres=# create database sonarqube ENCODING utf8;
postgres=# \l      # 查询数据库
                                                 List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges  
 
-----------+----------+----------+-------------+-------------+------------+-----------------+----------------------
-
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | 
 sonarqube | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          
+
           |          |          |             |             |            |                 | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          
+
           |          |          |             |             |            |                 | postgres=CTc/postgre
# 2.3 安装 Sonarqube

1、下载 sonarqube 的⼆进制包,然后解压⾄ /usr/local

#sonarqube 10.5
[root@sonarqube ~]# wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-10.5.0.89998.zip
#sonarqube 11.0
[root@sonarqube ~]# wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-25.11.0.114957.zip
[root@sonarqube ~]# unzip sonarqube-25.11.0.114957.zip -d /usr/local/
[root@sonarqube ~]# ln -s /usr/local/sonarqube-25.11.0.114957/ /usr/local/sonarqube

2、修改 sonarqube 连接 postgresql 数据库配置⽂件

[root@sonarqube ~]# vim /usr/local/sonarqube/conf/sonar.properties
#----- PostgreSQL
sonar.jdbc.username=postgres
sonar.jdbc.password=123456
sonar.jdbc.url=jdbc:postgresql://localhost/sonarqube
# JVM options of Elasticsearch process
sonar.search.javaOpts=-Xmx2028m -Xms2048m -XX:MaxDirectMemorySize=256m -XX:+HeapDumpOnOutOfMemoryError
# 2.4 启动 Sonarqube

1、设定 sonarqube 中的 ElasticSearch 使⽤的内存⼤⼩

[root@sonarqube ~]# vim /usr/local/sonarqube/elasticsearch/config/jvm.options
-Xms1g
-Xmx1g

2、启动 sonarqube 服务必须使⽤普通⽤户运⾏;如果使⽤ root 则会启动失败

[root@sonarqube ~]# useradd sonar
[root@sonarqube ~]# chown -R sonar:sonar /usr/local/sonarqube       
[root@sonarqube ~]# su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start"
# 2.5 访问 Sonarqube

1、通过浏览器输⼊ http://hostname:9000 地址来访问 sonarqube ,输⼊⽤户名: admin ⽤户密码: admin

3.png

2、点击 Create a local project ,创建⼀个项⽬,然后分析的⽅式 Analysis Method 为⼿动

1.png

2.png

3.png

3、选择对应需要分析的项⽬语⾔,sonarqube 会给出对应的分析命令

4.png

4、因此使⽤ SonarQube 分析 java 项⽬,可以直接使⽤ mvn 命令进⾏分析;

mvn clean verify sonar:sonar \
  -Dsonar.projectKey=springboot \
  -Dsonar.projectName='springboot' \
  -Dsonar.host.url=http://sonar.hmallleasing.com:9000 \
  -Dsonar.token=sqp_3a6fe642ad50ff06f2672cabe037fa692d3e722c

5、但对于⾮ java 的项⽬,则需要借助 sonar-scanner 功能来完成对应的分析

sonar-scanner \
  -Dsonar.projectKey=springboot \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://sonar.hmallleasing.com:9000 \
  -Dsonar.token=sqp_3a6fe642ad50ff06f2672cabe037fa692d3e722c
# 2.6 Sonarqube 插件管理

Sonarqube 默认已经安装了 C Java Python Php 等代码的质量分析⼯具,那我们为什么还需要安装插件,因为我们还需要检测 html 等类型代码,⽽默认插件没有,所以需要安装;以便将代码检测的更加完善;

# 2.6.1 联⽹安装插件

联⽹安装插件⽐较简单,仅需要上应⽤市场搜索插件名称即可,如下以安装中⽂语⾔包插件为例;点击 Administration-> Marketplace-> 搜索框 chinese ,出现⼀个 Chinese Pack ,然后点击 install ,安装完毕后需要重启 sonarqube 服务

安装好的插件会存储在 /usr/local/sonarqube/extensions/plugins/ ⽬录下

5.png

# 2.6.2 离线安装插件

通过导⼊的⽅式来完成插件的安装。前提是该压缩包⾥⾯有⾜够多的插件,且版本要与当前的 sonarqube 保持⼀致。

[root@sonarqube ~]# rm -rf /usr/local/sonarqube/extensions/plugins
[root@sonarqube ~]# tar xf sonar_plugins.tar.gz -C /usr/local/sonarqube/extensions/
[root@sonarqube ~]# chown -R sonar.sonar /usr/local/sonarqube/extensions/plugins/
[root@sonarqube ~]# su - sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart"

# 3. SonarQube 检测代码

前⾯已经将 SonarQube 服务以及插件安装完成,那么接下来只需要将代码推送⾄ Sonarqube 进⾏分析即可

Sonarqube 分析报错: NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy

# 3.1 JAVA 项⽬分析

1、生成 sonar 全局令牌

5.png

2、进⼊项⽬⽬录,使⽤ mvn 命令将代码直接推送⾄ Sonarqube 分析,【注意:sonarqube 版本过多,他要求客户端也得⽀持 java17,项⽬也得⽀持 java17】;

[root@jenkins ~]# mvn package
[root@jenkins ~]# mvn clean verify sonar:sonar \
  -Dsonar.projectKey=springboot-devops-oldxu-jar \
  -Dsonar.projectName='springboot-devops-oldxu-jar' \
  -Dsonar.host.url=http://sonar.hmallleasing.com:9000 \
  -Dsonar.token=sqa_b14c221e164b33d4733049072739739d51fbed04
# -Dsonar.java.binaries=target/classes
# -Dsonar.java.enablePreview=true   # 启⽤ java17 的新特性

3、配置 hosts 解析

[root@jenkins springboot-devops-demo-jar-java17]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.50 gitlab.hmallleasing.com
192.168.1.32 nexus.hmallleasing.com
192.168.1.8 sonar.hmallleasing.com

4、登陆 Sonarqube 查看项⽬分析结果;

6.png

# 3.2 ⾮ JAVA 项⽬分析

Sonarqube 分析 Html、php、go 项⽬;需要借助 sonar-scanner 客户端⼯具来完成代码的分析;

1、安装 sonar-scanner 命令;sonar-scanner 下载地址

[root@jenkins ~]# wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
[root@jenkins ~]# unzip sonar-scanner-cli-5.0.1.3006-linux.zip -d /usr/local/
[root@jenkins ~]# ln -s /usr/local/sonar-scanner-5.0.1.3006-linux/ /usr/local/sonar-scanner

2. 进⼊项⽬⽬录,使⽤ sonar-scanner ⼯具将代码推送 Sonarqube 服务端进⾏分析

# html
[root@jenkins ~]# /usr/local/sonar-scanner/bin/sonar-scanner \
  -Dsonar.projectKey=web_mointor \
  -Dsonar.sources=. \
  -Dsonar.host.url=http://sonar.hmallleasing.com:9000 \
  -Dsonar.token=sqa_b14c221e164b33d4733049072739739d51fbed04
 
# java (需要先编译后检测,否则会报错)
[root@jenkins ~]# /usr/local/sonar-scanner/bin/sonar-scanner \
  -Dsonar.projectKey=springboot-devops-demo-war \
  -Dsonar.sources=. \
  -Dsonar.java.binaries=target/classes \
  -Dsonar.host.url=http://sonar.hmallleasing.com:9000 \
  -Dsonar.token=sqa_b14c221e164b33d4733049072739739d51fbed04

3、登陆 Sonarqube 查看项⽬分析结果

7.png

# 4. Jenkins 集成 SonarQube

Jenkins 需要知道 Sonarqube 服务的地址;以便能将代码推送指定服务节点;

Jenkins 需要知道 Sonar-Scanner 客户端⼯具,以便能正常调⽤ scanner 进⾏代码扫描;

# 4.1 Jenkins 集成 Sonarqube

1、插件安装; 系统管理 --> 插件管理 -->SonarQube Scanner for Jenkins

2、在 Jenkins 上配置 SonarQube 服务端地址; 系统管理 --> 系统配置 -->sonarQube (告诉 jenkins SonarQubeServers 服务端地址)

  • Name 可以随意填写;
  • URL 添加 SonarQube 服务端地址(地址尾部不要添加斜杠,否则后期调⽤ Sonar 时,会出现⽆效的 JSON 字符串);
  • token 添加⼀个 Secret text ;内容填写此前 SonarQube ⽣成的 Token(3.1 生成 sonar 全局令牌)

1.png

# 4.2 Jenkins 集成 Sonar-Scanner

在 Jenkins 上配置 Sonar-Scanner 客户端⼯具路径; 系统管理 --> 全局⼯具配置 -->sonar-scanner(告诉 jenkins SonarScanner 在本地哪个路径)

  • Name 可以随意填写,但最好有规范 SonarQube Scanner
  • SONAR_RUNNER_HOME 填写 sonar-scanner 在 Jenkins 本地路径

2.png

# 5. Jenkins 为项⽬添加测试阶段

# 5.1 maven 质检⽅式

在项⽬编译后执⾏扫描动作,也就是 Post Steps 阶段

4.png

注意:如下内容不要添加 \ 换⾏符,直接回⻋即可。

clean
verify
sonar:sonar
-Dsonar.projectKey=${JOB_NAME}
-Dsonar.projectName=${JOB_NAME}
-Dsonar.host.url=http://sonar.hmallleasing.com:9000
-Dsonar.token=sqa_b14c221e164b33d4733049072739739d51fbed04
# 5.2 Scanner 质检⽅式

在项⽬编译后执⾏扫描动作,也就是 Post Steps 阶段

5.png

# 针对静态站点使⽤ sonar-canner(不要粘贴注释在⾥⾯)
sonar.projectName=${JOB_NAME} #项⽬在 sonarqube 上的显示名称
sonar.projectKey=${JOB_NAME}  #项⽬的唯⼀标识,不能重复
sonar.sources=.               #扫描哪个项⽬的源码
# 针对 java 使⽤ sonar-canner ⾃动扫描
sonar.projectName=${JOB_NAME}
sonar.projectKey=${JOB_NAME}
sonar.sources=.
sonar.java.binaries=target/classes
# 5.3 质量检测结果查看

1、检查 Jenkins 构建结果

6.png

2、检查 Sonarqube 质量检测结果

7.png

# 6. Jenkins 为项⽬添加通知阶段

CI 阶段: 通知 sonarqube 的质量结果;

CD 阶段:通知任务构建是否成功;

# 6.1 配置钉钉

1、点击钉钉右上角 +--> 发起群聊 --> 群名称:Jenkins-Notify--> 群归属:普通群

2、设置 --> 群类型 --> 内部群

3、打开钉钉群组,点击群机器⼈。(如果你不是群主,且群主开启了仅群主可管理,那么将⽆法创建机器⼈。)

4、添加⼀个⾃定义机器⼈

3.png

5、可以修改机器⼈名称,以及机器⼈的名字,自定义关键字(任务、BUG、漏洞、部署、代码、构建)

1.png

6、机器⼈修改成功后,会给出⼀个 webhook 地址。(此处的 webhook 后续 jenkins 需要使⽤)

https://oapi.dingtalk.com/robot/send?access_token=53b3de985e09e3d7bc6ef1fa84f2c2820a9d5d1a52f43aaa2e6fa3c548997250

2.png

# 6.2 Jenkins 集成钉钉

1、Jenkins 安装 dingding 插件, DingTalk 。

2、配置钉钉机器⼈,系统管理 --> 钉钉 --> 配置通知机制

4.png

5.png

3、添加机器⼈

7.png

4、点击测试,验证是否能将消息发送⾄钉钉

8.png

# 6.3 为项⽬添加通知

1、找到对应的 CD 阶段项⽬,然后选择此前添加的机器⼈,然后配置⾼级,选择通知谁,通知的消息是什么;

1.png

- 部署的项⽬: ${PROJECT_NAME}
- 部署的环境:${host_inventory}    #确实项目中是否存在该变量
- 部署的版本: ${jar_deploy_url}    #确实项目中是否存在该变量

2、检查钉钉的执⾏结果;

2.png

# 7. Jenkins 为项⽬通知质检结果

# 7.1 Sonarqube 结果通知⽅案

Jenkins--> 扫描项⽬ ---> 推送 -->Sonarqube-->Webhook--> 开源程序 --> 发送 --> 钉钉机器⼈

使⽤开源程序: sonarqube-ding-robot ,项⽬地址: https://github.com/akkuman/sonarqube-ding-robot/tree/master

  • 1、设定钉钉机器⼈,然后获取对应机器⼈的 token。
  • 2、运⾏ sonarqube_dingding 程序,但是需要指定 Sonarqube 的 Token ;
  • 3、配置 Sonarqube 的 Webhook,指定 sonarqube-dingding 程序运⾏的地址以及端⼝,但需要传递钉钉的 Token 。
# 7.2 配置钉钉机器⼈

1、点击钉钉右上角 +--> 发起群聊 --> 群名称:Jenkins-Notify--> 群归属:普通群

2、设置 --> 群类型 --> 内部群

3、打开钉钉群组,点击群机器⼈。(如果你不是群主,且群主开启了仅群主可管理,那么将⽆法创建机器⼈。)

4、添加⼀个⾃定义机器⼈

3.png

5、可以修改机器⼈名称,以及机器⼈的名字,自定义关键字(任务、BUG、漏洞、部署、代码、构建)

3.png

6、机器⼈修改成功后,会给出⼀个 webhook 地址。(此处的 webhook 后续 jenkins 需要使⽤)

https://oapi.dingtalk.com/robot/send?access_token=55af9255dd264a6b4c51a4fcc6a0a4553488a7db87f1c2942702039248536c0c

5.png

# 7.3 启动 sonarqube-ding 程序

如果在 Sonarqube 服务端上运⾏这个程序,则需要进⾏如下设定。

通⽤设置 --> 权限 -->Enable local webhooks validation (关闭) ,否则没办法通过 webhook 通知结果到本地的 localhost 程序上

6.png

1、下载 sonarqube-ding-robot

[root@jenkins ~]# wget https://mirror.ghproxy.com/ https://github.com/akkuman/sonarqube-ding-robot/releases/download/v1.0.0/sonarqube-ding-robot
[root@jenkins ~]# mv sonarqube-ding-robot /usr/local/bin/sonarqube_dingding
[root@jenkins ~]# chmod +x /usr/local/bin/sonarqube_dingding

2、启动 sonarqube-dingdingding ,然后传递对应 Sonarqube 的 Token

[root@jenkins ~]# vim /usr/lib/systemd/system/sonarqube_dingding.service
[Unit]
Description=sonarqube_dingding
Documentation=https://sonarqube-webhook/
After=network.target
[Service]
ExecStart=/usr/local/bin/sonarqube_dingding -addr 0.0.0.0:9002 -token sqa_0dd30b2ad16260b797d99b17f2f648ef6ee22570
ExecReload=/bin/kill -HUP
TimeoutStopSec=20s
Restart=always
[Install]
WantedBy=multi-user.target
# 启动
[root@jenkins ~]# systemctl daemon-reload
[root@jenkins ~]# systemctl start sonarqube_dingding
[root@jenkins ~]# systemctl enable sonarqube_dingding

3、检查程序是否启动成功

[root@jenkins ~]# netstat -lntp|grep 9002
tcp6       0      0 :::9002                 :::*                    LISTEN      23206/sonarqube_din
# 7.4 配置 SOnarqube-webhook

1、点击配置 -->Webhook--> 创建

7.png

2、填写名称和程序 URL(需要填写钉钉的 Token)

http://localhost:9002/dingtalk?access_token=55af9255dd264a6b4c51a4fcc6a0a4553488a7db87f1c2942702039248536c0c

8.png

3、配置 Server base URL,通知中点击分析结果可以链接至 SOnarqube 页面

12.png

4、执⾏ Sonarqube 的质量扫描,然后检查最终钉钉的通知结果 **(章节 5.2 Scanner 质检⽅式)**。

11.png

此文章已被阅读次数:正在加载...更新于

请我喝[茶]~( ̄▽ ̄)~*

Xu Yong 微信支付

微信支付

Xu Yong 支付宝

支付宝