美文网首页中间件解决方案微服务
Jenkins+GitLab+Docker+SpringClou

Jenkins+GitLab+Docker+SpringClou

作者: 欢醉 | 来源:发表于2019-07-10 08:48 被阅读140次

      现有混合云平台的场景下,即有线下和线上的环境,又有测试与正式的场景,而且结合了Docker,导致打包内容有所区分,且服务的发布流程复杂起来,手工打包需要在编译阶段就要根据环境到处更改配置,因此纯手工发布增加了实施的难度,需要一个统一的适应各种环境部署的方案。

    基于微服务的发布流程

      手动/自动构建 -> Jenkins 调度 K8S API ->动态生成 Jenkins Slave pod -> Slave pod 拉取 Git 代码/编译/打包镜像 ->推送到镜像仓库 Harbor -> Slave工作完成,Pod 自动销毁 ->部署到测试或生产 Kubernetes(K8S)平台。

      上面是理想状况下的将服务编译打包成镜像上传到镜像库后部署到Kubernetes平台的一个流程,但问题是:

    我们有线上线下平台,代码在线下GitLab,是出不了外网的,因此线上K8S集群无法拉取代码编译。

    Jenkins的master所在服务器是CentOS6.5,没有Docker环境,也没有在K8S集群服务器内,因此无法直接执行docker build镜像和 kubectl apply 发布服务到K8S集群。

    Jenkins的slave节点都是无法访问外网的,

    线上服务需要Pinpoint而线下环境暂时不需要启用Pinpoint,否则一直报错,因此需要根据选择的环境动态的构建Dockerfile,而且要求整个发布流程可选择。

    就上面现实问题,我们将发布流程简化:

    关键点:

    Docker镜像的打包使用com.spotify的docker-maven-plugin插件结合Dockerfile,调用远程服务器的Docker环境生成镜像。

    K8S服务部署采用的是ssh方式,将Deployment文件上传到K8S集群服务器,然后执行部署命令。

    如何利用Dockerfile打包镜像

      之前也是用com.spotify的docker-maven-plugin插件来打包镜像并推送到私有镜像仓库,但问题是无法根据环境写条件判断,如动态选择是否需要启动pinpoint,线上线下库地址动态更换,导致镜像名前缀也是要动态变化的,此时直接配置无法满足,需要结合Dockerfile来实现。

    先更改pom文件,指定本项目的Dockerfile文件地址,默认是放在项目根目录下:

    <plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.2.0</version><configuration><!--覆盖相同标签镜像--><forceTags>true</forceTags><!-- 与maven配置文件settings.xml一致 --><serverId>nexus-releases</serverId><!--私有仓库地址 --><registryUrl>https://${docker.repostory}</registryUrl><!--远程Docker地址 --><dockerHost>http://10.3.87.210:2375</dockerHost><!-- 注意imageName一定要是符合正则[a-z0-9-_.]的,否则构建不会成功 --><!--指定镜像名称 仓库/镜像名:标签--><imageName>${docker.repostory}/${project.artifactId}:${project.version}</imageName><dockerDirectory>${project.basedir}</dockerDirectory><resources><resource><!-- 指定要复制的目录路径,这里是当前目录 --><!-- 将打包文件放入dockerDirectory指定的位置 --><targetPath>/app/</targetPath><!-- 指定要复制的根目录,这里是target目录 --><directory>${project.build.directory}</directory><!-- 指定需要拷贝的文件,这里指最后生成的jar包 --><include>${project.build.finalName}.jar</include></resource></resources></configuration></plugin>

    <registryUrl>https://${docker.repostory}</registryUrl>

    指定远程仓库地址,在主项目的<properties>中指定,这里默认线上仓库<docker.repostory>39.95.40.97:5000</docker.repostory>

    <dockerHost>http://10.3.87.210:2375</dockerHost>

    指定Docker镜像打包服务器,这里指定线下服务器。

    <imageName>${docker.repostory}/${project.artifactId}:${project.version}</imageName>

    指定镜像名称 仓库/镜像名:标签

    <dockerDirectory>${project.basedir}</dockerDirectory>

    指定Dockerfile文件地址,此处指定项目根目录

    Dockerfile内容

    FROM join:0.2

    MAINTAINER {description} Join

    ADD /app/{artifactId}-{version}.jar /app/

    ENTRYPOINT ["java", "-Xmx512m","-Dspring.profiles.active={active}",{jarparam} "-jar", "/app/{artifactId}-{version}.jar"]

      基础镜像用join:0.2,里面包含了pinpoint和监控jvm的promethus客户端包。

      Jarparam会在Jenkins中动态替换运行时参数,active 指定当前运行环境,这里可能有人提议根据项目yml文件中指定内容自动匹配,因为要考虑到如果自动匹配 更换线上线下环境就需要更改yml配置文件后又要上传到gitlab,如此没有必要多做一步,直接在Jenkins中当作参数指定最为便捷。

      此处Dockerfile是通用模板,如果有特殊内容添加,可自行更改,此时的模板需要在Jenkins运行时替换参数后才有用,如果想直接在本机运行打包,可手动替换参数内容后运行:

    clean package -DskipTests docker:build

    推送

    clean package -DskipTests docker:build -DpushImage

    Jenkins发布流程

    利用Jenkins的pipeline构建流水线

      Pipeline也就是构建流水线,对于程序员来说,最好的解释是:使用代码来控制项目的构建、测试、部署等。使用它的好处有很多,包括但不限于:

    l  使用Pipeline可以非常灵活的控制整个构建过程;

    l  可以清楚的知道每个构建阶段使用的时间,方便构建的优化;

    l  构建出错,使用stageView可以快速定位出错的阶段;

    l  一个job可以搞定整个构建,方便管理和维护等。

      Pipeline 支持两种语法,声明式和脚本式。这两种方法都支持构建持续交付流水线,都可以通过 web UI 或 Jenkinsfile 文件来定义 Pipeline(通常认为创建 Jenkinsfile 文件并上传到源代码控制仓库是最佳实践)

    Jenkinsfile 就是一个包含对 Jenkins Pipeline 定义的文本文件,会上传到版本控制中。下面的 Pipeline 实现了基本的 3 段持续交付流水线。

    声明式 Pipeline:

    // Jenkinsfile (Declarative Pipeline)

    pipeline {

        agent any

        stages {

            stage('Build') {

                steps {

                    echo 'Building..'

                }

            }

            stage('Test') {

                steps {

                    echo 'Testing..'

                }

            }

            stage('Deploy') {

                steps {

                    echo 'Deploying....'

                }

            }

        }

    }

    对应的脚本式 Pipeline:

    // Jenkinsfile (Scripted Pipeline)

    node {

        stage('Build') {

            echo 'Building....'

        }

        stage('Test') {

            echo 'Building....'

        }

        stage('Deploy') {

            echo 'Deploying....'

        }

    }

      注意,所有的 Pipeline 都会有这三个相同的 stage,可以在所有项目的一开始就定义好它们。下面演示在 Jenkins 的测试安装中创建和执行一个简单的 Pipeline。

      假设项目已经设置好了源代码控制仓库,并且已经按照入门章节的描述在 Jenkins 中定义好了 Pipeline。

      使用文本编辑器(最好支持 Groovy 语法高亮显示),在项目根目录中创建 Jenkinsfile。

    上面的声明式 Pipeline 示例包含了实现一个持续交付流水线所需的最少步骤。必选指令 agent 指示 Jenkins 为 Pipeline 分配执行程序和工作空间。没有 agent 指令的话,声明式 Pipeline 无效,无法做任何工作!默认情况下 agent 指令会确保源代码仓库已经检出,并且可用于后续步骤。

      stage 和 step 指令在声明式 Pipeline 中也是必须的,用于指示 Jenkins 执行什么及在哪个 stage 中执行。

      对于脚本式 Pipeline 的更高级用法,上面的示例节点是至关重要的第一步,因为它为 Pipeline 分配了一个执行程序和工作空间。如果没有 node,Pipeline 不能做任何工作!在 node 内,业务的第一阶段是检出此项目的源代码。由于 Jenkinsfile 是直接从源代码控制中提取的,因此 Pipeline 提供了一种快速简单的方法来访问源代码的正确版本:

    // Jenkinsfile (Scripted Pipeline)

    node {

        checkout scm

        /* .. snip .. */

    }

    这个 checkout 步骤会从源代码控制中检查代码,scm 是特殊变量,它指示运行检出步骤,复制触发了这次 Pipeline 运行的指定版本。

    最终的流程样式:

      一般用声明式来构建流水,实际操作过程中还是发现脚本式构建更顺手,而且Groovy语言更方便查资料,因此下面以脚本构建为主演示一个流程。

    1.新建任务

    2.填写任务名和描述,由于防止构建历史太多,只保留3个。

    3.添加构建时全局构建参数,用来构建流程动态选择环境,这里有两种方式,一种是直接在页面上添加,如下图,一种是在Jenkinsfile中添加(第一次构建时不会出现选项,第二次构建才会出现,因此首次构建需要试构建,暂停再刷新页面才会有选择框),两种最张效果一样,这里为了方便采用Jenkinsfile来添加全局参数。

    Jenkinsfile中添加

    properties([

            parameters([string(name: 'PORT', defaultValue: '7082', description: '程序运行端口'),choice(name: 'ACTIVE_TYPE', choices: ['dev', 'prd', 'local'], description: '程序打包环境'),choice(name: 'ENV_TYPE', choices: ['online', 'offline'], description: '线上、还是线下环境'),booleanParam(name: 'ON_PINPOINT', defaultValue: true, description: '是否添加Pinpoint监控'),booleanParam(name: 'ON_PROMETHEUS', defaultValue: true, description: '是否添加Prometheus监控'),string(name: 'EMAIL', defaultValue: '104@qq.com', description: '打包结果通知')])

    ])

    4.选择源码代码库:

    需要添加认证,将Jenkins的ssh秘钥添加到GitLab的页面中,且需要将此处gitlab中joint用户添加到需要拉取代码的项目中才有权限拉取代码。

    Jenkinsfile位置放在项目的根目录。

    5. Jenkinsfile中指定maven目录地址

    MVNHOME = '/opt/maven354'

    为防止手工填写项目名和版本号等一系列信息,因此直接读取pom文件中要编译项目的这些信息给全局变量:

    pom = readMavenPom file: 'pom.xml'

    echo "group: ${pom.groupId}, artifactId: ${pom.artifactId}, version: ${pom.version} ,description: ${pom.description}"

    artifactId = "${pom.artifactId}"

    version = "${pom.version}"

    description = "${pom.description}"

    根据选择的线上环境还是线下环境,替换镜像仓库ip

    if (params.ENV_TYPE == 'offline' || params.ENV_TYPE == null) {

    sh "sed -i 's#39.95.40.97:7806#10.3.87.51:8080#g' pom.xml"

    image = "10.3.87.51:8080/${artifactId}:${version}"

    }

    6.编译

    利用maven构建,利用上面的内容先替换掉Dockerfile、Deployment中的变量,再根据选择的条件是否启用pinpoint和promethus,最后编译。

    def jarparam=''

    def pinname = artifactId

    if( pinname.length() > 23) {

      pinname = artifactId.substring(0,23)

    }

    //添加pinpointif(params.ON_PINPOINT) {

      jarparam ='"-javaagent:/app/pinpoint-agent/pinpoint-bootstrap-1.8.0.jar","-Dpinpoint.agentId={pinname}", "-Dpinpoint.applicationName={pinname}",'}//添加prometheusif(params.ON_PROMETHEUS) {

      jarparam = jarparam +'"-javaagent:/app/prometheus/jmx_prometheus_javaagent-0.11.0.jar=1234:/app/prometheus/jmx.yaml",'}

    sh "sed -i 's#{jarparam}#${jarparam}#g' Dockerfile"sh "sed -i 's#{description}#${description}#g;s#{artifactId}#${artifactId}#g;s#{version}#${version}#g;s#{active}#${params.ACTIVE_TYPE}#g;s#{pinname}#${pinname}#g' Dockerfile"sh "sed -i 's#{artifactId}#${artifactId}#g;s#{version}#${version}#g;s#{port}#${params.PORT}#g;s#{image}#${image}#g' Deployment.yaml"sh "'${MVNHOME}/bin/mvn' -DskipTests clean package"

    需要注意的是pinpoint的pinpoint.applicationName不能操作24个字符,否则启用不成功,因此超过的直接截断。

    Department文件详情看后文。

    跳过测试编译打包 '${MVNHOME}/bin/mvn' -DskipTests clean package 需要在Jenkins服务器安装maven环境,还有指定maven的jar包私有仓库地址。

    7. Docker打包

    前提是上一步指定pom文件中的镜像仓库和Dockerfile中的内容是替换后的完整内容。

    sh "'${MVNHOME}/bin/mvn' docker:build"

    8. 推送镜像

    sh "'${MVNHOME}/bin/mvn' docker:push"

    如何发布服务到K8S集群

      前面几步已经将项目打包并生成了镜像并推送到了私有仓库,下面就是部署服务到K8S集群。

    先看看Department.yaml文件:

    ---apiVersion: apps/v1

    kind: Deployment

    metadata:

      name: {artifactId}

      namespace: default

      labels:

        app: {artifactId}

        version: {version}

    spec:

      selector:

        matchLabels:

          app: {artifactId}

      replicas: 1  template:

        metadata:

          labels:

            app: {artifactId}

          annotations:

            prometheus.io.jmx: "true"        prometheus.io.jmx.port: "1234"    spec:

          containers:

          - name: {artifactId}

            image: {image}

            # IfNotPresent\Always        imagePullPolicy: Always

            ports:

            - name: prometheusjmx

              containerPort: 1234        livenessProbe: #kubernetes认为该pod是存活的,不存活则需要重启          httpGet:

                path: /health

                port: {port}

                scheme: HTTP

              initialDelaySeconds: 60## 设置为系统完全启动起来所需的最大时间+若干秒timeoutSeconds: 5          successThreshold: 1          failureThreshold: 5        readinessProbe: #kubernetes认为该pod是启动成功的          httpGet:

                path: /health

                port: {port}

                scheme: HTTP

              initialDelaySeconds: 40## 设置为系统完全启动起来所需的最少时间timeoutSeconds: 5          successThreshold: 1          failureThreshold: 5        env:

            - name: eureka-server

              value: "eureka-server.default.svc.cluster.local"- name: eureka-server-replica

              value: "eureka-server-replica.default.svc.cluster.local"        resources:

            # 5%的CPU时间和700MiB的内存          requests:#            cpu: 50m            memory: 700Mi

              # 最多允许它使用          limits:#            cpu: 100m            memory: 1000Mi

            # 指定在容器中挂载路径        volumeMounts:

            - name: logs-volume

              mountPath: /logs

            - name: host-time

              mountPath: /etc/localtime

              readOnly: true

            - name: host-timezone

              mountPath: /etc/timezone

              readOnly: true

            - name: pinpoint-config

              mountPath: /app/pinpoint-agent/pinpoint.config

          volumes:

          - name: logs-volume

            hostPath:

            # 宿主机上的目录path: /logs

          - name: host-time

            hostPath:

              path: /etc/localtime

          - name: host-timezone

            hostPath:

              path: /usr/share/zoneinfo/Asia/Shanghai

          - name: pinpoint-config

            configMap:

              name: pinpoint-config

          # 运行在指定标签的节点,前提是先给节点打标  kubectl label nodes 192.168.0.113 edgenode=flow#      nodeSelector:#        edgenode: flow---apiVersion: v1

    kind: Service

    metadata:

      name: {artifactId}

      namespace: default

      labels:

        app: {artifactId}

        version: {version}

    spec:

      selector:

        app: {artifactId}

      ports:

      - name: tcp-{port}-{port}

        protocol: TCP

        port: {port}

        targetPort: {port}

    里面的变量会在前面几步自动替换掉。

    添加了prometheus收集jvm的内容:

    prometheus.io.jmx: "true"

    prometheus.io.jmx.port: "1234"

    containerPort: 1234

    将pinpoint的配置内容pinpoint.config用configMap  保存,方便更改内容。

    其它内容不在此详解,可自行google。

      网上资料一般发布服务都是直接kubectl deploy,这种情况只适用于jenkins的服务器已包含在K8S服务器集群中。第二种情况是在K8S集群服务器里面生成Jenkins的一个slave节点,然后在pipeline里面设置node(“k8s”){ ……} 里面发布,具体方法自行google。

            这里为了避免麻烦,采用直接SSH到K8S服务器集群的方案发布服务。

    配置sshagent

    SSH Agent Plugin :sshagent方法支持,用于上传构建产物到目标服务器,使用详情见:

    https://wiki.jenkins.io/display/JENKINS/SSH+Agent+Plugin

    在Jenkins插件库搜索后直接下载安装(需要连外网环境),生产环境已安装,直接使用。

    使用:

    sshagent(credentials: ['deploy_ssh_key_23']) {

    sh "scp -P 2222 -r Deployment.yaml root@39.95.40.97:/docker/yaml/Deployment-${artifactId}.yaml"

    sh "ssh -p 2222 root@39.95.40.97 'kubectl apply -f /docker/yaml/Deployment-${artifactId}.yaml && kubectl set env deploy/${artifactId} DEPLOY_DATE=${env.BUILD_ID}'"

    }

    先用ssh远程到K8S集群中的服务器,将Deployment文件上传,然后再远程执行kubectl apply发布服务。

            为了避免误操作,在发布前做了发布确认提示判断。

    timeout(time: 10, unit: 'MINUTES') {

    input '确认要部署吗?'

    }

          以上流程已完成整个流程,然后可以去K8S环境去看服务是否有正常运行。

    关于测试

      上面的过程没有加入代码测试、代码质量分析SonarQube、发布后服务测试的阶段(Selenium是一套完整的Web应用程序测试系统http://www.51testing.com/zhuanti/selenium.html),后续可以接入。

    如何进行多模块如何构建

      很多项目采用的是多模块构成,因此每个项目配置和发布要求不一样,需要单独编译到部署,所以每个模块都需要独立的Dockerfile和Deployment文件,Jenkinsfile通用一份,然后在发布时自动弹出模块列表,选择需要发布的模块进行编译发布。

    //需要处理的项目多项目时先进入子项目

    projectwk ="."mainpom = readMavenPom file:'pom.xml'//存在多个模块时,选择其中一个进行编译if(mainpom.modules.size() > 0 ) {

      echo "项目拥有模块==${mainpom.modules}"  timeout(time: 10, unit:'MINUTES') {

        defselproj = input message:'请选择需要处理的项目', parameters: [choice(choices: mainpom.modules, description:'请选择需要处理的项目', name:'selproj')] //, submitterParameter:'project'    projectwk = selproj

        echo "选择项目=${projectwk}"  }

    }

     读取主项目的pom中的modules判断是否包含多个模块,供用户选择。

    然后根据选择的模块进行编译,dir进入选择的模块读取信息并编译。

    dir("${projectwk}") {

        pom = readMavenPom file:'pom.xml'    echo "group: ${pom.groupId}, artifactId: ${pom.artifactId}, version: ${pom.version} ,description: ${pom.description}"    artifactId ="${pom.artifactId}"    version ="${pom.version}"    description ="${pom.description}"}

    完整的Jenkinsfile

    properties([

            parameters([string(name: 'PORT', defaultValue:'7082', description:'程序运行端口'),choice(name:'ACTIVE_TYPE', choices: ['dev','prd','local'], description:'程序打包环境'),choice(name:'ENV_TYPE', choices: ['online','offline'], description:'线上、还是线下环境'),booleanParam(name:'ON_PINPOINT', defaultValue: true, description:'是否添加Pinpoint监控'),booleanParam(name:'ON_PROMETHEUS', defaultValue: true, description:'是否添加Prometheus监控'),string(name:'EMAIL', defaultValue:'1041126478@qq.com', description:'打包结果通知')])

    ])

    node {

        stage('Prepare') {

            echo "1.Prepare Stage"        MVNHOME ='/opt/maven354'//echo"UUID=${UUID.randomUUID().toString()}"        checkout scm

            //需要处理的项目多项目时先进入子项目

            projectwk ="."        mainpom = readMavenPom file:'pom.xml'        repostory ="${mainpom.properties['docker.repostory']}"//存在多个模块时,选择其中一个进行编译

            if(mainpom.modules.size() > 0 ) {

              echo "项目拥有模块==${mainpom.modules}"          timeout(time: 10, unit:'MINUTES') {

                defselproj = input message:'请选择需要处理的项目', parameters: [choice(choices: mainpom.modules, description:'请选择需要处理的项目', name:'selproj')] //, submitterParameter:'project'            projectwk = selproj

                echo "选择项目=${projectwk}"          }

            }

            dir("${projectwk}") {

                pom = readMavenPom file:'pom.xml'            echo "group: ${pom.groupId}, artifactId: ${pom.artifactId}, version: ${pom.version} ,description: ${pom.description}"            artifactId ="${pom.artifactId}"            version ="${pom.version}"            description ="${pom.description}"        }

            script {

                GIT_TAG = sh(returnStdout: true, script:'/usr/local/git/bin/git rev-parse --short HEAD').trim()

                echo "GIT_TAG== ${GIT_TAG}"        }

            image ="192.168.4.2:5000/${artifactId}:${version}"if(params.ENV_TYPE =='offline'|| params.ENV_TYPE == null) {

            sh "sed -i 's#39.95.40.97:5000#10.3.80.50:5000#g' pom.xml"        image ="10.3.80.50:5000/${artifactId}:${version}"      }

        }

        if(mainpom.modules.size() > 0 ) {

          stage('编译总项目') {

              sh "'${MVNHOME}/bin/mvn' -DskipTests clean install"      }

        }

        dir("${projectwk}") {

            stage('编译模块') {

                echo "2.编译模块 ${artifactId}"defjarparam=''defpinname = artifactId

                if( pinname.length() > 23) {

                  pinname = artifactId.substring(0,23)

                }

                //添加pinpoint

                if(params.ON_PINPOINT) {

                  jarparam ='"-javaagent:/app/pinpoint-agent/pinpoint-bootstrap-1.8.0.jar","-Dpinpoint.agentId={pinname}", "-Dpinpoint.applicationName={pinname}",'            }

                //添加prometheus

                if(params.ON_PROMETHEUS) {

                  jarparam = jarparam +'"-javaagent:/app/prometheus/jmx_prometheus_javaagent-0.11.0.jar=1234:/app/prometheus/jmx.yaml",'            }

                sh "sed -i 's#{jarparam}#${jarparam}#g' Dockerfile"            sh "sed -i 's#{description}#${description}#g;s#{artifactId}#${artifactId}#g;s#{version}#${version}#g;s#{active}#${params.ACTIVE_TYPE}#g;s#{pinname}#${pinname}#g' Dockerfile"            sh "sed -i 's#{artifactId}#${artifactId}#g;s#{version}#${version}#g;s#{port}#${params.PORT}#g;s#{image}#${image}#g' Deployment.yaml"            sh "'${MVNHOME}/bin/mvn' -DskipTests clean package"            stash includes: 'target/*.jar', name:'app'        }

            stage('Docker打包') {

                echo "3.Docker打包"            unstash 'app'            sh "'${MVNHOME}/bin/mvn' docker:build"        }

            stage('推送镜像') {

                echo "4.Push Docker Image Stage"            sh "'${MVNHOME}/bin/mvn' docker:push"        }

            timeout(time: 10, unit:'MINUTES') {

                input '确认要部署吗?'        }

            stage('发布') {

            if(params.ENV_TYPE =='offline'|| params.ENV_TYPE == null) {

                  sshagent(credentials: ['deploy_ssh_key_34']) {

                    sh "scp -r Deployment.yaml root@10.2.85.30:/docker/yaml/Deployment-${artifactId}.yaml"                sh "ssh root@10.2.85.30 'kubectl apply -f /docker/yaml/Deployment-${artifactId}.yaml && kubectl set env deploy/${artifactId} DEPLOY_DATE=${env.BUILD_ID}'"              }

              } else {

                  sshagent(credentials: ['deploy_ssh_key_238']) {

                    sh "scp -P 22 -r Deployment.yaml root@39.95.40.97:/docker/yaml/Deployment-${artifactId}.yaml"                sh "ssh -p 22 root@39.95.40.97 'kubectl apply -f /docker/yaml/Deployment-${artifactId}.yaml && kubectl set env deploy/${artifactId} DEPLOY_DATE=${env.BUILD_ID}'"              }

              }

                echo "发布完成"        }

        }

      stage('通知负责人'){//    emailext body:"构建项目:${description}\r\n构建完成", subject:'构建结果通知【成功】', to:"${EMAIL}"        echo "构建项目:${description}\r\n构建完成"  }

    }

    将Jenkinsfile文件放在项目根目录,然后将源码都上传到GitLab。

    打开BlueOcean,这是Jenkins新出的美化页面。

    选择自己的项目。

    进入后点击运行,其中会弹出框选择发布参数(这里需要手工填写发布的端口,由于采用配置中心化,端口无法自动读取)。

    进入查看流程状态,失败会有相应的提示:

    显示发布服务

    在K8S内查看部署的服务启动情况。

    Jenkinsfile Pipeline

    Jenkinsfile Pipeline语法内容可参考官网:https://jenkins.io/doc/book/pipeline/jenkinsfile/

    还可以进入项目后,有个流水线语法:

    选择想要的功能,生成:

    Jenkins还可用作发布Vue前端项目,具体内容可参考 Jenkins自动化构建vue项目然后发布到远程服务器 文档。

      Jenkins要发布Net服务需要有一台windows的Jenkins slave,还需要在此节点上安装编译器MSBuild框架,Git框架、更改服务器上的IIS权限等功能,最后文件分发到其它windows服务器,过程比较繁琐,若无发布审核建议直接通过VS自带发布功能发布程序。

    相关文章

      网友评论

        本文标题:Jenkins+GitLab+Docker+SpringClou

        本文链接:https://www.haomeiwen.com/subject/oxcqkctx.html