SonarQube 从 9.9.5.1 升级到 2025.1.0 指南

目录

Overview

本文档介绍如何将 SonarQube 从版本 9.9.5.1(9.9.6) 升级到 2025.1.0。由于此次升级涉及 operator 4.0 版本的变更,现有 SonarQube 实例需要迁移到新版本 operator。

Prerequisites

  • 新版本 operator(sonarqube-ce-operator)已安装到集群中
  • 确保系统资源充足以支持升级
  • 使用产品功能将 SonarQube 升级至版本 9.9.5.1
  • 按照备份文档进行完整数据备份

Upgrade Steps

1. 停止旧版本实例部署

# 防止 operator 自动同步
kubectl patch deployment <old-sonarqube-name>-sonarqube -n <old-instance-namespace> \
  --type=json \
  -p '[{"op": "add", "path": "/metadata/annotations/skip-sync", "value": "true"}]'

# 将 deployment 副本数缩减为 0
kubectl scale deployment <old-sonarqube-name>-sonarqube -n <old-instance-namespace> --replicas=0

2. 配置新版本实例

2.1 数据库配置

注意:SonarQube 9.9.5 支持 PG 版本 11-15,SonarQube 2025.1.0 支持 PG 版本 13-17。若需迁移到新的 PG 版本,请参考官方 PG 文档

旧版本 SonarQube 使用的 PG 信息记录在 SonarQube 实例的 spec.database.secretName 中。

kubectl get sonarqube.operator.devops.alauda.io <old-sonarqube-name> -n <old-instance-namespace> -o jsonpath='{.spec.database.secretName}'

使用上述命令获取 secretName 后,再使用

kubectl get secret <secretName> -n <old-instance-namespace> -o yaml 获取 secret 信息

secret 内容示例如下:

apiVersion: v1
data:
  database: <database base64>
  host: <host base64>
  password: <password base64>
  port: <port base64>
  sslmode: <sslmode base64>
  username: <username base64>
kind: Secret
metadata:
  name: old-sonarqube-pg-secret
type: Opaque
  1. 按照备份文档进行完整数据备份

  2. 为新 SonarQube 实例创建新的 PG 数据库

建议为新版本 SonarQube 部署创建新的数据库,以避免污染旧数据库,并确保旧 SonarQube 能正常运行

  1. 按照备份文档进行数据迁移

  2. 创建新的数据库 secret,新版本 secret 只需存储密码:

# 注意:此处密码为新部署的 PG 数据库密码
kubectl create secret -n <namespace> generic sonarqube-db-secret \
  --from-literal=jdbc-password=<password>
  1. 创建带有数据库连接信息的新 SonarQube 实例配置,连接至之前的 PG 实例
spec:
  helmValues:
    postgresql:
      enabled: false  # 禁用默认 PostgreSQL
    jdbcOverwrite:
      enable: true
      # jdbcSecretName 为新创建的 secret 名称
      jdbcSecretName: sonarqube-db-secret
      # username、host、port、database 为新 PG 数据的用户名、主机、端口、数据库名
      jdbcUrl: jdbc:postgresql://<host>:<port>/<database>?socketTimeout=1500
      jdbcUsername: <username>

2.2 存储配置

根据旧 SonarQube 实例使用的存储类型选择对应配置:

kubectl get sonarqube.operator.devops.alauda.io <old-sonarqube-name> -n <old-instance-namespace> -o jsonpath='{.spec.persistence.type}'

使用 StorageClass:

使用已有 PVC 部署新实例

spec:
  helmValues:
    persistence:
      enabled: true
      ## 旧版本 PVC 名称为 <old-sonarqube-name>-sonarqube
      existingClaim: <old-sonarqube-name>-sonarqube

使用已有 PVC:

使用以下命令获取旧 SonarQube 版本使用的 PVC 名称

kubectl get sonarqube.operator.devops.alauda.io <old-sonarqube-name> -n <old-instance-namespace> -o jsonpath='{.spec.persistence.pvc.webServiceExistingClaim}'

spec:
  helmValues:
    persistence:
      enabled: true
      existingClaim: <spec.persistence.pvc.webServiceExistingClaim from old instance YAML>

使用 HostPath:

注意:新旧版本 HostPath 所在节点必须保持一致。path 需在旧版本路径基础上添加 portal 目录。例如,旧版本路径为 /sonarqube/,新版本路径应为 /sonarqube/portal/

