在k8s上面sonarqube搭建过程
首先需要搭建postgres数据库
编写yaml编排文件
[root@node1 postgres]# vim postgres.yaml
内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-sonar
namespace: devops
labels:
app: postgres-sonar
spec:
replicas: 1
selector:
matchLabels:
app: postgres-sonar
template:
metadata:
labels:
app: postgres-sonar
spec:
containers:
- name: postgres-sonar
image: 10.110.152.173/utils/postgress:12.4
imagePullPolicy: Always
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
value: sonar
- name: POSTGRES_USER
value: sonar
- name: POSTGRES_PASSWORD
value: sonar
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 500m
memory: 1024Mi
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumes:
- name: data
persistentVolumeClaim:
claimName: postgres-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
namespace: devops
spec:
accessModes:
- ReadWriteMany
storageClassName: devops-cephfs
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: postgres-sonar
namespace: devops
labels:
app: postgres-sonar
spec:
type: NodePort
ports:
- port: 5432
targetPort: 5432
nodePort: 32333
selector:
app: postgres-sonar
运行上述的postgres的yaml编排文件
kubectl apply -f postgres.yaml
使用DBeaver查看数据库如下:
注:使用NodePort暴露postgres数据库的
安装sonarqube
生成编排文件
[root@node1 sonarqube]# vim sonar.yaml
编排文件内容如下:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sonarqube
namespace: devops
labels:
app: sonarqube
spec:
serviceName: sonar
replicas: 1
selector:
matchLabels:
app: sonarqube
template:
metadata:
labels:
app: sonarqube
spec:
initContainers:
- name: init-sysctl
image: busybox
imagePullPolicy: IfNotPresent
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext:
privileged: true
containers:
- name: sonarqube
image: 10.110.152.173/utils/sonarqube:8.4.2-community
ports:
- containerPort: 9000
env:
- name: SONARQUBE_JDBC_USERNAME
value: sonar
- name: SONARQUBE_JDBC_PASSWORD
value: sonar
- name: SONARQUBE_JDBC_URL
value: jdbc:postgresql://postgres-sonar:5432/sonar
volumeMounts:
- mountPath: /opt/sonarqube/conf
name: data
subPath: conf
- mountPath: /opt/sonarqube/data
name: data
subPath: data
# - mountPath: /opt/sonarqube/extensions #注意,此处不要挂卷,否则会覆盖镜像原有的插件的
# name: data
# subPath: extensions
volumes:
- name: data
persistentVolumeClaim:
claimName: sonar-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sonar-data
namespace: devops
spec:
accessModes:
- ReadWriteMany
storageClassName: devops-cephfs
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
name: sonarqube
namespace: devops
labels:
app: sonarqube
spec:
ports:
- name: sonarqube
port: 9000
targetPort: 9000
protocol: TCP
selector:
app: sonarqube
执行编排文件
[root@node1 sonarqube]# kubectl apply -f sonar.yaml
statefulset.apps/sonarqube unchanged
persistentvolumeclaim/sonar-data unchanged
service/sonarqube unchanged
执行ingress暴露sonarqube服务
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sonar-ingress
namespace: devops
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-body-size: "100m" #设置请求体大小,否则如果项目太大会报错的哦!
spec:
rules:
- host: sonar.ailab.lenovo.com
http:
paths:
- path: /
backend:
serviceName: sonarqube
servicePort: 9000
使用浏览器访问sonarqube
jenkins集成sonarqube
在jenkins上面安装sonar工具
安装jenkins及其相关工具参见前面文章:https://blog.csdn.net/cyxinda/article/details/107254673
在jenkins上面配置sonarqube环境
扫描java的maven项目
编写的pipeline如下:
pipeline{
agent any
tools {
maven 'maven3.6.3'
jdk 'jdk8'
}
stages {
stage ('Initialize') {
steps {
sh("PATH=${PATH}:/usr/local/maven/3.6.3/bin")
}
}
stage('=============================================代码检出已经打包docker镜像=============================================') {
steps{
script{
uuidUrl="git@gitlab.lenovo.com:saas/bot_anywhere.git";
credentialsId="caoyong1";
}
dir("uid"){
echo "清理当前目录中的代码"
sh("rm -rf *")
echo "=============================================开始uuid部分检出代码============================================="
checkout([$class: 'GitSCM', branches: [[name: 'v3.3.3.3_test']], userRemoteConfigs: [[credentialsId: "$credentialsId", url: "$uuidUrl"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: []])
script{
// 此处是读取pom文件中的version,用来指定镜像的版本号$vName
pom = readMavenPom file: 'pom.xml'
vName=pom.version
sonarqubeScannerHome = tool name: 'sonar4.4.0', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
}
withSonarQubeEnv('sonarqube') {
echo "buildNum:::::::::::::${env.BUILD_NUMBER}"
sh("mvn clean package sonar:sonar -Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} -Dsonar.analysis.tag=v3.3.3.3_test ");
}
// script{ //此处用于等待sonarqube的webhook回调,但是凭证没有验证成功,所以,使用的是sonarqube回调应用接口,一方面是暂时没有调试成功,另一方面就是不应该在jenkins上面进行阻塞,防止不可控的情况发生
// result = waitForQualityGate webhookSecretId: 'sonar' ,abortPipeline: true
// echo "$result"
// }
}
}
}
}
}
查看结果
运行该pipeline后,在sonarqube上面可见
扫描python项目
编写jenkins pipeline如下:
pipeline{
agent any
tools {
maven 'maven3.6.3'
jdk 'jdk8'
}
stages {
stage ('Initialize') {
steps {
sh("PATH=${PATH}:/usr/local/maven/3.6.3/bin")
}
}
stage('=============================================代码检出已经打包docker镜像=============================================') {
steps{
script{
uuidUrl="git@gitlab.lenovo.com:yucc1/leintent.git";
credentialsId="caoyong1";
}
dir("uid"){
echo "清理当前目录中的代码"
sh("rm -rf *")
echo "=============================================开始uuid部分检出代码============================================="
checkout([$class: 'GitSCM', branches: [[name: 'v3.3.3.3_test']], userRemoteConfigs: [[credentialsId: "$credentialsId", url: "$uuidUrl"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: []])
script{
sonarqubeScannerHome = tool name: 'sonar4.4.0', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
}
withSonarQubeEnv('sonarqube') {
echo "buildNum:::::::::::::${env.BUILD_NUMBER}"
sh "${sonarqubeScannerHome}/bin/sonar-scanner -e \
-Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} \
-Dsonar.analysis.tag=v3.3.3.3_test \
-Dsonar.projectKey=key-leintent \
-Dsonar.projectName=leintent \
-Dsonar.projectVersion=v3.3.3.3_testV \
-Dsonar.sources=./ \
-Dsonar.language=py \
-Dsonar.sourceEncoding=UTF-8 \
-Dsonar.python.pylint.reportPath=pylint-report.txt \
-Dsonar.python.coverage.reportPath=*coverage-*.xml \
-Dsonar.python.xunit.reportPath=nosetests.xml \
-Dsonar.python.xunit.skipDetails=true"
}
// script{ //此处用于等待sonarqube的webhook回调,但是凭证没有验证成功,所以,使用的是sonarqube回调应用接口,一方面是暂时没有调试成功,另一方面就是不应该在jenkins上面进行阻塞,防止不可控的情况发生
// result = waitForQualityGate webhookSecretId: 'sonar' ,abortPipeline: true
// echo "$result"
// }
}
}
}
}
}
查看结果
运行该pipeline后,在sonarqube上面可见
扫描vue.js项目
编写jenkins pipeline如下:
pipeline{
agent any
tools {
maven 'maven3.6.3'
jdk 'jdk8'
nodejs "node12"
}
stages {
stage ('Initialize') {
steps {
sh("PATH=${PATH}:/usr/local/maven/3.6.3/bin")
}
}
stage('=============================================代码检出已经打包docker镜像=============================================') {
steps{
script{
uuidUrl="git@gitlab.lenovo.com:chatbot-h5/chatbot-h5.git";
credentialsId="caoyong1";
}
dir("uid"){
echo "清理当前目录中的代码"
sh("rm -rf *")
echo "=============================================开始uuid部分检出代码============================================="
checkout([$class: 'GitSCM', branches: [[name: 'v8.8.8.8_test']], userRemoteConfigs: [[credentialsId: "$credentialsId", url: "$uuidUrl"]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: []])
script{
sonarqubeScannerHome = tool name: 'sonar4.4.0', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
}
withSonarQubeEnv('sonarqube') {
echo "buildNum:::::::::::::${env.BUILD_NUMBER}"
sh "${sonarqubeScannerHome}/bin/sonar-scanner -e \
-Dsonar.analysis.buildNumber=${env.BUILD_NUMBER} \
-Dsonar.analysis.tag=v8.8.8.8_test \
-Dsonar.projectKey=key-chatbot-h5 \
-Dsonar.projectName=chatbot-h5 \
-Dsonar.projectVersion=v8.8.8.8_testV \
-Dsonar.sources=./ \
-Dsonar.language=js \
-Dsonar.profile=node \
-Dsonar.sourceEncoding=UTF-8"
}
// script{ //此处用于等待sonarqube的webhook回调,但是凭证没有验证成功,所以,使用的是sonarqube回调应用接口,一方面是暂时没有调试成功,另一方面就是不应该在jenkins上面进行阻塞,防止不可控的情况发生
// result = waitForQualityGate webhookSecretId: 'sonar' ,abortPipeline: true
// echo "$result"
// }
}
}
}
}
}
查看结果
运行该pipeline后,在sonarqube上面可见
sonar入口
也可以在jenkins的job页面上面,直接进入sonar入口查看
关于sonarqube回调
回调接口报文结构如下:
{
"serverUrl": "http://sonar.ailab.lenovo.com",
"taskId": "AXS6Y9GT42ipPrCBokIw",
"status": "SUCCESS",
"analysedAt": "2020-09-23T09:55:29+0000",
"revision": "49ed5fa81a300b8a350c49e5f5e68fe39132f85a",
"changedAt": "2020-09-23T09:55:29+0000",
"project": {
"key": "key-chatbot-h5",
"name": "chatbot-h5",
"url": "http://sonar.ailab.lenovo.com/dashboard?id=key-chatbot-h5"
},
"branch": {
"name": "master",
"type": "BRANCH",
"isMain": true,
"url": "http://sonar.ailab.lenovo.com/dashboard?id=key-chatbot-h5"
},
"qualityGate": {
"name": "Sonar way",
"status": "OK",
"conditions": [{
"metric": "new_reliability_rating",
"operator": "GREATER_THAN",
"status": "NO_VALUE",
"errorThreshold": "1"
}, {
"metric": "new_security_rating",
"operator": "GREATER_THAN",
"status": "NO_VALUE",
"errorThreshold": "1"
}, {
"metric": "new_maintainability_rating",
"operator": "GREATER_THAN",
"status": "NO_VALUE",
"errorThreshold": "1"
}, {
"metric": "new_coverage",
"operator": "LESS_THAN",
"status": "NO_VALUE",
"errorThreshold": "80"
}, {
"metric": "new_duplicated_lines_density",
"operator": "GREATER_THAN",
"status": "NO_VALUE",
"errorThreshold": "3"
}, {
"metric": "new_security_hotspots_reviewed",
"operator": "LESS_THAN",
"status": "NO_VALUE",
"errorThreshold": "100"
}]
},
"properties": {
"sonar.analysis.buildNumber": "1",
"sonar.analysis.tag": "v8.8.8.8_test"
}
}
其中包含的sonar检测报告入口url、工程的名称等。
sonar配置:
- 可以在sonarqube -> 配置 -> 应用市场下载各种插件,默认的sonar已经安装了常用的插件,基本不用手动安装;不过我安装了汉化的插件【】。
- 可以在sonarqube -> 配置 -> 权限 -> 用户 设置 用户的token,前面的jenkins连接sonar的secret便是在这里设置的;
- 可以在sonarqube -> 配置 -> 配置 -> 网络调用 设置回调接口webhook,设置的秘钥,是用于与应用验证回调合法性的;参见:https://docs.sonarqube.org/latest/project-administration/webhooks/
- 可以在sonarqube -> 配置 -> 配置 -> 通用 配置sonarqube的server地址:
参考文档:略