ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DevOps全链路实战 | 第 10 天:SonarQube 代码质量检查:SonarQube 部署与 GitLab CI 集成

DevOps全链路实战 | 第 10 天:SonarQube 代码质量检查:SonarQube 部署与 GitLab CI 集成 第 10/19 天引言在前面几天的实战中我们已经搭建了 K8s 集群、Harbor 私有镜像仓库、GitLab CE 代码托管平台以及 GitLab CI 流水线实现了从代码提交到镜像构建的自动化闭环。然而一条成熟的 DevOps 管道不仅要保证”能构建、能部署”更要保证”构建出来的代码质量是达标的”。代码质量是 DevOps 全链路中不可或缺的一环。如果没有自动化质量门禁低质量代码会随着 CI/CD 流水线一路流向生产环境技术债务不断积累最终引发线上故障。SonarQube正是解决这一问题的利器——它能够对代码进行静态分析覆盖代码规范、安全漏洞、重复代码、复杂度、测试覆盖率等多个维度并可以在 CI 流水线中设置质量门禁Quality Gate只有通过检查的代码才允许继续部署。今天我们将在 K8s 集群中部署 SonarQube配置 PostgreSQL 持久化存储生成 Sonar 令牌与项目配置然后将其集成到 GitLab CI 流水线中实现代码提交后自动触发静态分析、质量门禁校验的完整流程。核心概念SonarQube 架构概述SonarQube 采用经典的 Server Scanner 架构SonarQube ServerWeb 界面 计算引擎 搜索服务ElasticSearch负责项目管理、规则配置、质量门禁定义和报告展示Sonar Scanner在 CI 流水线中运行的扫描器负责读取源代码、执行分析、将结果上报给 Server数据库SonarQube 支持 PostgreSQL、Oracle、SQL Server 等PostgreSQL 是 K8s 环境下的首选质量门禁Quality Gate质量门禁是 SonarQube 最核心的概念之一。它定义了一组条件例如新增代码的 Bug 数量必须为 0新增代码的安全漏洞等级不得高于 Critical新增代码的重复率不得超过 3%新增代码的测试覆盖率不得低于 80%只有所有条件都满足Quality Gate 才会返回PASSED。在 CI 流水线中我们可以根据这个结果决定是否放行后续的构建和部署步骤。SonarScanner 工作原理SonarScanner 在执行时需要以下关键参数sonar.host.urlSonarQube Server 地址sonar.projectKey项目唯一标识sonar.projectName项目显示名称sonar.sources源代码目录sonar.login认证令牌Scanner 执行后会向 Server 上传分析报告Server 计算引擎处理后返回 Quality Gate 结果。实战步骤一、部署 PostgreSQL 数据库SonarQube 需要外部数据库存储配置和分析数据。我们先在devops-tools命名空间部署 PostgreSQL。 代码示例# 创建命名空间kubectl create namespace devops-tools# 添加 Bitnami Helm 仓库helm repo add bitnami https://charts.bitnami.com/bitnamihelm repo update# 安装 PostgreSQLhelm install postgresql bitnami/postgresql–namespace devops-tools–set global.postgresql.auth.postgresPasswordSonarPass123–set global.postgresql.auth.databasesonar–set primary.persistence.size10Gi–set primary.persistence.storageClasslocal-path安装完成后验证 PostgreSQL Pod 状态 代码示例kubectl get pods -n devops-tools -l app.kubernetes.io/namepostgresql# 期望输出postgresql-0 1/1 Running 0 2m二、部署 SonarQube Server使用官方 Helm Chart 部署 SonarQube Community Edition 代码示例# 添加 SonarQube Helm 仓库helm repo add sonarqube https://SonarSource.github.io/sonarqube-helm-charthelm repo update# 创建 values 文件cat /tmp/sonar-values.yaml ‘EOF’edition: “community”image:tag: “10.6-community”postgresql:enabled: false # 使用外部 PostgreSQLjdbcOverwrite:enabled: truejdbcUrl: “jdbc:postgresql://postgresql.devops-tools.svc.cluster.local:5432/sonar”jdbcUsername: “postgres”jdbcPassword: “SonarPass123”persistence:enabled: truestorageClass: “local-path”size: “10Gi”sonarProperties:sonar.ce.workerCount: “2”sonar.search.javaOpts: “-Xmx1g”sonar.web.javaOpts: “-Xmx1g”service:type: NodePortport: 9000nodePort: 30900EOF# 安装 SonarQubehelm install sonarqube sonarqube/sonarqube–namespace devops-tools–values /tmp/sonar-values.yaml–version 10.6.1三、验证 SonarQube 启动SonarQube 首次启动需要初始化 ElasticSearch 和数据库通常需要 3-5 分钟 代码示例# 监控启动日志kubectl logs -f deployment/sonarqube -n devops-tools# 关键日志出现表示启动成功# SonarQube is up# App is ready at /sonarqube# 检查 Pod 状态kubectl get pods -n devops-tools -l appsonarqube启动完成后通过浏览器访问http://节点IP:30900使用默认账号admin / admin登录首次登录会要求修改密码。四、配置 SonarQube 项目与令牌登录 SonarQube Web 界面后执行以下配置安装中文语言包进入 Administration → Marketplace搜索 “Chinese Pack”点击安装并重启创建项目令牌进入 My Account → Security → Generate Tokens 代码示例# 通过 API 创建令牌假设 SonarQube 已启动curl -u admin:YourNewPassword123-X POST “http://localhost:30900/api/user_tokens/generate”-d “namegitlab-ci-tokentypePROJECT_ANALYSIS_TOKENprojectKeymy-java-app”# 响应示例# {“token”:“squ_xxxxxxxxxxxxxxxxxxxxxxxxx”,“type”:“PROJECT_ANALYSIS_TOKEN”,…}将返回的squ_开头的令牌保存好后续 GitLab CI 需要用到。五、配置质量门禁SonarQube 默认提供了一个标准 Quality Gate我们可以自定义更严格的质量门禁 代码示例{“name”: “DevOps Production Gate”,“conditions”: [{“metric”: “new_vulnerabilities”,“operator”: “GT”,“errorThreshold”: “0”,“statusOnError”: true},{“metric”: “new_bugs”,“operator”: “GT”,“errorThreshold”: “0”,“statusOnError”: true},{“metric”: “new_code_smells”,“operator”: “GT”,“errorThreshold”: “5”,“statusOnError”: true},{“metric”: “new_duplicated_lines_density”,“operator”: “GT”,“errorThreshold”: “3”,“statusOnError”: true},{“metric”: “new_coverage”,“operator”: “LT”,“errorThreshold”: “80”,“statusOnError”: true}]}通过 API 创建并应用 代码示例# 创建自定义质量门禁curl -u admin:YourNewPassword123-X POST “http://localhost:30900/api/qualitygates/create”-d “nameDevOps Production Gate”# 设置为默认质量门禁curl -u admin:YourNewPassword123-X POST “http://localhost:30900/api/qualitygates/set_default”-d “nameDevOps Production Gate”六、GitLab CI 集成配置这是全链路集成的关键步骤。我们需要在 GitLab 中配置 CI 变量并修改.gitlab-ci.yml加入 SonarQube 扫描阶段。首先在 GitLab 项目中添加 CI/CD 变量Settings → CI/CD → VariablesSONAR_HOST_URL值为http://sonarqube.devops-tools.svc.cluster.local:9000SONAR_TOKEN值为前面生成的squ_xxxxx令牌然后编写.gitlab-ci.yml在构建阶段之后加入 SonarQube 分析 代码示例stages:– build– test– sonar– deployvariables:IMAGE_NAME: harbor.stellardata.top/devops/my-java-appIMAGE_TAG: $CI_COMMIT_SHORT_SHAkaniko-build:stage: buildimage:name: gcr.io/kaniko-project/executor:debugentrypoint: [“”]script:– /kaniko/executor–context“${CI_PROJECT_DIR}”–dockerfile“${CI_PROJECT_DIR}/Dockerfile”–destination“IMAGE_NAME:{IMAGE\_NAME}:IMAGE_NAME:{IMAGE_TAG}”–skip-tls-verifyonly:– mainsonarqube-check:stage: sonarimage:name: sonarsource/sonar-scanner-cli:latestentrypoint: [“”]variables:SONAR_USER_HOME: “${CI_PROJECT_DIR}/.sonar”GIT_DEPTH: “0”cache:key: “${CI_JOB_NAME}”paths:– .sonar/cachescript:– sonar-scanner-Dsonar.projectKeymy-java-app-Dsonar.projectName“My Java App”-Dsonar.sourcessrc-Dsonar.host.url${SONAR_HOST_URL}-Dsonar.login${SONAR_TOKEN}-Dsonar.qualitygate.waittrue-Dsonar.java.binariestarget/classesallow_failure: falseonly:– main关键参数说明sonar.qualitygate.waittrue阻塞等待 Quality Gate 结果返回。如果门禁失败CI Job 将报错退出allow_failure: false质量门禁未通过时整个流水线中止阻止后续 deploy 阶段执行sonar.java.binariesJava 项目必须指定编译产物路径否则无法执行部分规则检查GIT_DEPTH: 0完整克隆 Git 历史SonarQube 需要计算新增代码的变更差异七、验证 CI 集成效果提交代码触发流水线后观察 GitLab CI 的执行结果 代码示例# 在 SonarQube 中查看项目分析结果curl -u admin:YourNewPassword123“http://localhost:30900/api/components/show?componentmy-java-app”# 查询质量门禁状态curl -u admin:YourNewPassword123“http://localhost:30900/api/qualitygates/project_status?projectKeymy-java-app”# 响应示例# {# “projectStatus”: {# “status”: “OK”,# “conditions”: [# {“status”: “OK”, “metricKey”: “new_bugs”, …},# {“status”: “OK”, “metricKey”: “new_vulnerabilities”, …}# ]# }# }当status为OK时Quality Gate 通过CI 流水线继续执行 deploy 阶段当status为ERROR时流水线在 sonar 阶段中止阻止有问题的代码进入生产环境。常见问题1. SonarQube Pod 启动失败日志报 vm.max_map_count 不足SonarQube 内置的 ElasticSearch 要求宿主机vm.max_map_count至少为 262144。在所有 K8s 节点上执行 代码示例sysctl -w vm.max_map_count262144echo “vm.max_map_count262144” /etc/sysctl.conf也可以通过安装 initContainer 的 sysctl 修改来处理但生产环境推荐直接在节点层面永久设置。2. SonarScanner 报错 “Insufficient privileges”确认 CI 变量中SONAR_TOKEN使用的是 PROJECT_ANALYSIS_TOKEN 类型且该令牌对应的用户对目标项目有 “Execute Analysis” 权限。建议在 SonarQube 中创建专用的 CI 账号避免使用 admin 账号。3. Quality Gate 状态一直显示 PENDING这是因为sonar.qualitygate.waittrue未配置Scanner 不会等待分析结果。另外也可能是 SonarQube Server 的 Compute Engine 负载过高。如果项目较大可以适当增加sonar.ce.workerCount来加速分析。4. Java 项目扫描报 “Class not found”SonarQube 的部分 Java 规则需要读取编译后的.class文件。确保sonar.java.binaries参数指向正确的编译产物目录且在 sonar 阶段之前已经执行了mvn compile或gradle build。总结今天我们完成了 SonarQube 在 K8s 中的完整部署并将其深度集成到 GitLab CI 流水线中。核心要点回顾PostgreSQL SonarQube 部署使用 Helm 在devops-tools命名空间快速部署配置 NodePort 方便访问质量门禁机制自定义 Quality Gate 条件将代码质量检查从”事后审查”变为”流水线门禁”GitLab CI 集成通过 CI 变量注入 SonarQube 配置使用sonar-scanner-cli镜像执行分析qualitygate.waittrue实现阻塞式门禁校验闭环保障质量门禁未通过时流水线在 sonar 阶段中止有问题的代码无法继续部署至此我们的 DevOps 全链路已经补齐了”代码质量”这一关键环节。从代码提交 → Kaniko 构建镜像 → SonarQube 质量检查 → Harbor 推送 → Argo CD 部署一条带有质量门禁的完整 CI/CD 管道已经成型。下期预告明天我们将进入可观测性篇章发布第 11 天Prometheus 部署kube-prometheus-stack 与 ServiceMonitor 指标采集。届时将在 K8s 集群中部署 Prometheus 全套监控栈配置 ServiceMonitor 自动发现服务指标为后续的 Grafana 看板和告警系统奠定数据基础。系列大纲全链路架构总览从代码提交到灰度发布的完整管道设计K8s 集群与网络基础kubeadm 离线部署与 Cilium 网络插件Harbor 私有镜像仓库部署与验证Helm 安装与镜像推送GitLab CE 自托管部署代码仓库与项目管理平台GitLab Runner 配置K8s Executor 与 RBAC 权限设置GitLab CI 流水线搭建.gitlab-ci.yml 与 Kaniko 无守护进程构建Harbor 镜像版本管理与 Tag 策略配置Argo CD 部署与 GitOps 配置仓库创建CI 与 CD 联动从代码提交到部署的全自动闭环SonarQube 代码质量检查SonarQube 部署与 GitLab CI 集成今天Prometheus 部署kube-prometheus-stack 与 ServiceMonitor 指标采集Grafana 看板搭建K8s 标准面板与自定义业务看板告警规则与 Alertmanager钉钉/邮件通知渠道配置Argo Rollouts 安装与基础概念CRD 与 Rollout 资源定义金丝雀发布实战setWeight 流量分割与 pause 步骤AnalysisTemplate 指标分析与自动回滚机制全链路端到端演示代码提交→构建→代码检查→灰度→监控→告警完整流程生产化加固要点Harbor/GitLab/Argo CD/SonarQube 高可用方案供应链安全闭环Trivy 扫描 cosign 签名 Kyverno 验签
返回列表