spec:
  helmValues:
    nodeSelector:
      kubernetes.io/hostname: <node-name>
    persistence:
      enabled: false
      host:
        nodeName: <spec.persistence.location.nodeName from old instance YAML>
        path: <spec.persistence.location.path from old instance YAML>/portal # 旧版本控制器添加了 portal 目录,新版本需保持一致

2.3 网络配置

由于旧版本实例尚未清理,新版本网络配置不能与旧版本相同(即 ingress 不能使用相同域名,nodePort 不能使用相同端口),否则会产生冲突。暂时使用其他地址,升级完成后清理旧版本实例,再修改访问地址。

使用以下命令获取旧 SonarQube 版本使用的网络类型

kubectl get sonarqube.operator.devops.alauda.io <old-sonarqube-name> -n <old-instance-namespace> -o jsonpath='{.spec.service.type}'

Ingress 配置:

spec:
  helmValues:
    ingress:
      enabled: true
      hosts:
        - name: <spec.service.ingress.domainName from old instance YAML> ## 注意:旧实例存在时,新实例使用相同域名会冲突,需设置不同域名
      tls: ## 若旧版本为 https,则需配置 tls,否则不配置以下内容
        - secretName: <spec.service.ingress.secretName from old instance YAML> ## 旧版本证书可能在 cpaas-system,需要复制到实例部署的命名空间
          hosts:
            - <spec.service.ingress.domainName from old instance YAML>

NodePort 配置:

spec:
  helmValues:
    service:
      name: sonarqube
      type: NodePort
      nodePort: <spec.service.nodePort.port from old instance YAML> ## 注意:旧实例存在时,新实例使用相同 nodePort 会冲突,需设置不同 nodePort

配置 spec.externalURL:

spec:
  ## 若网络配置为 Ingress 类型,<new-sonar-url> 为 <spec.service.ingress.domainName from old instance YAML>
  ## 若网络配置为 NodePort 类型,使用命令 kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}' 获取 IP,<new-sonar-url> 为 IP:<nodePort>
  externalURL: <new-sonar-url>

其他配置

  • 保留插件:新版本需保留旧版本插件,添加配置 spec.helmValues.plugins.deleteDefaultPlugins 为 false
  • SSO 配置迁移:根据部署文档:SSO 配置重新配置
  • 资源配置迁移:根据旧实例的 spec.resourceAssign 配置新实例的 spec.helmValues.resources
  • helmValues 配置迁移:旧实例中大部分 helmValues 数据可直接迁移至新实例的 helmValues,例如 spec.helmValues.jvmOpts 可直接迁移

新版本完整 YAML 示例:

apiVersion: operator.alaudadevops.io/v1alpha1
kind: Sonarqube
metadata:
  name: new-sonarqube
spec:
  helmValues:
    plugins:
      deleteDefaultPlugins: false # 保留旧版本插件
    prometheusExporter: # 禁用默认 prometheus 监控,启动时需提前添加 jar 包
      enabled: false
    resources: # 设置资源限制,来源于旧实例 YAML 中的 spec.resourceAssign
      limits:
       cpu: 800m
       memory: 4Gi
      requests:
       cpu: 400m
       memory: 2Gi
    postgresql: # 禁用默认 PostgreSQL 实例
      enabled: false
    jdbcOverwrite: # 使用旧版本实例的 PG 信息配置
      enable: true
      jdbcSecretName: sonarqube-db-secret # 使用新创建的 secret 名称
      jdbcUrl: jdbc:postgresql://<pg.host>:<pg.port>/<pg.database>?socketTimeout=1500
      jdbcUsername: <pg.username>
    service: # 根据旧版本实例配置
      name: sonarqube
      type: NodePort
      nodePort: <spec.service.nodePort.port from old instance YAML>
    persistence: # 根据旧版本实例配置
      enabled: true
      existingClaim: <spec.persistence.pvc.webServiceExistingClaim from old instance YAML>

5. 手动执行数据结构迁移

注意:提前备份旧版本数据

访问 new-sonar-url/setup 并按照提示操作

6. 验证升级结果

检查以下内容确保升级成功:

  • 所有项目数据完整
  • 用户账号及权限正确
  • 插件状态正常(部分插件可能需要重新安装)
  • 历史分析数据可访问

7. 清理工作

  1. 确认新实例稳定运行后,可删除旧实例
  2. 调整网络配置,使其与原配置保持一致

Reference Documents