乐趣区

关于运维:kubernetes-基于jenkins-spinnaker的cicd实践二sonarqube安装与简单使用

背景:

程序有点乱了在 ci/cd 过程中应该是先进行代码的动态扫描再去进行扫描镜像的呢,就佛系的写了。反正步骤都是独立的。这里写一下 sonarqube 的装置与集成,预计实际的我还要好好钻研一下!

helm 装置 sonarqube

参照官网文档:
https://docs.sonarqube.org/8.9/setup/sonarqube-on-kubernetes/

helm 减少 repo 仓库

[root@k8s-master-01 helm]# helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube
[root@k8s-master-01 helm]# helm repo update

helm fetch 包到本地

[root@k8s-master-01 helm]# helm search repo sonarqube
[root@k8s-master-01 helm]# helm fetch sonarqube/sonarqube-lts


没有方法,墙裂 … 手动下载 ing,rz 上次到服务器

解压缩 tgz 包并批改 value.yaml 文件

[root@k8s-master-01 helm]# tar zxvf sonarqube-lts-1.0.20+140.tgz



value.yam 就批改了存储 storageclass:如下

helm install 装置 sonarqube 到 kube-ops namespace

[root@k8s-master-01 sonarqube-lts]# helm install sonarqube -f values.yaml  . -n kube-ops


[root@k8s-master-01 anchore-engine1]# kubectl get svc -n kube-ops
[root@k8s-master-01 anchore-engine1]# kubectl get pods -n kube-ops

ingress 对外映射

ingress 应用的 traefik, 详情参照:Kubernetes 1.20.5 装置 traefik 在腾讯云下的实际

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sonarqube-sonarqube-lts
  namespace: kube-ops
  annotations:
    kubernetes.io/ingress.class: traefik  
    traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
  rules:
  - host: sonarqube.xxxx.com
    http:
     paths:
     - pathType: Prefix
       path: /
       backend:
          service:
            name:  sonarqube-sonarqube-lts
            port:
              number: 9000

web 登陆 sonarqube 验证

默认用户名明码 admin admin(我蒙的),进去批改了明码


更改 中文语言包 (感觉换成中文真心不好,非必要的还是英文吧我感觉!)


可能会无奈从 gitlab 下载插件 pod log 日志报错如下

能够手动下载插件 kubectl cp 插件到 pod /opt/sonarqube/extensions/plugins 目录中,而后重启服务,重启服务能够在 web 操作

默认语言的扫描插件应该新版本貌似都装置了:


当然了 我的还是试了几次在线装置胜利了 间接有了 restart server 的提醒,而后重启 server!

从新登陆,胜利切换语言为中文

jenkins 集成 sonar

参照:https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-jenkins/

创立 SonaQube 的账户 token

将 token 保留到 Jenkins 凭据中


在 Jenkins 中装置插件 sonarqube scanner。

jenkins 配置 sonarqube 服务器

转到 ” 治理 Jenkins> 系统配置 ”,向下滚动到 SonarQube 配置局部,单击 Add SonarQube,增加服务器,抉择凭据。

[root@k8s-master-01 anchore-engine1]# kubectl cp sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar sonarqube-sonarqube-lts-0:/opt/sonarqube/lib/extensions/sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar -n kube-ops
Defaulted container "sonarqube-lts" out of: sonarqube-lts, wait-for-db (init), init-sysctl (init), inject-prometheus-exporter (init)
[root@k8s-master-01 anchore-engine1]# kubectl exec -it sonarqube-sonarqube-lts-0 bash -n kube-ops
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
Defaulted container "sonarqube-lts" out of: sonarqube-lts, wait-for-db (init), init-sysctl (init), inject-prometheus-exporter (init)
bash-5.0$ cd /opt/sonarqube/lib/extensions/
bash-5.0$ ls
sonar-csharp-plugin-8.22.0.31243.jar     sonar-go-plugin-1.8.3.2219.jar           sonar-javascript-plugin-7.4.4.15624.jar  sonar-ruby-plugin-1.8.3.2219.jar
sonar-css-plugin-1.4.2.2002.jar          sonar-html-plugin-3.4.0.2754.jar         sonar-kotlin-plugin-1.8.3.2219.jar       sonar-scala-plugin-1.8.3.2219.jar
sonar-flex-plugin-2.6.1.2564.jar         sonar-jacoco-plugin-1.1.1.1157.jar       sonar-php-plugin-3.17.0.7439.jar         sonar-vbnet-plugin-8.22.0.31243.jar
sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar   sonar-java-plugin-6.15.1.26025.jar       sonar-python-plugin-3.4.1.8066.jar       sonar-xml-plugin-2.2.0.2973.jar

