当前位置: 首页 > news >正文

Jenkins + SonarQube 从原理到实战一:基于 K8s 部署与使用(含中文插件与 Python 扫描)

前言

公司开发部门希望在 Jenkins 构建过程中自动集成 C/C++ 的代码扫描,正好我也没接触过 SonarQube,于是记录下从零开始部署 SonarQube 服务并集成到 CI/CD 的过程,供后来者参考。


一、SonarQube 原理与工作机制详解

1.1 什么是 SonarQube?

SonarQube 是一款开源的代码质量管理平台,通过静态代码分析识别代码中的 Bug、安全隐患、重复代码、不规范风格等问题。它支持 CI/CD 集成、质量门控、可视化报告、规则自定义等功能,有助于提升开发效率与软件质量。

设计目标包括:

  • 防止 Bug 潜入主干(Shifting Left)
  • 统一代码质量度量标准
  • 提升协作开发效率

1.2 工作机制与关键组件

SonarQube 的整体流程可概括为 3 个阶段:

🔍 阶段一:代码分析

  • 使用 SonarScanner 或 IDE 插件(如 SonarLint)对项目进行扫描
  • 收集源代码、控制流、函数结构、复杂度、注释等静态信息
  • 编译型语言(如 C++、Java)需借助 build-wrapper 或编译日志获取 AST 与依赖信息

🚀 阶段二:数据传输

  • 扫描结果打包成 .sonar 文件,通过 HTTP(S) 上传至 SonarQube Server
  • 上传时需配置 token 或用户名/密码

📊 阶段三:质量评估与展示

  • Server 接收数据后执行:

    • 规则匹配引擎(Rules Engine):查找违规代码
    • 质量门检查(Quality Gates):判断是否满足发布标准
    • 报告生成与持久化:结果写入数据库(如 PostgreSQL),UI 展示可视化报表

📘 例如,Python 代码中使用 eval() 会被标记为高危漏洞,质量门不通过,从而阻止 CI 发布。

💡 一开始我误以为是由 sonar-scanner 上传代码,SonarQube Server 再去分析,实际是本地的 sonar-scanner 完成分析,然后将结果上传到服务器展示。


二、SonarQube 的语言支持与扫描机制差异

不同语言使用不同的分析策略,以下是主流语言支持情况对比:

编程语言内置支持特殊要求分析深度说明
Java支持完整语义分析
Python可识别格式、Bug、注释等问题
JavaScript可结合 ESLint 使用
C/C++需安装插件 + 构建信息使用 sonar-cxx 插件 + build-wrapper
Go分析速度较快
PHP可配合 PHPUnit 报告
Kotlin与 IntelliJ 兼容性好
HTML/CSS/TS适用于前端项目

🔎 补充说明

  • 解释型语言(如 Python/JS):通过 AST + 规则匹配进行分析
  • 编译型语言(如 C++/Java):依赖编译输出、控制流图、符号表等更复杂结构
  • 通用指标包括:Bugs、Vulnerabilities、Code Smells、Coverage、Duplication,但其计算方式会根据语言有所差异

三、SonarQube 版本体系详解

SonarQube 提供多个版本以满足不同用户需求:

版本收费特性亮点
Community Edition免费支持主流语言、基本规则配置、质量门控、Web UI
Developer Edition商用支持 C/C++/Swift、数据流分析、分支分析、Git blame 支持
Enterprise Edition商用增加多项目仪表盘、多租户支持、安全审计、SAML 登录
Data Center Edition商用支持高可用集群部署、适合大型企业环境

本文使用的是 Community Edition,可通过插件支持 C/C++ 分析,但不支持商业功能如分支差异比较、安全数据流等。
如果社区版实现不了的功能,那就由社区版 + 开源插件实现。


四、在 K8s 上部署 SonarQube(+ PostgreSQL)

我存储用的是 NFS,请PV、PVC部分请根据实际情况改动。

SonarQube 不支持 MySQL
一般来说,SonarQube 里的 H2 数据库也够用,就不用不过具体看公司规模情况,不过生产环境还是用 PostgreSQL,后续更好维护一些。

