K8S搭建SonarQube并集成到Jenkins
前提:已经搭建好k8s环境
搭建postgres数据库
存储类是使用nfs,下面是yaml内容
apiVersion: v1
kind: PersistentVolume
metadata:
name: postgres-pv
namespace: devops
labels:
app: postgres
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 10Gi
mountOptions: #NFS挂在选项
- hard
- nfsvers=4.1 #NFS Server版本
nfs: #NFS设置
server: 192.168.111.152
path: /nfs/postgres
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: postgres-pvc
namespace: devops
labels:
app: postgres
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi #设置大小为5G
selector:
matchLabels:
app: postgres
---
apiVersion: v1
kind: Service
metadata:
name: postgres-svc
namespace: devops
labels:
app: postgres
spec:
type: NodePort
ports:
- name: server
port: 5432
targetPort: 5432
# nodePort: 30543 #指定 Nodeport 端口
protocol: TCP
selector:
app: postgres
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: devops
labels:
app: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: reg-hub.gzeport.com/gzeport/postgres:11.4
imagePullPolicy: "IfNotPresent"
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB #PostgreSQL 数据库名称
value: "sonarDB"
- name: POSTGRES_USER #PostgreSQL 用户名
value: "sonarUser"
- name: POSTGRES_PASSWORD #PostgreSQL 密码
value: "sonarPasswd123!@#"
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 500m
memory: 1024Mi
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgredb
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: postgres-pvc
安装sonarqube服务
存储类是使用nfs,下面是yaml内容
apiVersion: v1
kind: PersistentVolume
metadata:
name: sonarqube-pv
namespace: devops
labels:
app: sonarqube
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 10Gi
mountOptions: #NFS挂在选项
- hard
- nfsvers=4.1 #NFS Server版本
nfs: #NFS设置
server: 192.168.111.152
path: /nfs/sonarqube
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: sonarqube-pvc
namespace: devops
labels:
app: sonarqube
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi #设置大小为5G
selector:
matchLabels:
app: sonarqube
---
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sonarqube
namespace: devops
labels:
app: sonarqube
spec:
replicas: 1
selector:
matchLabels:
app: sonarqube
template:
metadata:
labels:
app: sonarqube
spec:
initContainers: #设置初始化镜像,执行 system 命令
- name: init-sysctl
image: reg-hub.gzeport.com/gzeport/busybox:1.36.0-glibc
imagePullPolicy: IfNotPresent
command: ["sysctl", "-w", "vm.max_map_count=262144"] #必须设置vm.max_map_count这个值调整内存权限,否则启动可能报错
securityContext:
privileged: true #赋予权限能执行系统命令
containers:
- name: sonarqube
image: reg-hub.gzeport.com/gzeport/sonarqube:8.9.10-community
ports:
- containerPort: 9000
env:
- name: SONARQUBE_JDBC_USERNAME
value: "sonarUser" #引用 PostgreSQL 配置中设置的用户名
- name: SONARQUBE_JDBC_PASSWORD
value: "sonarPasswd123!@#" #引用 PostgreSQL 配置中设置的密码
- name: SONARQUBE_JDBC_URL
value: "jdbc:postgresql://postgres-svc:5432/sonarDB" #指定 PostgreSQL 在 Kubernetes 中的地址
# livenessProbe:
# httpGet:
# path: /sessions/new
# port: 9000
# initialDelaySeconds: 60
# periodSeconds: 30
# readinessProbe:
# httpGet:
# path: /sessions/new
# port: 9000
# initialDelaySeconds: 60
# periodSeconds: 30
# failureThreshold: 6
resources:
limits:
cpu: 1000m
memory: 2048Mi
requests:
cpu: 500m
memory: 1024Mi
volumeMounts:
- mountPath: /opt/sonarqube/conf
name: sonarqube
subPath: conf
- mountPath: /opt/sonarqube/data
name: sonarqube
subPath: data
- mountPath: /opt/sonarqube/extensions
name: sonarqube
subPath: extensions
volumes:
- name: sonarqube
persistentVolumeClaim:
claimName: sonarqube-pvc #绑定上面创建的 PVC
nodeSelector:
kubernetes.io/hostname: k8s-node01
---
apiVersion: v1
kind: Service
metadata:
name: sonarqube-svc
namespace: devops
labels:
app: sonarqube
spec:
type: NodePort
ports:
- name: sonarqube
port: 9000
targetPort: 9000
protocol: TCP
selector:
app: sonarqube
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sonarqube-gzeport-com
namespace: devops
labels:
app: sonarqube-gzeport-com
spec:
rules:
- host: sonarqube.gzeport.com
http:
paths:
- backend:
service:
name: sonarqube-svc
port:
number: 9000
pathType: Prefix
path: /
运行成功后,设置hosts 浏览器输入http://sonarqube.gzeport.com,
开始初始化数据库,这个时间过程比较长,大概几分钟。初始化成功后进入登录界面,
账号:admin 密码:admin
SonarQube汉化
进入SonarQube主页后,发现全部是英文,英文不好或使用不太习惯的,可以将语言设置为中文。
- 主页,依次点击Administration-->Marketplace
-
滑动页面,在Plugins处,搜索
Chinese Pack
插件,然后点击右侧的install -
安装完成后,点击
Restart Server
- 重启成功后,再次访问,登录进入主页面,汉化成功了
Jenkins集成SonarQube进行代码质量扫描
安装插件
管理Jenkins->插件管理,安装SonarQube Scanner
插件
生成SonarQube Token
SonarQube菜单右上角头像- > My Account(我的账号) -> Security(安全) 或者访问 http://sonarqube.gzeport.com/account/security/
生成之后记得复制并保存Token,不然页面刷新或者关闭后就无法查询到Token了 1c409ca4a8d73f2b45ce504c99992f6212b36246
添加Jenkins凭据
菜单:凭据 —> 系统 -> 全局凭据 -> 添加凭据
类型选择:Secret text
,然后Secret中填入之前生成的Token
配置SonarQube Server
菜单:管理Jenkins -> 系统设置
找到SonarQube servers
配置项增加SonarQube Server
配置项说明:
配置项 | 说明 |
---|---|
Name | Sonar服务名,按照自己习惯来即可 |
Server URL | SonarQube Server的主页地址,我这边使用了K8S的无头服务地址sonarqube-svc.devops.svc.cluster.local:9000 (这就是k8s的好处拉) |
Sonar authentication token | Sonar Token,选择已添加的凭据即可 |
配置sonar-scanner-cli镜像
因为使用的jenkins master-slave模式,所以需要配置slave镜像
编写Jenkins-流水线请求Sonar
#!/usr/bin/env groovy
//公共
// 项目信息
def PROJECT_NAME = "apps"
def APP_NAME = "gzeport-gitlab-demo"
//GIT源码拉取地址
def GIT_URL = "http://gitlab-svc.devops.svc.cluster.local/guoliangjun/gzeport-gitlab-demo.git"
//认证
def Git_AUTH = "fa1f8c79-b111-4220-8d6c-776a66437614"
def LANGUAGE = "java"
def PROJECT_DIR = "src"
def BUILD_ID = "1.0-SNAPSHOT"
pipeline {
agent {label 'jenkins-slave'}
options {
//设置运行的超时时间,超过超时时间,job会自动被终止
timeout(time: 60, unit: 'MINUTES')
//禁止同时构建
disableConcurrentBuilds()
}
//参数列表
parameters{
gitParameter branch: '', branchFilter: '.*', defaultValue: 'origin/master', description: '选择发布的分支', listSize: '10', name: 'Branch', quickFilterEnabled: false, selectedValue: 'NONE', sortMode: 'ASCENDING', tagFilter: '*', type: 'PT_BRANCH'
choice choices: ['false', 'true'] , description: '是否进行代码扫描', name: 'SonarQube_Bool'
}
stages {
stage('拉取代码'){
steps {
checkout([$class: 'GitSCM',
branches: [[name: "${params.Branch}"]],
doGenerateSubmoduleConfigurations: false,
extensions: [], submoduleCfg: [],
userRemoteConfigs: [[credentialsId: "${Git_AUTH}", url: "${GIT_URL}"]]])
sh 'ls -l'
}
}
stage('代码检查'){
when {
expression { SonarQube_Bool == 'true' }
}
steps{
echo '执行sonarQube'
container("sonar-scanner") {
withCredentials([string(credentialsId: '150cc81a-4229-4b89-8c19-41e4c6feaba7', variable: 'SONAR_TOKEN')]) {
sh "sonar-scanner -Dsonar.login=${SONAR_TOKEN} " +
"-Dsonar.projectKey=${APP_NAME} " +
"-Dsonar.projectName=${APP_NAME} " +
"-Dsonar.sourceEncoding=UTF-8 "+
"-Dsonar.language=${LANGUAGE} "+
"-Dsonar.projectVersion=${BUILD_ID} "+
"-Dsonar.sources=${PROJECT_DIR} "+
"-Dsonar.java.binaries=. "
}
}
}
}
}
}
执行成功后,进行Sonarqube查看效果
参考
https://cloud.tencent.com/developer/article/1578435
https://www.cnblogs.com/zoujiaojiao/p/16910697.html