SonarQube 实例部署

本文档介绍 SonarQube Operator 的订阅及 SonarQube 实例的部署功能。

Namespace Security Policy Restrictions

由于以下原因,SonarQube 不支持 在设置了 SPA(Security Policy Admission)策略为 RestrictedBaseline 的命名空间中部署:

  1. Init 容器需要 root 权限:SonarQube 使用 init 容器初始化 PVC 目录权限,需 root 权限,而 Restricted 策略不允许。
  2. InitSysctl 需要特权权限:默认情况下,SonarQube 使用 initSysctl 容器配置 Elasticsearch 所需的 sysctl 参数(如 vm.max_map_countfs.file-max),这需要 privileged 权限以修改系统内核参数。

建议:为 SonarQube 部署创建专用命名空间,并确保其安全策略设置为 privileged

前提条件

  • 本文档适用于平台提供的 SonarQube 9.9.5 及以上版本,采用 Operator 等技术与平台解耦。

  • 请确保 SonarQube Operator 已部署(订阅)到目标集群,即已准备好通过 SonarQube Operator 创建实例。

部署规划

SonarQube 支持多种资源配置以满足不同客户场景。不同场景下所需资源、配置等存在较大差异。因此,本节介绍部署 SonarQube 实例前需考虑的方面及决策点的影响,便于用户基于此信息进行后续具体实例部署。

基本信息

  1. 平台提供的 SonarQube Operator 基于社区官方 SonarQube Chart,增强了企业能力,如 IPv6 支持和安全漏洞修复。功能上与社区版完全兼容,用户体验上通过可选定制模板等方式提升 SonarQube 部署便利性。

部署前资源规划

部署前资源规划指在部署前做出的决策,这些决策将在部署过程中生效。

更多环境资源建议请参考官方文档:https://docs.sonarsource.com/sonarqube-server/2025.1/setup-and-upgrade/installation-requirements/server-host/#hardware

实例部署

使用 Quickstart Template 模板部署

该模板用于快速创建轻量级 SonarQube 实例,适用于开发和测试场景,不建议用于生产环境。

  • 计算资源:800m CPU,4 Gi 内存
  • 存储:使用节点本地存储,配置存储节点 IP 和路径
  • 网络访问:使用 NodePort 访问服务,共享存储节点 IP,指定端口

使用 Production Template 模板部署

该模板用于快速创建生产环境 SonarQube 实例,适用于生产场景,推荐用于生产环境。

  • 计算资源:8 核 CPU,16 Gi 内存
  • 存储:使用 PVC 存储,配置存储类
  • 网络访问:使用域名访问服务

使用 YAML 部署

资源配置

SonarQube 只需配置整体资源,例如:

spec:
  helmValues:
    resources:
      limits:
        cpu: 800m
        memory: 4Gi
      requests:
        cpu: 400m
        memory: 2Gi

详情请参见 SonarQube Chart 中的资源描述

网络配置

网络配置分为两类:

  • 基于 ingress 的网络配置
  • 基于 NodePort 的网络配置

基于 ingress 的网络配置支持 https 和 http 协议,需提前在集群中部署 ingress controller。

spec:
  helmValues:
    ingress:
      enabled: true
      hosts:
        - name: test-ingress-https.example.com
      tls:
        - secretName: test-tls-cert
          hosts:
            - test-ingress-http.example.com

基于 NodePort 的网络配置:

spec:
  helmValues:
    service:
      name: sonarqube
      type: NodePort
      nodePort: <nodeport.http>

存储配置

存储配置主要分为三类:

  • 基于 StorageClass 的存储配置
  • 基于 PVC 的存储配置
  • 基于 HostPath 的存储配置

基于 StorageClass 的存储配置:

spec:
  helmValues:
    persistence:
      enabled: true
      storageClass: <storage-class.rwm> ## 需提前创建 StorageClass
      size: 10Gi

基于 PVC 的存储配置:

spec:
  helmValues:
    persistence:
      enabled: true
      existingClaim: sonarqube-pvc ## 需提前创建 PVC

基于 HostPath 的存储配置:

spec:
  helmValues:
    nodeSelector:
      kubernetes.io/hostname: <node.random>  ## 选择部署节点
    
    persistence:
      enabled: false
      host:
        nodeName: <node.random> ## 节点名称
        path: /tmp/sonarqube-<template.{{randAlphaNum 10}}> ## 选择部署节点并指定存储路径

PostgreSQL 访问凭据配置

需在平台提前创建 PostgreSQL 实例,并在 PostgreSQL 中创建数据库供使用。

SonarQube 25.1.0 支持的 PostgreSQL 版本为 13 至 17。

PostgreSQL 访问通过配置特定格式的 secret 资源实现,详情见 配置 PostgreSQL 及账号访问凭据

在 SonarQube yaml 中使用 secret 配置访问 PG 的凭据:

spec:
  helmValues:
    postgresql:
      enabled: false ## 禁用默认 PostgreSQL 实例
    jdbcOverwrite:
      enable: true
      jdbcSecretName: postgres-password ## 连接 PG 的凭据
      jdbcUrl: jdbc:postgresql://<pg.host>:<pg.port>/<pg.database>?socketTimeout=1500 ## 连接 PG 地址
      jdbcUsername: postgres ## PG 访问用户

管理员账号配置

初始化 SonarQube 实例时需配置管理员账号及密码,通过配置 secret 资源实现,详情见 配置 PostgreSQL 及账号访问凭据

通过 YAML 指定给 SonarQube:

