写在前面
为啥要升级
目前使用的是SonarQube 6.7,已经有超过100个项目在使用。近期开发同学反馈,IDEA SonarLint结合使用非常好用,可以在代码编写和问题产生的第一现场解决问题。但是开发同学也希望,能使用IDEA SonarLint SonarQube,与最终“质量门禁”使用相同的规则,以促进质量内建。 但是在使用过程中发现,由于SonarQube6.7版本过低,新版本的IDEA SonarLint无法与之配合使用。考虑之下,决定启动SonarQube的升级,也启动了踩坑之旅。
升级路径
首先,去SonarQube官网了解了一下。 https://docs.sonarqube.org/latest/setup/upgrading/
Upgrade the Server Upgrading across multiple, non-LTS versions is handled automatically. However, if you have an LTS version in your migration path, you must first migrate to this LTS and then migrate to your target version. Example 1 : 5.1 -> 7.0, migration path is 5.1 -> 5.6.7 LTS -> 6.7.x LTS -> 7.0 Example 2 : 6.2 -> 6.7, migration path is 6.2 -> 6.7.x LTS (where x is the latest patch available for 6.7 - you don't need to install all the intermediary patches, just take the latest)
根据官网的说法,如果我们要升级到目前最新的版本,也就是8.1版本,升级路径会是这样的: 6.7->6.7LTS->7.9 LTS->8.1 也就是先升级到离目前版本最近的一个长期维护版本LTS,然后再升级到离目标版本最近的一个升级版本,并最终达到最新版本。
看得见的坑
1、数据库不再支持MySQL 根据官网的描述,SonarQube在7.9版本开始就不再支持MySQL了。开源的数据库只支持PostgreSQL一种数据库类型了。当然默认自带的H2也算,不过只能用于demo,不能用于生产。所以,我们要经历数据库迁移。 2、JDK也要升级 JDK8也不在支持范围内了。
3、插件的版本升级
社区版默认是没有branch、C 、PLSQL等插件的,我们是通过开源版本来获得这些能力的。但是高版本中是否支持,需要验证。一般来说,开源社区的支持存在一定的滞后性。
升级目标:服务不断,数据不乱
简单来说,对外部用户来说,一切无影响。对于在使用现有系统的用户来说,之前的流水线不需要做调整,访问和浏览SonarQube也不受影响。这也就意味着扫描记录、账号与权限等需要维持不变。
新版本安装测试
作为整个过程的第一步,我们先在测试环境进行了SonarQube7.9.2LTS的安装测试
内核调优
根据文档, https://docs.sonarqube.org/latest/requirements/requirements/ 需要设置linux的几个内核参数
代码语言:javascript复制sysctl -w vm.max_map_count=262144
sysctl -w fs.file-max=65536
ulimit -u 4096 sonarqube
ulimit -n 65536 sonarqube
坑1- 上述参数的设定需要写入文件,上述命令行只对当前session有效,系统重启后又恢复前值,会导致系统无法正常启动。
离线安装
版本包获取 SonarQube https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.9.2.zipOpenJDK https://jdk.java.net/archive/
安装 上传到目标服务器解压即可
配置
SonarQube只有两个配置文件需要配置。
首先是数据库
如果你只是用来demo一下,sonar自带了一个H2的嵌入式数据库。可以不修改任何配置直接使用即可。
代码语言:javascript复制#--------------------------------------------------------------------------------------------------
# DATABASE
#
# IMPORTANT:
# - The embedded H2 database is used by default. It is recommended for tests but not for
# production use. Supported databases are Oracle, PostgreSQL and Microsoft SQLServer.
#----- Embedded Database (default)
# H2 embedded database server listening port, defaults to 9092
#sonar.embeddedDatabase.port=9092
如果需要需要使用别的类型的数据库,譬如Oracle,则需要修改以下三个参数
代码语言:javascript复制# User credentials.
# Permissions to create tables, indices and triggers must be granted to JDBC user.
# The schema must be created first.
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
#----- Oracle 11g/12c/18c/19c
# The Oracle JDBC driver must be copied into the directory extensions/jdbc-driver/oracle/.
# Only the thin client is supported, and we recommend using the latest Oracle JDBC driver. See
# https://jira.sonarsource.com/browse/SONAR-9758 for more details.
# If you need to set the schema, please refer to http://jira.sonarsource.com/browse/SONAR-5000
#sonar.jdbc.url=jdbc:oracle:thin:@localhost:1521/XE
sonar.jdbc.url=jdbc:oracle:thin:@localhost:1521:SONAR
坑2- JDBC URL有3种写法,在笔者的环境中,使用默认写法无法识别,修改为示例写法后通过,成功连接上数据库。
坑3- Sonar没有自带连接ORACLE所需的OJDBC jar包,需要自行下载后放置到$SONAR_HOME extensionsjdbc-driveroracle目录下。
坑4- 要注意下OJDBC jar包的与ORACLE以及OS的兼容性。相同的包,在RHEL6.7上可以用,但是在RHEL7.3上就得换更新的OJDBC包了
创建数据库
根据之前的配置,我们需要在Oracle服务器上新建一个名为sonar 的schema,作为sonarqube的后端数据库。详细的数据库创建脚本可以和DBA联系,以下只是 一个案例。
代码语言:javascript复制CREATE SMALLFILE TABLESPACE "TS_SONAR"
LOGGING DATAFILE '/oradata/ts_sonar.dbf'
SIZE 4096M REUSE AUTOEXTEND ON NEXT 100M
MAXSIZE 31G EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
CREATE USER sonar IDENTIFIED BY sonar;
ALTER USER sonar DEFAULT TABLESPACE ts_sonar;
GRANT UNLIMITED TABLESPACE, CONNECT, RESOURCE,
CREATE SESSION,
CREATE TABLE,
CREATE VIEW,
CREATE SYNONYM,
CREATE SEQUENCE,
CREATE PROCEDURE,
CREATE TRIGGER TO sonar;
Web 端口
如果默认端口被占用,需要修改端口号。譬如出于测试的需要,在一台服务器上部署了多个SonarQube,则必须至少修改以下两个端口。
代码语言:javascript复制# TCP port for incoming HTTP connections. Default value is 9000.
sonar.web.port=19000
# Elasticsearch port. Default is 9001. Use 0 to get a free port.
# As a security precaution, should be blocked by a firewall and not exposed to the Internet.
sonar.search.port=19001
禁止自动更新
由于我们是在内网进行安装,没有互联网连接,所以Sonar的自动更新服务也就不需要了,可以禁止掉。并且如果没有禁止的话,会经常在日志中报更新服务无法连接的错误,比较烦人且影响监控。
代码语言:javascript复制# UPDATE CENTER
# Update Center requires an internet connection to request https://update.sonarsource.org
# It is enabled by default.
sonar.updatecenter.activate=false
与LDAP集成
作为一个企业级服务的话,在账号和权限上与外部用户体系集成是必须必要的一个功能。通常是与企业的LDAP服务(AD)集成。 主要是分为三部分,1)LDAP服务器的连接信息 2)用户的关联 3)用户组的关联。
代码语言:javascript复制# Enable the LDAP feature
sonar.security.realm=LDAP
ldap.url=ldap://localhost:10389
ldap.bindDn=cn=sonar,ou=users,o=mycompany
ldap.bindPassword=secret
# USER MAPPING
ldap.user.baseDn=cn=users,dc=example,dc=org
ldap.user.request=(&(objectClass=user)(sAMAccountName={login}))
ldap.user.realNameAttribute=name
ldap.user.emailAttribute=email
# GROUP MAPPING
ldap.group.baseDn=cn=groups,dc=example,dc=org
ldap.group.request=(&(objectClass=group)(member={dn}))
ldap.group.idAttribute=sAMAccountName
上述配置只是Sonar提供的默认配置,一般在实际项目中需要联系LDAP的管理员,申请相关的访问数据的权限,并根据企业用户/用户组的实际配置来调整上述配置项。
完成上述配置之后,用户就可以使用LDAP中的用户名/密码来登录SonarQube,并且在用户每次登录时,通过Group部分的配置来动态设置SonarQube的用户组。SonarQube管理员只需要为每个项目设置用户组,就可以实现项目的权限配置,不再需要为每个用户来分配项目和权限了。
插件升级
插件升级其实就是重新下载已有插件的更新版本,一般是部署在SONARQUBE_HOME/extensions/plugins目录下
- 分支插件 https://github.com/Facthunder/sonar-branch-plugin
- 汉化包: https://github.com/SonarQubeCommunity/sonar-l10n-zh/releases
- C 扫描插件 https://github.com/SonarOpenCommunity/sonar-cxx
- PL/SQL扫描插件 https://github.com/felipebz/zpa
启动服务
由于SonarQube使用ES作为后台,但是ES不能用root用户启动。所以启动SonarQube需要以非root用户 假设我们以sonar用户启动服务。
- 修改目录所有者
chown -R sonar:sonar SONARQUBE_HOME
- 赋可执行权限
对于SONARQUBE_HOME/bin/linux-x86-64目录下文件赋可执行权限
chown x *.sh
坑5- 要注意下对于SONARQUBE_HOME/elasticsearch/bin也要赋权哦,不然服务跑不起来。
启动
代码语言:javascript复制cd SONARQUBE_HOME/bin/linux-x86-64
sudo -name sonar ./sonar.sh start
**坑6- 启动过程中报错 Stopping SonarQube org.elasticsearch.cluster.block.ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]; 。 原来是因为ES需要新建索引缓存,会在SONARQUBE_HOME/data/es6下面占用不少空间。 但是demo用虚拟机磁盘空间不够,导致启动失败。 解决办法: 1)清理出足够空间 2)删除SONARQUBE_HOME/data/es6下面已有内容 3)重新启动
至此,我们完成了SonarQube新版本的安装。接下来,就可以启动升级过程了。
升级 6.7->6.7LTS
升级场景:在原SonarQube所在服务器上升级至LTS版本,且不更换数据库。
备份SonarQube
- 停止现有的SonarQube
$SONAR_HOME/bin/linux-x86-64/sonar.sh stop
- 备份数据库
mysqldump -h localhost -u sonar –password=’password’ sonar| gzip -9 > databasename.gz
当然,如果购买了商业版本的SonarQube,也可以使用官方提供的工具 https://docs.sonarqube.org/display/SONAR/Sonar DB Copy Tool
- 备份现有服务的安装目录
zip -r Sonar_home.zip $SONAR_HOME
- 其余项目 插件和自定义规则需要额外升级
- 插件清单:$SONAR_HOME/extensions/plugins
- 自定义规则:$SONAR_HOME/extensions/rules
- 配置文件:$SONAR_HOME/config 而配置文件中的某些配置项需要在升级过程中使用。 Step 7 – Re-start the production server
- 转储Sonar_home.zip and sonar.gz以备恢复使用
安装SonarQube 6.7.7 LTS并升级
笔者原先使用的是6.7.2,因此需要先升级至最近的 LTS版本,然后再升级到最新的LTS版本。 1)** 确保原SonarQube服务器已停止** 2)安装并配置 SonarQube 6.7.7 LTS至同一服务器NEW_SONARQUBE_HOME目录下 https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-6.7.7.zip 安装过程参考本文前半部分,下同 3)安装插件和自定义规则 4)使用原6.7版本的sonar.properties和 wrapper.conf中的配置 主要包括:web server URL, database, ldap settings 由于新版本可能修改或者新增配置项,所以不建议直接复制黏贴文件,复制这些配置项即可。 在6.7->6.7.7LTS的升级过程中,将使用原MySQL数据库,因此并不涉及数据库的迁移。 5)启动新的SonarQube服务 $SONAR_HOME/bin/linux-x86-64/sonar.sh start 6)升级 访问 http://yourSonarQubeServerURL/setup 并按照提示操作。以下是一个案例 http://blog.majcica.com/2016/11/01/upgrading-sonarqube-to-a-newer-version/ 7)验证升级结果,确保数据没有丢失
升级SonarQube 6.7.7 LTS->7.9.2 LTS
升级场景:升级版本,同时更换数据库
按照前一小段中升级到6.7.7LTS的过程,我们需要重新操作一遍备份和升级的过程。只是按照本文第一部分的介绍,我们会将数据库更换为ORACLE。因此在升级的步骤过程中,需要在安装SonarQube 7.9.2LTS完成后,启动升级前,需要额外增加一个步骤
数据库迁移
- 下载官方数据迁移插件 https://github.com/SonarSource/mysql-migrator
2)执行数据库升级
代码语言:javascript复制mysql-migrator -source sonar.propertie -target new.propertie
-source 是原来6.7.7的配置文件副本,指向一个MySQL数据库。 而 -target 是新安装的7.9.2的配置文件的副本,也就是指向了某个ORACLE schema。 在数据库迁移完成后,再启动升级过程。
**坑7- mysql-migrator所需要的ojdbc需要额外提供,且一定要命名为 mysql-migrator/lib/oracle.jar。如果不成功,可能还是驱动版本不匹配,换一个再试试。
升级SonarQube 7.9.2LTS->8.1
检查了一下各个开源插件的支持情况,发现普遍支持7.9.2和8.0,但是对8.1支持情况不明确。 考虑了一下,还是暂缓吧。