当前位置: 首页 > 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.lryc.cn/news/602064.html

相关文章:

  • 力扣1457. 二叉树中的伪回文路径
  • 力扣面试150(42/150)
  • 旧物回收小程序:科技赋能,让旧物回收焕发生机
  • 软件测试之功能测试
  • 6种将iPhone照片传输到Windows 10电脑的方法
  • 跨境协作系统文化适配:多语言环境下的业务符号隐喻与交互习惯
  • 快速了解MySQL
  • Ubuntu lamp
  • 分布式IO选型指南:2025年分布式无线远程IO品牌及采集控制方案详解
  • 四、计算机组成原理——第3章:存储系统
  • 低速信号设计之 SMBUS 篇
  • Power Query概述及导入多源数据方法
  • 从fork到exit:剖析Linux进程的诞生、消亡机制
  • C盘清理大赛技术指南
  • 凸优化:凸函数的一些常用性质
  • 动/静态库的原理及制作
  • 开源B端生态掘金:从Odoo二次开发到行业专属模块的技术变现
  • Qwen 系列模型实现文本改写工具
  • Java 大视界 -- 基于 Java 的大数据实时流处理在智能电网分布式能源接入与电网稳定性保障中的应用(368)
  • Java从入门到精通!第十八天(JDK17安装以及网络编程) 完结篇!!!
  • WPF,窗口拖动事件与窗口内控件点击事件
  • Visual Studio Code使用
  • MCP资源管理深度实践:动态数据源集成方案
  • Jenkins vs GitLab CI/CD vs GitHub Actions在容器化部署流水线中的对比分析与实践指南
  • Spring Boot 2整合Druid的两种方式
  • Spring Boot日志开发实战手册:集成/输出/级别控制/持久化精要
  • docker排查OOM
  • c++ 中的字符串相关的操作
  • 「源力觉醒 创作者计划」_文心大模型4.5系列开源模型,意味着什么?对开发者、对行业生态有何影响?
  • 重复文件清理工具,附免费链接