PostgreSQL

PersistentVolume、PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolume
metadata:name: pv-postgresqlnamespace: sonar
spec:capacity:storage: 50GiaccessModes:- ReadWriteManystorageClassName: postgresqlpersistentVolumeReclaimPolicy: Retainnfs:server: NFS地址path: /k8s-nfs/sonar/postgresql
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-postgresqlnamespace: sonar
spec:accessModes:- ReadWriteManystorageClassName: postgresqlresources:requests:storage: 50Gi

Service、Deployment

kind: Service
metadata:name: postgresqlnamespace: sonar
spec:selector:app: postgresqlports:- protocol: TCPport: 5432targetPort: 5432name: postgresql
---
apiVersion: apps/v1
kind: Deployment
metadata:name: postgresqlnamespace: sonar
spec:replicas: 1selector:matchLabels:app: postgresqltemplate:metadata:name: postgresqllabels:app: postgresqlspec:nodeSelector:group: itcontainers:- name: postgresqlimage: postgres:17env:- name: TZvalue: 'Asia/Shanghai'- name: POSTGRES_USERvalue: sonar- name: POSTGRES_PASSWORDvalue: sonar_password- name: POSTGRES_DBvalue: sonarports:- name: postgresqlcontainerPort: 5432volumeMounts:- name: postgresqlmountPath: /var/lib/postgresql- name: postgresqlmountPath: /var/lib/postgresql/datasubPath: datavolumes:- name: postgresqlpersistentVolumeClaim:claimName:  pvc-postgresql

这里会一点小坑,在 dockerhub 上面搜 postgresql 会出现各种各样的数据库,但这都不是官方的,并且数据库目录 data 位置也不一样,官方的是 postgres

SonarQube

PersistentVolume、PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolume
metadata:name: pv-sonarqubenamespace: sonar
spec:capacity:storage: 50GiaccessModes:- ReadWriteManystorageClassName: sonarqubepersistentVolumeReclaimPolicy: Retainnfs:server: NFS地址path: /k8s-nfs/sonar/sonarqube
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-sonarqubenamespace: sonar
spec:accessModes:- ReadWriteManystorageClassName: sonarquberesources:requests:storage: 50Gi

Service、Deployment

apiVersion: v1
kind: Service
metadata:name: sonarqubenamespace: sonar
spec:selector:app: sonarqubetype: NodePortports:- protocol: TCPport: 9000targetPort: 9000nodePort: 32018name: sonarqube
---
apiVersion: v1
kind: Pod
metadata:name: sonarqubenamespace: sonarlabels:app: sonarqube
spec:containers:- name: sonarqubeimage: sonarqube:lts-community #我这里是9.9.x版本env:- name: TZvalue: 'Asia/Shanghai'- name: SONAR_JDBC_URLvalue: jdbc:postgresql://postgresql:5432/sonar- name: SONAR_JDBC_USERNAMEvalue: sonar- name: SONAR_JDBC_PASSWORDvalue: sonar_password- name: SONAR_WEB_JVM_OPTSvalue: "-Xmx2G -Xms1G -XX:+HeapDumpOnOutOfMemoryError"ports:- name: sonarqubecontainerPort: 9000volumeMounts:- name: sonarqubemountPath: /opt/sonarqube/extensionssubPath: extensions- name: sonarqubemountPath: /opt/sonarqube/logssubPath: logs- name: sonarqubemountPath: /opt/sonarqube/datasubPath: data- name: sonarqubemountPath: /opt/sonarqube/confsubPath: confrestartPolicy: Nevervolumes:- name: sonarqubepersistentVolumeClaim:claimName: pvc-sonarqube

然后给宿主机(Node 节点)修改下配置,否则es启动会报错:

echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
# 控制单个进程可拥有的虚拟内存映射区域(VMA)数量上限(例如内存映射文件、共享库等)
sudo sysctl -p
# 立即生效,无需重启系统

就可以 kubectl apply -f xxx.yaml运行起来了

