SonarQube 升级指南:从 9.9.5.1 到 2025.1.0
概述
本文件描述了如何将 SonarQube 从版本 9.9.5.1(9.9.6)升级到 2025.1.0。由于此次升级涉及到操作员 4.0 版本的变化,因此现有的 SonarQube 实例需要迁移到新的版本操作员。
先决条件
- 已在集群中安装新的版本操作员(sonarqube-ce-operator)
- 确保有足够的系统资源可用于升级
- 使用产品功能将 SonarQube 升级到版本 9.9.5.1
- 根据 备份文档 进行完整的数据备份
升级步骤
1. 停止旧版本实例的部署
# 防止操作员自动同步
kubectl patch deployment <old-sonarqube-name>-sonarqube -n <old-instance-namespace> \
--type=json \
-p '[{"op": "add", "path": "/metadata/annotations/skip-sync", "value": "true"}]'
# 将部署规模缩减至 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
-
根据 备份文档 进行完整的数据备份。
-
为新的 SonarQube 实例创建一个新的 PG 数据库。
建议为部署新的 SonarQube 版本创建一个新的数据库,以避免污染旧数据库,并确保旧 SonarQube 仍能正常运行。
-
根据 备份文档 进行数据迁移。
-
创建一个新的数据库 secret。新版本的 secret 只需要存储密码:
# 注意:这里的密码是新部署的 PG 数据库的密码
kubectl create secret -n <namespace> generic sonarqube-db-secret \
--from-literal=jdbc-password=<password>
- 创建一个新的 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 可以直接迁移到新实例的 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. 清理工作
- 在确认新实例稳定运行后,可以删除旧实例。
- 调整网络配置,使其与原始配置一致。
参考文档