我的 jenkins build 节点

我的 jenkins 是部署在 kubernetes 集群中的,嗯集群的 cri 用了 containerd…. 故构建我用了一台独自的服务器装置了 docker 做 build 节点应用了 jnlp 的形式启动一个 jar 程序包!, 嗯主机节点命名是 build01。
集体习惯 build(嗯算是 soft 软件吧)的包都扔到 /data/ci/buildtools 目录下了,改名也是集体习惯疏忽 ……

[root@k8s-node-06 buildtools]# pwd
/data/ci/buildtools
[root@k8s-node-06 buildtools]# wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.6.2.2472-linux.zip
[root@k8s-node-06 buildtools]# unzip sonar-scanner-cli-4.6.2.2472-linux.zip
[root@k8s-node-06 buildtools]#mv sonar-scanner-cli-4.6.2.2472-linux.zip sonar-scanner

批改 /etc/profile 退出环境

vim /etc/profile

export SONAR_SCANNER_HOME=/data/ci/buildtools/sonar-scanner
export PATH=$SONAR_SCANNER_HOME/bin:$PATH

source /etc/profile 


对于 sonar-scanner 默认的 jdk 是 11,代码都是 java8…. 有必要批改一下 …….

use_embedded_jre=true 批改为 false

注:当然了前提我的服务器 server 早装置了 java8, 毕竟 jenkins 跑起来了早 ……,加入 /etc/profile 中 java 配置

sonar pipeline demo

搞一个 java 的 demo

gitlab 中仓库以及测试代码

登陆 https://start.spring.io/ 生成一个 jar 包:

下载到本地上传到本人的 gitlab 仓库:https://gitlab.xxxx.com/devop…:

额定扔了一个 jenkinsfile,当然了 也能够间接 jenkins 中 Pipeline script

def buildTools = ["maven": "/usr/local/maven/",
                 "sonar" : "/data/ci/buildtools/sonar-scanner/"]




pipeline {agent { label  "build01"}    
    options {skipDefaultCheckout true}

    stages {stage("GetCode"){
            steps{
                script{println("下载代码 --> 分支:${env.branchName}")
                     checkout([$class: 'GitSCM', branches: [[name: "${env.branchName}"]],
                              extensions: [], 
                              userRemoteConfigs: [[credentialsId: 'gitlab-admin-user', 
                                                      url: "${env.gitHttpURL}"]]])
                }
            }
            
        }

        stage("Build"){
            steps {
                script {

                    //sh "/usr/local/maven/bin/mvn clean package"
                    sh "${buildTools["maven"]}/bin/mvn clean package"
                }
            }
        }
        stage("SonarScanForPlugin"){
            steps{
                script{withSonarQubeEnv("sonarqube-1"){
                        def sonarDate = sh  returnStdout: true, script: 'date  +%Y%m%d%H%M%S'
                        sonarDate = sonarDate - "\n"

                        sh """${buildTools["sonar"]}/bin/sonar-scanner \
                                -Dsonar.projectKey=${JOB_NAME} \
                                -Dsonar.projectName=${JOB_NAME} \
                                -Dsonar.projectVersion=${sonarDate} \
                                -Dsonar.ws.timeout=30 \
                                -Dsonar.projectDescription="my test project" \
                                -Dsonar.links.homepage=http://www.baidu.com \
                                -Dsonar.sources=src \
                                -Dsonar.sourceEncoding=UTF-8 \
                                -Dsonar.java.binaries=target/classes \
                                -Dsonar.java.test.binaries=target/test-classes \
                                -Dsonar.java.surefire.report=target/surefire-reports  \
                                
                                #echo \$PATH
                           """
                    }
                }
            }
        }

        stage("UnitTest"){
            steps{
                script{sh "${buildTools["maven"]}/bin/mvn test"

                }
            }
            post {
                success {
                    script{junit 'target/surefire-reports/*.xml'}
                }
            }
        }

    }

    post {
        always {
            script{echo "always......"}
        }

        success {
            script {echo "success....."}
        }
    }

}