📌 访问地址:http://NodeIP:32018

默认账号密码:admin,admin


五、中文插件离线安装指南

中文插件地址(github)
按对应版本下载:
在这里插入图片描述

简要步骤

下载的插件 .jar 文件,放到 sonarqube 的 extensions/plugins/ 路径下。
并重启服务后并重新登录,界面将变为中文。

个人感觉中文翻译很差,真的是机翻,还不如使用英文版。


六、Python 项目扫描实战

1. 新增项目

  • 左上角 “项目” - 右侧 :“新增项目” - “手工”
  • 输入 “显示名”“项目标识”“主分支名称”(可默认main),点击 “设置”;
  • 点击 “本地” ,确认 “令牌名称” ,点击 “创建” - “继续”
  • 点击 “其他 (比如 JS,TS,Go,Python,PHP…)”,并选择对内操作系统(我这里是Windows)

2. 安装 sonar-scanner

  • “新增项目” 做完后,下面会有下载链接和提示:
    在这里插入图片描述
  • 点击并访问,下载解压并且添加到系统/用户环境变量

    Linux 操作雷同。

3. 执行扫描:

  • 进入 Python 项目并执行:
    sonar-scanner.bat -D"sonar.projectKey=令牌名称" D"sonar.sources=." -D"sonar.host.url=http://sonar地址" D"sonar.login=sqp_91..."
    看到最后提示 SUCCESS 即成功。

4. 报告查看:

  • 在 Sonar 的 Web 页面上,选择相应项目可以查看。

注:
在 Windows 系统的扫描项目下配置sonar-project.properties文件不生效,Linux 系统反而没这个问题。

sonar-project.properties 只是把 -D 参数后面的东西写入配置文件,sonar-scanner.bat 执行时使用里面的配置而已。


结语

上面就是 SonarQube 的部署已经简单使用,后续将更新 SonarQube 如何通过 cxx 插件,实现 C/C++ 代码的扫描,以及打通 Windows AD 和 Jenkins。

http://www.dtcms.com/a/302143.html

相关文章:

  • 企业级日志分析系统ELK
  • R语言常用扩展包
  • 绳子切割 图论
  • Nestjs框架: 多租户与多数据库的架构设计与实现
  • 【LeetCode】算法详解#10 ---搜索二维矩阵II
  • React 项目中使用 Redux 实现公共状态共享
  • 从 WAIC 2025 的火爆,看 AI 时代视频“入口层”的技术演进
  • flink yarn 问题排查
  • [VLDB 2025]面向Flink集群巡检的交叉对比学习异常检测
  • 数据驱动与智能重构:定制开发开源AI智能名片S2B2C商城小程序对数字营销话语权的重塑
  • Spring ai 调用大模型
  • 盲盒抽卡机小程序系统开发:连接线上线下娱乐新桥梁
  • uniapp 更新apk有缓存点不动,卸载安装apk没有问题。android
  • 小程序组件的生命周期,以及在小程序中进行接口请求的方法设置
  • 网络编程概述与UDP编程
  • 【esp32s3】7 - VSCode + PlatformIO + Arduino + 构建项目
  • 基于神经网络的手写数字识别系统
  • 【论文阅读53】-CNN-LSTM-滑坡风险随时间变化研究
  • 【论文阅读】Safety Alignment Should Be Made More Than Just a Few Tokens Deep
  • cacti的RCE
  • 计算机视觉---Halcon概览
  • 实用工具类分享:BeanCopyUtils 实现对象深浅拷贝高效处理
  • 墨者:SQL手工注入漏洞测试(MySQL数据库-字符型)
  • haproxy实列
  • 开源AI智能体-JoyAgent集成Deepseek
  • AI论文阅读方法+arixiv
  • 元宇宙工厂前端新形态:Three.js与WebGL实现3D产线交互的轻量化之路
  • 使用std::transform实现并发计算
  • Java 开发新人,入职后的环境搭建和配置
  • 安宝特方案丨AI算法能力开放平台:适用于人工装配质检、点检、实操培训