spec:
  helmValues:
    account:
      adminPasswordSecretName: sonarqube-root-password

完整 YAML 示例

NodePort、PVC、PostgreSQL、管理员账号

apiVersion: operator.alaudadevops.io/v1alpha1
kind: Sonarqube
metadata:
  name: sonarqube-demo
spec:
  helmValues:
    prometheusExporter: # 禁用默认 prometheus 监控,启动时需提前添加 jar 包
      enabled: false
    resources: # 设置资源限制
      limits:
       cpu: 800m
       memory: 4Gi
      requests:
       cpu: 400m
       memory: 2Gi
    postgresql: # 禁用默认 PostgreSQL 实例
      enabled: false
    jdbcOverwrite: # 使用预创建的 PostgreSQL 实例
      enable: true
      jdbcSecretName: postgres-password
      jdbcUrl: jdbc:postgresql://<pg.host>:<pg.port>/<pg.database>?socketTimeout=1500
      jdbcUsername: <pg.username>
    service: # 使用 NodePort 暴露 SonarQube 实例
      name: sonarqube
      type: NodePort
      nodePort: <nodeport.http>
    account: # 设置 Root 密码
      adminPasswordSecretName: sonarqube-root-password
    persistence: # 使用 PVC 挂载存储
      enabled: true
      existingClaim: sonarqube-pvc

SSO 配置

配置 SSO 包括以下步骤:

在 global 集群注册 SSO 认证客户端

  • 在 global 集群创建以下 OAuth2Client 资源以注册 SSO 认证客户端。
  • 配置 SonarQube 实例使用 SSO 认证
apiVersion: dex.coreos.com/v1
kind: OAuth2Client
name: OIDC
metadata:
  name: onxw4ylsof2wezjnmrsxrs7sttsiiirdeu # 该值基于 id 字段的哈希计算,在线计算器:https://go.dev/play/p/QsoqUohsKok
  namespace: cpaas-system
id: sonarqube-dex # 客户端 id
public: false
redirectURIs:
  - <sonarqube-host>/* # SonarQube 认证回调地址,<sonarqube-host> 替换为 SonarQube 实例访问地址
secret: Z2l0bGFiLW9mZmljaWFsLTAK # 客户端密钥
spec: {}
字段说明示例
name资源显示名称OIDC
idSSO 认证客户端 ID,允许任意值,alauda-dex 保留,可能导致冲突。sonarqube-dex
secret用于 SSO 认证的客户端密钥,可设置任意值。Z2l0bGFiLW9mZmljaWFsLTAK
redirectURIsSonarQube 认证回调 URL,格式为 <sonarqube-host>/*https://example.sonarqube.com/*
metadata.name资源名称,必须基于 id 字段的哈希计算生成。可使用在线哈希计算器如 https://go.dev/play/p/QsoqUohsKok 生成。onxw4ylsof2wezjnmrsxrs7sttsiiirdeu
metadata.namespace平台系统命名空间,必须为 cpaas-systemcpaas-system

将 SSO 配置添加到 SonarQube 实例:

spec:
  helmValues:
    sonarProperties:
      sonar.core.serverBaseURL: <sonarqube url>
      sonar.forceAuthentication: false
      sonar.auth.oidc.enabled: true
      sonar.auth.oidc.issuerUri: <platform-url>/dex
      sonar.auth.oidc.clientId.secured: sonarqube-dex # 客户端 id
      sonar.auth.oidc.clientSecret.secured: Z2l0bGFiLW9mZmljaWFsLTAK  # 客户端密钥
      sonar.auth.oidc.loginStrategy: Preferred username
      sonar.auth.oidc.providerConfiguration: '{"issuer":"<platform-url>/dex","authorization_endpoint":"<platform-url>/dex/auth","token_endpoint":"<platform-url>/dex/token","jwks_uri":"<platform-url>/dex/keys","response_types_supported":["code","id_token","token"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"],"scopes_supported":["openid","email","groups","profile","offline_access"],"token_endpoint_auth_methods_supported":["client_secret_basic"],"claims_supported":["aud","email","email_verified","exp","iat","iss","locale","name","sub"]}'

为使用自签名证书的平台启用 SSO

若平台通过 https 访问且使用自签名证书,则需将自签名证书的 CA 挂载到 SonarQube 实例,方法如下:

在 global 集群的 cpaas-system 命名空间中,找到名为 dex.tls 的 secret,从中获取 ca.crt 和 tls.crt 内容,保存为新 secret 并创建到 SonarQube 实例所在命名空间。

apiVersion: v1
data:
  ca.crt: <base64 encode data>
  tls.crt: <base64 encode data>
kind: Secret
metadata:
  name: dex-tls
  namespace: cpaas-system

编辑 SonarQube 实例使用该 CA:

spec:
  helmValues:
    caCerts:
      enabled: true
      secret: dex-tls

在纯 IPv6 集群中使用

在纯 IPv6 集群环境部署时,由于 Java 默认支持双栈,需要显式配置 IPv6 协议,添加以下配置以确保正常连通:

spec:
  helmValues:
    env:
      - name: JAVA_TOOL_OPTIONS
        value: '-Djava.net.preferIPv6Addresses=true'
    sonarProperties:
      sonar.cluster.node.search.host: '[::1]'
      sonar.cluster.node.es.host: '[::1]'
      sonar.web.javaAdditionalOpts: '-javaagent:/opt/sonarqube/extensions/plugins/sonarqube-community-branch-plugin-1.23.1.jar=web -Djava.net.preferIPv6Addresses=true'