对于 jenkins job

jenkinsfile 中用了参数化构建,先把这两个参数搞上了,另外新点的 gitlab 中分支都叫 main 了,不再是 master 了。也留神一下:

构建工作

构建实现发现一个问题:jenkins 配置 sonarqube 服务器的过程中我写的集群内的内网地址。而后这样 sonar 的连接点开都无奈跳转,所以我将 sonarqube 的服务器配置最初设置为了公网地址:



空白 demo 没有什么太大看的就先跑通一下。后续再整合看看怎么优化,因为本人的我的项目也都是聚合我的项目要看一下怎么去玩一下!

php 我的项目

我其余的我的项目大部分是 php 了也扫描一下试试吧!这个仓库比拟坑上面有 7 - 8 个子我的项目,我平时做的是参数化构建的。这里就摘出来一个做测试

def buildTools = ["maven": "/usr/local/maven/",
                 "sonar" : "/data/ci/buildtools/sonar-scanner/"]
pipeline {agent { label  "build01"}
    stages {stage("GetCode"){agent { label  "build01"}
            steps{
                script{println("下载代码 --> 分支:${env.branchName}")
                     checkout([$class: 'GitSCM', branches: [[name: "${env.branchName}"]],
                              doGenerateSubmoduleConfigurations: false, 
                             extensions: [[$class: 'CloneOption', depth: 1, noTags: false, reference: '', shallow: true]], 
                             submoduleCfg: [], 
                              userRemoteConfigs: [[credentialsId: 'xxxxx', 
                              url: "${env.gitHttpURL}"]]])
                }
            }
         }
        stage("SonarScanForPlugin"){agent { label  "build01"}
            when {environment name: 'xxxx', value: 'true'}        
            steps{
                script{withSonarQubeEnv("sonarqube-1"){
                        def sonarDate = sh  returnStdout: true, script: 'date  +%Y%m%d%H%M%S'
                        sonarDate = sonarDate - "\n"

                        sh """   cd xxxx/html
                                ${buildTools["sonar"]}/bin/sonar-scanner \
                                -Dsonar.projectKey=${JOB_NAME}-xxxxx \
                                -Dsonar.projectName=${JOB_NAME}-xxxx \
                                -Dsonar.projectVersion=${sonarDate} \
                                -Dsonar.ws.timeout=30 \
                                                 -Dsonar.language=php \
                                -Dsonar.projectDescription="my php project" \
                                -Dsonar.sources=. \
                                -Dsonar.sourceEncoding=UTF-8 \
                                
                                #echo \$PATH
                           """
                    }
                }
            }
        }       
        stage('docker build laya-maker') {agent { label  "build01"}
            when {environment name: 'xxxx', value: 'true'}
            steps {
                sh "cd laya-maker&&docker build -t ccr.ccs.tencentyun.com/xxxxx/xxxx:$data ."
                withCredentials([usernamePassword(credentialsId: 'xxxxx', passwordVariable: 'dockerPassword', usernameVariable: 'dockerUser')]) {sh "docker login -u ${dockerUser} -p ${dockerPassword} ccr.ccs.tencentyun.com"
                    sh "docker push ccr.ccs.tencentyun.com/xxxxx/xxxx:$data"
        }       
            }
            }

    }
}

运行根本就是上面这个样子:

有点懵逼哈哈哈。

看了一眼破绽这样的根本都能够疏忽。有工夫钻研一下怎么深刻应用!

讲一下比拟刺激的

扫了一下线上 java 仓库的代码,小伙伴都不加 method = {RequestMethod.GET, RequestMethod.POST})这样的?,前段时间无聊看他人写的 java 代码 安全性来说 这不是标准吗 …… 请原谅一下咱们这些家养的 ….. 看不下去了 …….

总结:

本文着重于装置以及配置。实战要深入研究一下,也心愿小伙伴能分享一下更多实战的例子让我学习一下 ……

退出移动版