Jenkins Pipeline结合Sonarqube对Java代码进行审查

1.k8s部署Sonarqube

1.1部署pgsql作为Sonarqube的数据库

pgsql-sts.yaml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: sonarqube
spec:
  selector:
    matchLabels:
      app: postgres
  serviceName: "postgres-service"
  template:
    metadata:
      labels:
        app: postgres
    spec:
      terminationGracePeriodSeconds: 10
      #nodeSelector:
      #  public: ops
      containers:
      - name: postgres
        image: postgres
        imagePullPolicy: IfNotPresent
        env:
        # put the data into a sub directory to avoid the permission issue in k8s with restricted psp enabled
        # more detail refer to https://github.com/goharbor/harbor-helm/issues/756
        - name: PGDATA
          value: /var/lib/postgresql/data/pgdata
        - name: ALLOW_IP_RANGE
          value: "0.0.0.0/0"
        - name: POSTGRES_DB
          value: "sonarDB"
        - name: POSTGRES_USER
          value: "sonarUser"
        - name: POSTGRES_PASSWORD
          value: "123456"
        ports:
        - name: pgport
          protocol: TCP
          containerPort: 5432
        resources:
          limits:
            cpu: 1000m
            memory: 2Gi
          requests:
            cpu: 500m
            memory: 1Gi
        volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: database-data
        - mountPath: /dev/shm
          name: shm-volume
      initContainers:
      - name: data-migrator
        image: postgres    #goharbor/harbor-db:v2.7.0
        imagePullPolicy: IfNotPresent
        command:
        - /bin/sh
        args:
        - -c
        - '[ -e /var/lib/postgresql/data/postgresql.conf ] && [ ! -d /var/lib/postgresql/data/pgdata
          ] && mkdir -m 0700 /var/lib/postgresql/data/pgdata && mv /var/lib/postgresql/data/*
          /var/lib/postgresql/data/pgdata/ || true'
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: database-data

      - name: data-permissions-ensurer
        image: postgres
        command:
        - /bin/sh
        args:
        - -c
        - chmod -R 700 /var/lib/postgresql/data/pgdata || true
        imagePullPolicy: IfNotPresent
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: database-data
      securityContext:
        runAsUser: 999
        fsGroup: 999
      volumes:
      - emptyDir:
          medium: Memory
          sizeLimit: 512Mi
        name: shm-volume
  volumeClaimTemplates:
  - metadata:
      name: database-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "manage-167nfs"
      resources:
        requests:
          storage: 20Gi
pgsql-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres-service
  namespace: sonarqube
  labels:
    app: postgres
spec:
  selector:
    app: postgres
  ports:
  - name: pgport
    port: 5432
  clusterIP: None

1.2创建pvc作为sonarqube的持久化存储

sonarqube-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sonarqube-data
  namespace: sonarqube
spec:
  accessModes:
    - ReadWriteMany
  # 修改为自己的sc
  storageClassName: "managed-nfs-storage"
  resources:
    requests:
      storage: 20Gi
sonarqube.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sonarqube
  namespace: sonarqube
  labels:
    app: sonarqube
spec:
  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: sonarqube:lts
        ports:
        - containerPort: 9000
        env:
        - name: SONARQUBE_JDBC_USERNAME
          value: "sonarUser"
        - name: SONARQUBE_JDBC_PASSWORD
          value: "123456"
        - name: SONARQUBE_JDBC_URL
          value: "jdbc:postgresql://postgres-service:5432/sonarDB"
        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: 2000m
            memory: 4096Mi
          requests:
            cpu: 1000m
            memory: 1024Mi
        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: sonarqube-data
sonarqube-svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: sonarqube
  name: sonarqube
  namespace: sonarqube
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    - name: sonarqube
      port: 9000
      protocol: TCP
      targetPort: 9000
  selector:
    app: sonarqube
  sessionAffinity: None
  type: ClusterIP
sonarqube-ingress.ymal
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    # 启用了TLS,则控制器会将 (308) 重定向到 HTTPS
    nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
    nginx.ingress.kubernetes.io/service-weight: ''
  name: sonarqube-ingress
  namespace: sonarqube
spec:
  ingressClassName: nginx
  rules:
  - host: sonarqube.XXX.com
    http:
      paths:
      - backend:
          service:
            name: sonarqube
            port:
              number: 9000
        path: /
        pathType: ImplementationSpecific

全部执行

通过ingress配置的域名访问默认账号密码admin/admin
登录后因为是全英文的,需要安装中文插件

1.3SonaQube关闭审查结果上传到SCM功能

2.将Sonarqube加入到Jenkins Pipeline中

Jenkins需要添加sonarqube的客户端命令和服务的的信息,所以要先安装sonarqube插件
1. Sonar Quality Gates Plugin
2.SonarQube Scanner for Jenkins

2.1添加sonarqube的客户端命令工具

这里我是用的是sonar-scanner-cli-4.7.0.2747-linux.zip,把文件存放在公司内网的nginx中,构建时下载解压然后使用该命令

wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.7.0.2747-linux.zip

2.2添加sonarqube服务端信息

Name:自定义
URL:可以用k8s的SVC或是域名可以访问到的信息,如果用svc则不能通过jenkins的扫描结果直接跳转到sonarqube
Token:这个时非常重要的,要去sonarqube中生成

2.3Sonarqube生成token

配置 》 配置 》 webhook,信息填写完成后会生成token

jenkins上添加对应的凭据

配置完成后添加到pipeline中

2.4Pipeline添加Sonarqube扫描

stage('SonarQube代码审查') { 
            when {
                expression {
                    return (CHKDEPL == 'deploy')
                }
            }
            steps{ 
                script { 
                    env.scannerHome = tool 'sonarqube-scanner' 
                }
                withSonarQubeEnv('sonarqube') { 
                    sh '''
                    echo ${scannerHome}
                    ls -l ${scannerHome}/sonar-scanner-4.7.0.2747-linux/bin
                    pwd
                    ls -l
                    ${scannerHome}/sonar-scanner-4.7.0.2747-linux/bin/sonar-scanner -Dsonar.projectKey=${PROJECT_NAME} -Dsonar.projectName=${PROJECT_NAME} -Dsonar.projectVersion=${BUILD_NUMBER} -Dsonar.sources=. -Dsonar.java.binaries=. -Dsonar.language=java -Dsonar.sourceEncoding=UTF-8     
                    #需要配置默认的java项,否则运行会报错:
                    #org.sonar.java.AnalysisException: Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property
                    #sonar.java.binaries=.
                    '''
                }
            } 
        }
}

网上很多同学直接使用sonarqube配置文件配置sonarqube的服务端信息,配置文件是sonar-project.properties如下:

# 项目名,如果项目名不存在会自动创建该项目
sonar.projectKey=my_project
# 源码路径,设置为当前目录
sonar.sources=.
# SonarQube 访问地址,根据实际情况填写
sonar.host.url=http://JenkinsIP:9000
# token,在 SonarQube 中创建的 token,只有 SonarQube 开起了强制用户认证,才需要 token,默认情况下,强制用户认证是关闭的。
sonar.login=c4765957e5ada82ebe21a7c2e1f56afbff4059d3
# 语言类型
sonar.language=java
# 二进制文件目录,就是 .class 文件的目录,只有部分项目需要该配置
sonar.java.binaries=collector/target/classes,jmx_prometheus_httpserver/target/classes,jmx_prometheus_javaagent/target/classes
# 源代码编码格式
sonar.sourceEncoding=UTF-8
这里我们不采用这种方式,因为客户端是在k8s的pod中的,每构建一次下载一次,构建完摧毁pod

Pipeline中扫描Java代码使用的命令

 ${scannerHome}/sonar-scanner-4.7.0.2747-linux/bin/sonar-scanner \
# 配置该Java项目的项目Key
-Dsonar.projectKey=${PROJECT_NAME} \
# 配置该Java项目的项目名称
-Dsonar.projectName=${PROJECT_NAME} \
# 配置该Java项目的版本信息,自定义
-Dsonar.projectVersion=${BUILD_NUMBER} \
# 扫描所在代码目录
-Dsonar.sources=. \
# 这里要配置,否则运行会报错:
     #org.sonar.java.AnalysisException: Your project contains .java files, please provide compiled classes with sonar.java.binaries property, or exclude them from the analysis with sonar.exclusions property
-Dsonar.java.binaries=. \
# java html
-Dsonar.language=java \
-Dsonar.sourceEncoding=UTF-8

扫描后可以看到相关信息

添加对Vue项目的扫描

stage('SonarQube代码审查') { 
            steps{ 
                script { 
                    env.scannerHome = tool 'sonarqube-scanner' 
                    env.ndjs = tool "nodejs16142" 
                }
                withSonarQubeEnv('sonarqube') { 
                    sh '''
                    echo ${scannerHome}
                    echo ${ndjs}
                    PATH=${PATH}:${ndjs}/bin
                    ls -l ${scannerHome}/sonar-scanner-4.7.0.2747-linux/bin
                    pwd
                    ls -l
                    ${scannerHome}/sonar-scanner-4.7.0.2747-linux/bin/sonar-scanner -Dsonar.projectKey=${PROJECT_NAME} -Dsonar.projectName=${PROJECT_NAME} -Dsonar.projectVersion=${BUILD_NUMBER} -Dsonar.sources=. -Dsonar.java.binaries=.  -Dsonar.sourceEncoding=UTF-8     
                    '''
                }
            } 
 }

${scannerHome}/sonar-scanner-4.7.0.2747-linux/bin/sonar-scanner \
-Dsonar.projectKey=${PROJECT_NAME} \
-Dsonar.projectName=${PROJECT_NAME} \
-Dsonar.projectVersion=${BUILD_NUMBER} \
-Dsonar.sources=. \
-Dsonar.java.binaries=.  \
-Dsonar.sourceEncoding=UTF-8  
注意:这里扫描会检查node版本所以要先安装nodejs
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值