Kubernetes + Docker搭建Sonarqube

1. Sonar概述

Sonar是一个用于代码质量管理的开放平台。通过插件机制,Sonar可以集成不同的测试工具,代码分析工具,以及持续集成工具。
与持续集成工具(例如Hudson/Jenkins等)不同,Sonar并不是简单地把不同的代码检查工具结果(例如FindBugs,PMD等)直接显示在Web页面上,而是通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。
在对其他工具的支持方面,Sonar不仅提供了对IDE的支持,可以在Eclipse和IntelliJ IDEA这些工具里联机查看结果;同时Sonar 还对大量的持续集成工具提供了接口支持,可以很方便地在持续集成中使用Sonar。
此外,Sonar的插件对Java/PHP/C/C++/Python等编程语言提供支持,对国际化以及报告文档化也有良好的支持。
官网:Sonarqube


2. Snoar结构与集成

结构图:

与其他ALM工具集成:


3. Sonar的Kubernetes部署

3.1 事前准备

集群构成:

建议先将sonarqube镜像pull下来。不准备的话kubernetes创建RC的时候也会自动pull。

1
docker pull sonarqube

3.2 创建namespace

定义namespace.yaml:

namespace.yaml
1
2
3
4
apiVersion: v1
kind: Namespace
metadata:
name: sonar

创建sonar命名空间:
1
kubectl create -f namespace.yaml

3.3 启动mysql

首先要启动db,这里使用mysql。
注意:sonarqube6.2镜像要求mysql版本是5.6以上,所以mariadb不可以。另外max_allowed_packet需要设置的大一些,mysql镜像默认是4M。

rc-mysql56.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: v1
kind: ReplicationController
metadata:
name: rc-mysql56
namespace: sonar
labels:
name: mysql
context: ctpaas_staging_site
spec:
replicas: 1
template:
metadata:
labels:
name: mysql
spec:
containers:
- name: mysql
image: docker.io/mysql
args: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_unicode_ci", "--max_allowed_packet=32M"]
env:
- name: TZ
value: 'Asia/Shanghai'
- name: LANG
value: 'C.UTF-8'
- name: MYSQL_ROOT_PASSWORD
value: 'password'
- name: MYSQL_DATABASE
value: 'sonar'
ports:
- containerPort: 3306
volumeMounts:
- mountPath: "/var/lib/mysql"
name: mysql-data-dir
volumes:
- name: mysql-data-dir
nfs:
server: 192.168.205.77
path: "/nfs_share/mysql56/mysql_data"
svc-mysql56.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Service
metadata:
name: svc-mysql56
namespace: sonar
spec:
ports:
- port: 3306 # the port that this service should serve on
# the container on each pod to connect to, can be a name
# (e.g. 'www') or a number (e.g. 80)
targetPort: 3306
protocol: TCP
nodePort: 0
# just like the selector in the replication controller,
# but this time it identifies the set of pods to load balance
# traffic to.
selector:
name: mysql
type:
NodePort

创建mysql rc和service:

1
2
kubectl create -f rc-mysql56.yaml
kubectl create -f svc-mysql56.yaml

3.3 创建Sonar RC/Service

定义rc-sonar.yaml,db使用mysql的cluster ip:

rc-sonar.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
apiVersion: v1
kind: ReplicationController
metadata:
name: rc-sonar
namespace: sonar
labels:
name: sonar
spec:
replicas: 1
selector:
name: sonar
template:
metadata:
labels:
name: sonar
spec:
containers:
- name: sonar
image: docker.io/sonarqube
env:
- name: SONARQUBE_JDBC_USERNAME
value: user
- name: SONARQUBE_JDBC_PASSWORD
value: password
- name: SONARQUBE_JDBC_URL
value: 'jdbc:mysql://10.254.130.11:3306/sonar?useUnicode=true&characterEncoding=utf8'
ports:
- containerPort: 9000
volumeMounts:
- mountPath: "/opt/sonarqube/conf"
name: sonar-conf
- mountPath: "/opt/sonarqube/data"
name: sonar-data
- mountPath: "/opt/sonarqube/extensions"
name: sonar-extensions
- mountPath: "/opt/sonarqube/logs"
name: sonar-logs
volumes:
- name: sonar-conf
nfs:
server: 192.168.205.77
path: "/nfs_share/sonar/conf"
- name: sonar-data
nfs:
server: 192.168.205.77
path: "/nfs_share/sonar/data"
- name: sonar-extensions
nfs:
server: 192.168.205.77
path: "/nfs_share/sonar/extensions"
- name: sonar-logs
nfs:
server: 192.168.205.77
path: "/nfs_share/sonar/logs"

创建volumes,将数据、配置、插件、日志都放在volumes上,这样容器重新创建也不会受影响。

定义svc-sonar.yaml:

svc-sonar.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: svc-sonar
namespace: sonar
spec:
type: NodePort
ports:
- port: 9000
protocol: TCP
nodePort: 0
selector:
name: sonar

创建sonar rc和service:

1
2
kubectl create -f rc-sonar.yaml
kubectl create -f svc-sonar.yaml

确认pod/rc/svc:

获取sonar service的NodePort:

确认是否可以正常打开:


4. 使用Sonar进行代码分析

4.1 安装Sonarqube Scanner

参照Analyzing with SonarQube Scanner:

  • 下载Scanner并解压
  • 修改install_directory/conf/sonar-scanner.properties中的sonar.host.url为搭建的sonar服务器地址,端口为NodePort
  • 将install_directory/bin加入path中
  • 运行sonar-scanner -h

4.2 创建sonar-project.properties

在项目根目录下添加sonar-project.properties配置文件,模板如下:

sonar-project.properties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#required metadata
#projectKey项目的唯一标识,不能重复。
sonar.projectKey=pj_key
#projectName值不能是中文,否则web页面部分是乱码
sonar.projectName=pj_name
sonar.projectVersion=1.0
sonar.sourceEncoding=UTF-8
sonar.modules=java-module,javascript-module,html-module
# Java module
java-module.sonar.projectName=pj_name_java
java-module.sonar.language=java
# .表示projectBaseDir指定的目录
java-module.sonar.sources=JavaSource
java-module.sonar.projectBaseDir=.
#sonar.binaries=classes
# JavaScript module
javascript-module.sonar.projectName=pj_name_js
javascript-module.sonar.language=js
javascript-module.sonar.sources=WebContent
javascript-module.sonar.projectBaseDir=.
# Html module
html-module.sonar.projectName=pj_name_html
html-module.sonar.language=web
html-module.sonar.sources=WebContent
html-module.sonar.projectBaseDir=.

4.3 分析并确认结果

在代码根目录运行sonar-scanner,结束后到sonar上确认结果:


5. Jenkins集成Sonarqube

参照Analyzing with SonarQube Scanner for Jenkins,在Jenkins上安装Sonarqube插件后进行配置。具体后面再开一篇说明。


6. Sonar常用插件

目前安装的插件如下:



参照资料:
Kubernetes单Pod启动sonarqube
From Pet to Cattle – Running Sonar on Kubernetes
sonar-examples
SonarQube Documentation