• KubeSphere DevOps流水线部署


    一. 安装

    1.1 下载yaml

    mkdir -p /root/i/yaml/kubesphere && cd /root/i/yaml/kubesphere
    wget https://github.com/kubesphere/ks-installer/releases/download/v3.3.0/kubesphere-installer.yaml
    wget https://github.com/kubesphere/ks-installer/releases/download/v3.3.0/cluster-configuration.yaml
    
    • 1
    • 2
    • 3

    查看

    [root@master kubesphere]# ls
    cluster-configuration.yaml  kubesphere-installer.yaml
    
    • 1
    • 2

    1.2 设置默认StorageClass

    [root@master kubesphere]# kubectl get sc | grep nfs-storage
    nfs-storage   nfs-storage   Retain          Immediate           false                  115d
    [root@master kubesphere]# kubectl patch storageclass nfs-storage -p  '{ "metadata" : { "annotations" :{"storageclass.kubernetes.io/is-default-class": "true"}}}'
    storageclass.storage.k8s.io/nfs-storage patched
    [root@master kubesphere]# kubectl get sc | grep nfs-storage
    nfs-storage (default)   nfs-storage   Retain          Immediate           false                  115d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果没有设置,不会安装

    1.3 安装

    kubectl create ns kubesphere-system
    kubectl apply -f kubesphere-installer.yaml
    
    • 1
    • 2

    安装成功

    [root@master kubesphere]# kubectl get pods -n kubesphere-system
    NAME                           READY   STATUS    RESTARTS   AGE
    ks-installer-c9655d997-hpqns   1/1     Running   0          72s
    
    • 1
    • 2
    • 3

    1.4 配置

    kubectl apply -f cluster-configuration.yaml
    
    • 1

    检查安装日志

    kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
    
    • 1

    1.5 查看

    新建了命名空间

    kubesphere-controls-system:
    kubesphere-monitoring-federated:联邦集群,多集群
    kubesphere-monitoring-system:集群监控
    kubesphere-system:
    
    • 1
    • 2
    • 3
    • 4

    其他资源

    [root@master kubesphere]# kubectl get pods -n kubesphere-system
    NAME                                     READY   STATUS    RESTARTS   AGE
    ks-apiserver-66cd784f8f-jn2k5            1/1     Running   0          11m
    ks-console-5c5676fb55-h6krc              1/1     Running   0          11m
    ks-controller-manager-6d6b54464d-qrxfs   1/1     Running   0          11m
    ks-installer-c9655d997-kz4gb             1/1     Running   0          12m
    
    [root@master kubesphere]# kubectl get svc -n kubesphere-system
    NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    ks-apiserver            ClusterIP   10.109.250.63           80/TCP         11m
    ks-console              NodePort    10.102.49.78            80:30880/TCP   11m
    ks-controller-manager   ClusterIP   10.101.243.88           443/TCP        11m
    
    [root@master kubesphere]# kubectl get pods -n kubesphere-monitoring-system
    NAME                                               READY   STATUS    RESTARTS   AGE
    alertmanager-main-0                                2/2     Running   0          8m58s
    alertmanager-main-1                                2/2     Running   0          8m57s
    alertmanager-main-2                                2/2     Running   0          8m56s
    kube-state-metrics-645c64569c-pkvkj                3/3     Running   0          9m55s
    node-exporter-2t6pq                                2/2     Running   0          9m54s
    node-exporter-bstgl                                2/2     Running   0          9m54s
    node-exporter-mts6g                                2/2     Running   0          9m55s
    notification-manager-deployment-7dd45b5b7d-p4bpr   2/2     Running   0          5m15s
    notification-manager-deployment-7dd45b5b7d-sp8vw   2/2     Running   0          5m15s
    notification-manager-operator-8598775b-vppz6       2/2     Running   0          9m34s
    prometheus-k8s-0                                   2/2     Running   0          8m57s
    prometheus-k8s-1                                   2/2     Running   0          8m55s
    prometheus-operator-57c78bd7fb-jbfxs               2/2     Running   0          9m56s
    
    [root@master kubesphere]# kubectl get pvc -n kubesphere-monitoring-system
    NAME                                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    prometheus-k8s-db-prometheus-k8s-0   Bound    pvc-9046cbb5-8c31-4014-9342-6a63fb348fb3   20Gi       RWO            nfs-storage    9m9s
    prometheus-k8s-db-prometheus-k8s-1   Bound    pvc-5816cdfc-0976-4312-918c-d4dc361d5ec9   20Gi       RWO            nfs-storage    9m7s
    
    • 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

    1.6 页面

    访问 http://192.168.4.27:30880,默认账号密码admin/P@88w0rd,然后要求修改密码Ww$19930327
    image.png

    二. 流水线部署

    2.1 开启流水线设置

    2.1.1 未安装KS前进行设置

    在安装KS前,可通过编辑config-sample.yaml文件,设置如下:

    devops:
      enabled: true # 将"false"更改为true
    
    • 1
    • 2
    2.1.2 已安装过KS通过管理界面进行设置

    若之前已安装过KS,则可通过KS管理界面(平台管理->集群管理)左侧菜单定时资源定义(CRD) -> 搜索clusterconfiguration -> 然后编辑其下资源ks-installer,如下图:
    image.png
    点击进入
    image.png
    同样设置devops.enabledtrue
    image.png
    kubectl 中执行以下命令检查安装过程:

    kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
    
    • 1

    Kubesphere Devops详细开启说明可参见:
    https://kubesphere.io/zh/docs/pluggable-components/devops/

    2.2 查看流水线安装

    设置完成后可通过KS管理界面查看系统组件 - DevOps相关资源是否已安装完成,如下图:
    image.png

    状态都是健康,安装成功

    2.3 创建企业空间

    工作台 -> 企业空间 -> 创建
    image.png

    2.4 创建DevOps项目

    image.png
    image.png

    2.5 Devops项目添加凭证

    后续在使用流水线时,Jenkins pipeline脚本需要与外部Git仓库Docker仓库K8s集群(可以是外部集群)进行交互,所以需要在其对应的Devops项目中添加凭证(用于访问外部环境的账号密码、密钥等),后续在Jenkins pipeline脚本中会通过凭证名称(ID)进行引用。

    测试环境的外部依赖如下:

    凭证名称(ID)凭证类型凭证说明
    gitee-wanfei用户名和密码Gitee登录账号密码,用于流水线拉取代码
    docker-aliyun用户名和密码阿里云容器镜像服务ACR个人版 docker login账号密码,用于Jenkins脚本推送docker镜像
    k8s-config-kskubeconfig当前K8s集群的kubeconfig文件(新建时默认填充),用于Jenkins脚本部署K8s应用负载

    双击 DevOps 项目名称进入
    具体凭证列表如下图:
    image.png

    2.6 自定义 Jenkins Agent(忽略这一步)

    2.6.1 查看agent配置

    配置->配置字典->搜索jenkins-casc-config->编辑YAML
    image.png
    搜索data.jenkins_user.yaml:jenkins.clouds.kubernetes.templates

    2.6.2 自定义agent配置(label没有发现)

    也可以添加自定义镜像,例如:

    - name: "maven-jdk11" # 自定义 Jenkins Agent 的名称。
      label: "maven jdk11" # 自定义 Jenkins Agent 的标签。若要指定多个标签,请用空格来分隔标签。
      inheritFrom: "maven" # 该自定义 Jenkins Agent 所继承的现有容器组模板的名称。
      containers:
      - name: "maven" # 该自定义 Jenkins Agent 所继承的现有容器组模板中指定的容器名称。
        image: "kubespheredev/builder-maven:v3.2.0jdk11" # 此镜像只用于测试。您可以使用自己的镜像。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2.6.3 java8

    官方镜像:kubesphere/builder-maven:v3.2.0,但是helm版本是2

    2.6.4 java11

    官方镜像:kubesphere/builder-maven:v3.2.1-jdk11,但是helm版本是2

    Dockerfile可以参考 https://hub.docker.com/layers/builder-maven/kubesphere/builder-maven/v3.2.1-jdk11/images/sha256-0fed85db83a4b215a128ae1155a3f007fa6d03adc37f65acfd9bc2cdb4c5597a?context=explore

    2.6.5 maven-pvc(可以不用pvc执行挂载hostPath)

    image.png
    添加maven-pvc,也可以使用现有的devops-jenkins pvc,存储maven下载的jar,多次部署不用重复下载

    2.7 测试流水线Jenkinsfile(可以跳过)

    2.7.1 使用自带的label maven
    pipeline {
      agent {
        node {
          label 'maven'
        }
      }
      stages {
        stage('Print Maven and JDK version') {
          steps {
            container('maven') {
              sh '''
              mvn -v
              java -version
              '''
            }
          }
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    参考 https://kubesphere.io/zh/docs/v3.3/devops-user-guide/how-to-use/pipelines/choose-jenkins-agent/

    2.7.2 使用自定义得label maven && jdk11(报错label发现不了)
    pipeline {
      agent {
        node {
          label 'maven && jdk11'
        }
      }
      stages {
        stage('Print Maven and JDK version') {
          steps {
            container('maven') {
              sh '''
              mvn -v
              java -version
              '''
            }
          }
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    参考 https://kubesphere.io/zh/docs/v3.3/devops-user-guide/how-to-use/pipelines/customize-jenkins-agent/

    2.7.3 yaml
    pipeline {
      agent {
        kubernetes {
          //cloud 'kubernetes'
          label 'mypod'
          yaml """
    apiVersion: v1
    kind: Pod
    spec:
      containers:
      - name: maven
        image: kubesphere/builder-maven:v3.2.1-jdk11
        command: ['cat']
        tty: true
    """
        }
      }
      stages {
        stage('Print Maven and JDK version') {
          steps {
            container('maven') {
              sh '''
              mvn -v
              java -version
              '''
            }
          }
        }
      }
    }
    
    • 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

    2.8 测试流水线

    2.8.1 项目添加Jekinsfile``2.7.1

    image.png

    2.8.2 创建流水线

    image.png
    image.png
    输入git仓库地址和凭证
    image.png
    image.png
    image.png
    image.png

    2.8.3 查看git分支

    双击流水线名称进入
    image.png

    2.8.4 运行

    image.png
    image.png
    运行中
    image.png
    双击进入
    image.png

    2.8.5 查看日志

    点击右上角 查看日志
    image.png

    可以看到执行了Jenkinsfile配置的流水线脚本

    2.9 项目Jenkinsfile

    def label = "slave-${UUID.randomUUID().toString()}"
    
    def helmLint(String chartDir) {
        println "校验 chart 模板"
        sh "helm lint ${chartDir}"
    }
    
    def helmDeploy(Map args) {
        if (args.dry_run) {
            println "Debug 应用 ${args.profile} 环境"
            sh "helm upgrade --install --dry-run --debug --install ..."
        } else {
            println "部署应用 到 ${args.profile} 环境"
            sh "helm upgrade --install --set global.pullPolicy=Always --set global.javaOpts='-Xms256m -Xmx1024m -Xss512k -XX:+PrintGC' \
                --set global.imagePullSecrets=${args.imagePullSecrets} --set global.imageHub.server=${args.imageHubServer}\
                --set global.imageHub.project=${args.imageHubProject} --set global.version=${args.imageTag} \
                --set global.profiles=${args.profile} --set global.namespace=${args.namespace} ${args.name} ${args.chartDir}"
            echo "应用 ${args.name} 部署成功. 可以使用 helm status ${args.name} 查看应用状态"
        }
    }
    
    podTemplate(label: label,
        containers: [
            containerTemplate(name: 'maven', image: 'kubesphere/builder-maven:v3.2.1-jdk11', command: 'cat', ttyEnabled: true),
            containerTemplate(name: 'helm', image: 'hypnoglow/kubernetes-helm:3.0.2', command: 'cat', ttyEnabled: true)
        ],
        volumes: [
                hostPathVolume(hostPath: '/var/run/docker.sock', mountPath: '/var/run/docker.sock'),
                hostPathVolume(hostPath: '/var/data/jenkins_maven_cache', mountPath: '/root/.m2'),
                hostPathVolume(mountPath: '/var/data/jenkins_sonar_cache', hostPath: '/root/.sonar/cache')
            ]) {
            node(label) {
            // checkout scm 下载代码
            def myRepo = checkout scm
            def gitCommit = myRepo.GIT_COMMIT
            def gitBranch = myRepo.GIT_BRANCH
            // Docker凭证ID
            def dockerCredentialId = "docker-aliyun"
            def imageHubServer = "registry.cn-shanghai.aliyuncs.com"
            def imageHubProject = "wanfei"
            def imageTag = "1.0.0-dev"
            // K8S配置凭证ID
            def k8sConfigCredentialId = 'k8s-config-ks'
    
            stage('代码编译打包') {
                container('maven') {
                    echo "1. 代码编译打包阶段"
                    echo "当前commit: ${gitCommit}, 分支: ${gitBranch}"
                    sh """
                    ls -la
                    mvn clean package -Dmaven.test.skip=true
                    """
                }
            }
    
            stage('构建 Docker 镜像') {
                container('maven') {
                    withCredentials([usernamePassword(credentialsId: "${dockerCredentialId}", passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME')]) {
                        echo "2. 构建 Docker 镜像阶段"
                        sh """
                        ls -la
                        echo "$DOCKER_PASSWORD" | docker login "${imageHubServer}" -u "$DOCKER_USERNAME" --password-stdin
                        sh ./script/deploy/buildImage.sh -v "${imageTag}" -s "${imageHubServer}" -p "${imageHubProject}"
                        """
                      }
                }
            }
    
            stage('运行 Helm') {
                container('helm') {
                echo "3. [INFO] 开始 Helm 部署"
                    // 使用对应K8s配置
                    withCredentials([
                        kubeconfigFile(
                        credentialsId: "${k8sConfigCredentialId}",
                        variable: 'KUBECONFIG')
                        ]) {
                            helmDeploy(
                                dry_run             : false,
                                imagePullSecrets    : "",
                                imageHubServer      : "${imageHubServer}",
                                imageHubProject     : "${imageHubProject}",
                                imageTag            : "${imageTag}",
                                profile             : "dev",
                                namespace           : "default",
                                name                : "devops-demo",
                                chartDir            : "./script/deploy/chart/"
                            )
                            echo "[INFO] Helm 部署应用成功..."
                    }
                }
            }
    
        }
    }
    
    • 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
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95

    2.10 Jenkins

    访问 http://192.168.4.27:30180/ ,账号密码admin / P@88w0rd

    参考 https://kubesphere.io/zh/docs/v3.3/faq/devops/install-jenkins-plugins/

    三. 集成sonar

    3.1 helm安装sonar

    helm upgrade --install sonarqube sonarqube \
      --repo https://charts.kubesphere.io/main \
      -n kubesphere-devops-system  \
      --create-namespace \
      --set service.type=NodePort \
      --set service.nodePort=32590
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • repo地址:https://charts.kubesphere.io/main
    • 安装版本:8.9-community

    界面访问 http://192.168.4.27:32590/ 账号密码 admin / admin,修改密码为www19930327

    3.2 创建 SonarQube 管理员令牌 (Token)

    点击右上角字母 A,然后从菜单中选择 My Account 以转到 Profile 页面。
    image.png
    点击 Security 并输入令牌名称,例如 kubesphere
    image.png
    点击 Generate 并复制此令牌。
    image.png

    c0500471a49371f7fa4053f3b9dc50e091fc3d72

    将上面生成的token保存到Jenkins凭据中
    image.png

    3.3 创建 Webhook 服务器

    执行以下命令获取 SonarQube Webhook 的地址。(就是Jenkins地址)

    export NODE_PORT=$(kubectl get --namespace kubesphere-devops-system -o jsonpath="{.spec.ports[0].nodePort}" services devops-jenkins)
    export NODE_IP=$(kubectl get nodes --namespace kubesphere-devops-system -o jsonpath="{.items[0].status.addresses[0].address}")
    echo http://$NODE_IP:$NODE_PORT/sonarqube-webhook/
    
    • 1
    • 2
    • 3

    预期输出结果:

    http://192.168.4.27:30180/sonarqube-webhook/
    
    • 1

    依次点击 AdministrationConfigurationWebhooks 创建一个 Webhook。
    image.png
    点击 Create
    image.png
    在弹出的对话框中输入 NameJenkins Console URL(即 SonarQube Webhook 地址)。点击 Create 完成操作。
    image.png

    3.4 将 SonarQube 配置添加到 ks-installer

    执行以下命令编辑 ks-installer。

    kubectl edit cc -n kubesphere-system ks-installer
    
    • 1

    搜寻至 devops。添加字段 sonarqube 并在其下方指定 externalSonarUrl 和 externalSonarToken。

    devops:
      enabled: true
      jenkinsJavaOpts_MaxRAM: 2g
      jenkinsJavaOpts_Xms: 512m
      jenkinsJavaOpts_Xmx: 512m
      jenkinsMemoryLim: 2Gi
      jenkinsMemoryReq: 1500Mi
      jenkinsVolumeSize: 8Gi
      sonarqube: # Add this field manually.
        externalSonarUrl: http://192.168.4.27:32590 # The SonarQube IP address.
        externalSonarToken: c0500471a49371f7fa4053f3b9dc50e091fc3d72 # The SonarQube admin token created above.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    完成操作后保存此文件。

    3.5 将 SonarQube 服务器添加至 Jenkins

    3.5.1 配置sonar服务器

    登录Jenkins
    点击 系统管理 -> 系统配置
    搜寻到 SonarQube servers,然后点击 Add SonarQube
    image.png

    sonar
    http://192.168.4.27:32590
    sonar-token
    
    • 1
    • 2
    • 3

    点击确定

    3.5.2 全局配置SonarQube Scanner

    点击 系统管理 -> 全局工具配置
    image.png
    点击保存

    3.6 将 sonarqubeURL 添加到 KubeSphere 控制台

    您需要指定 sonarqubeURL,以便可以直接从 KubeSphere 控制台访问 SonarQube。

    执行以下命令:

    kubectl edit  cm -n kubesphere-system  ks-console-config
    
    • 1

    搜寻到 data.client.enableKubeConfig,在下方添加 devops 字段并指定 sonarqubeURL。

    client:
      enableKubeConfig: true
      devops: # 手动添加该字段。
        sonarqubeURL: http://192.168.4.27:32590 # SonarQube IP 地址。
    
    • 1
    • 2
    • 3
    • 4

    保存该文件。

    3.7 重启服务

    kubectl -n kubesphere-devops-system rollout restart deploy devops-apiserver
    
    • 1
    kubectl -n kubesphere-system rollout restart deploy ks-console
    
    • 1

    3.8 项目Jenkinsfile

    def label = "slave-${UUID.randomUUID().toString()}"
    
    def helmLint(String chartDir) {
        println "校验 chart 模板"
        sh "helm lint ${chartDir}"
    }
    
    def helmDeploy(Map args) {
        if (args.dry_run) {
            println "Debug 应用 ${args.profile} 环境"
            sh "helm upgrade --install --dry-run --debug --install ..."
        } else {
            println "部署应用 到 ${args.profile} 环境"
            sh "helm upgrade --install --set global.pullPolicy=Always --set global.javaOpts='-Xms256m -Xmx1024m -Xss512k -XX:+PrintGC' \
                --set global.imagePullSecrets=${args.imagePullSecrets} --set global.imageHub.server=${args.imageHubServer}\
                --set global.imageHub.project=${args.imageHubProject} --set global.version=${args.imageTag} \
                --set global.profiles=${args.profile} --set global.namespace=${args.namespace} ${args.name} ${args.chartDir}"
            echo "应用 ${args.name} 部署成功. 可以使用 helm status ${args.name} 查看应用状态"
        }
    }
    
    podTemplate(label: label,
        containers: [
            containerTemplate(name: 'maven', image: 'kubesphere/builder-maven:v3.2.1-jdk11', command: 'cat', ttyEnabled: true),
            containerTemplate(name: 'helm', image: 'hypnoglow/kubernetes-helm:3.0.2', command: 'cat', ttyEnabled: true)
        ],
        volumes: [
                hostPathVolume(hostPath: '/var/run/docker.sock', mountPath: '/var/run/docker.sock'),
                hostPathVolume(hostPath: '/var/data/jenkins_maven_cache', mountPath: '/root/.m2'),
                hostPathVolume(mountPath: '/var/data/jenkins_sonar_cache', hostPath: '/root/.sonar/cache')
            ]) {
            node(label) {
            // checkout scm 下载代码
            def myRepo = checkout scm
            def gitCommit = myRepo.GIT_COMMIT
            def gitBranch = myRepo.GIT_BRANCH
            // Docker凭证ID
            def dockerCredentialId = "docker-aliyun"
            def imageHubServer = "registry.cn-shanghai.aliyuncs.com"
            def imageHubProject = "wanfei"
            def imageTag = "1.0.0-dev"
            // K8S配置凭证ID
            def k8sConfigCredentialId = 'k8s-config-ks'
    
            stage('代码编译打包') {
                container('maven') {
                    echo "1. 代码编译打包阶段"
                    echo "当前commit: ${gitCommit}, 分支: ${gitBranch}"
                    sh """
                    ls -la
                    mvn clean package -Dmaven.test.skip=true
                    """
                }
            }
    
            stage('代码扫描') {
                echo "2. 代码扫描阶段"
                // jenkins配置的 sonar-server name
                withSonarQubeEnv('sonar') {
                    def SCANNER_HOME = tool 'sonar-scan'
                    sh """
                    ${SCANNER_HOME}/bin/sonar-scanner \
                    -Dsonar.projectKey=devops-demo1 \
                    -Dsonar.projectName=devops-demo1 \
                    -Dsonar.projectVersion=1.0 \
                    -Dsonar.sourceEncoding=UTF-8 \
                    -Dsonar.language=java \
                    -Dsonar.sources=src \
                    -Dsonar.java.binaries=target/classes
                    """
                }
            }
    
            stage('检查结果分析') {
                echo "3. 检查结果分析阶段"
                timeout(5) {
                    // 等待sonarqube结果回调过来
                    def qg = waitForQualityGate()
                    echo "结果状态: ${qg.status}"
                    if (qg.status != 'OK') {
                        error "未通过Sonarqube的代码质量阈检查,请及时修改!failure: ${qg.status}"
                    }
                }
            }
    
            stage('构建 Docker 镜像') {
                container('maven') {
                    withCredentials([usernamePassword(credentialsId: "${dockerCredentialId}", passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME')]) {
                        echo "4. 构建 Docker 镜像阶段"
                        sh """
                        ls -la
                        echo "$DOCKER_PASSWORD" | docker login "${imageHubServer}" -u "$DOCKER_USERNAME" --password-stdin
                        sh ./script/deploy/buildImage.sh -v "${imageTag}" -s "${imageHubServer}" -p "${imageHubProject}"
                        """
                      }
                }
            }
    
            stage('运行 Helm') {
                container('helm') {
                echo "5. [INFO] 开始 Helm 部署"
                    // 使用对应K8s配置
                    withCredentials([
                        kubeconfigFile(
                        credentialsId: "${k8sConfigCredentialId}",
                        variable: 'KUBECONFIG')
                        ]) {
                            helmDeploy(
                                dry_run             : false,
                                imagePullSecrets    : "",
                                imageHubServer      : "${imageHubServer}",
                                imageHubProject     : "${imageHubProject}",
                                imageTag            : "${imageTag}",
                                profile             : "dev",
                                namespace           : "default",
                                name                : "devops-demo",
                                chartDir            : "./script/deploy/chart/"
                            )
                            echo "[INFO] Helm 部署应用成功..."
                    }
                }
            }
    
        }
    }
    
    • 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
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125

    3.9 测试

    image.png
    image.png

    四. 提交代码自动构建

    4.1 查看Webhook 推送 URL

    流水线 -> 编辑
    image.png
    复制URL
    image.png

    4.2 gitee添加webhook

    在这里插入图片描述
    添加

    因为部署再本地环境,gitee无法访问,所以配置下内网穿透测试

    # 原地址
    http://192.168.4.27:30880/devops_webhook/git/?url=https://gitee.com/www19930327/devops-demo.git
    
    # 内网穿透后
    http://frp-tai.wanfei.wang/devops_webhook/git/?url=https://gitee.com/www19930327/devops-demo.git
    
    • 1
    • 2
    • 3
    • 4
    • 5

    image.png
    添加成功
    在这里插入图片描述

    4.3 测试

    随便添加一行代码
    image.png
    触发自动构建
    image.png
    代码检查通过
    image.png
    构建成功
    image.png

  • 相关阅读:
    Kotlin高仿微信-第5篇-主页-通讯录
    【技能树笔记】网络篇——练习题解析(三)
    第8天:Django Admin高级配置
    定时器方案,红黑树,时间轮
    Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)
    无线信道划分
    Spring之AOP的切点、通知、切点表达式以及知识要点
    FFmpeg 命令:从入门到精通 | ffmpeg 命令裁剪与合并视频
    计算机视觉任务图像预处理之去除图像中的背景区域-------使用连通域分析算法(包含完整代码)
    I.MX6UL的uboot移植
  • 原文地址:https://blog.csdn.net/qq_38983728/article/details/126337162