zoukankan      html  css  js  c++  java
  • 🏆(不要错过!)【CI/CD技术专题】「Jenkins实战系列」(4)jenkins+pipeline构建自动化部署

    前提引言

    • Jenkins的精髓是Pipeline(流水线技术),那为什么要用Pipeline呢?实现自动化构建,其中Pipeline能够将以前project中的配置信息以steps的方式放在一个脚本里,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂流程,形成流水式发布,构建步骤视图化。

    • 简单来说,Pipeline适用的场景更广泛,能胜任更复杂的发布流程。举个例子,job构建工作在master节点,自动化测试脚本在slave节点,而不同节点的执行处理通过Pipeline可以。

    基本概念

    • 【Stage: 阶段】,一个Pipeline可以划分为若干个Stage,每个Stage代表一组操作。注意,Stage是一个逻辑分组的概念,可以跨多个Node。

    • 【Node: 节点】,一个Node就是一个Jenkins节点,或者是Master,或者是slave,是执行Step的具体运行期环境。

    • 【Step: 步骤】,Step是最基本的操作单元,小到创建一个目录,大到构建一个Docker镜像,由各类Jenkins Plugin提供。

    Pipeline配置

    新建一个“流水线”的job

    配置Pipeline脚本

    Pipeline也支持Poll SCM

    pipline流水线流程

    PIpeline语法

    1. Pipeline支持两种语法:Declarative Pipeline(在Pipeline 2.5中引入,结构化方式)Scripted Pipeline,两者都支持建立连续输送的Pipeline。

    共同点

    两者都是pipeline代码的持久实现,都能够使用pipeline内置的插件或者插件提供的steps,两者都可以利用共享库扩展。

    不同点:

    • 两者不同之处在于语法和灵活性。Declarative pipeline对用户来说,语法更严格,有固定的组织结构,更容易生成代码段,使其成为用户更理想的选择。

    • 但是Scripted pipeline更加灵活,因为Groovy本身只能对结构和语法进行限制,对于更复杂的pipeline来说,用户可以根据自己的业务进行灵活的实现和扩展。

    下面举例介绍两种语法的使用

    Declarative Pipeline

    windows环境脚本案例
    pipeline {
        agent any  //在可用的节点运行
        stages{
    	stage ('Prepare'){
                steps{
    		 //清空发布目录
                     bat '''if exist D:\publish\LoginServiceCore (rd/s/q D:\publish\LoginServiceCore)
                           if exist C:\Users\Administrator\.nuget (rd/s/q C:\Users\Administrator\.nuget) exit''' 
    		} 
    	} 
           	//拉取git代码仓库
           	stage ('Checkout'){
                	steps{
                        checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], 
                        userRemoteConfigs: [[credentialsId: 'c6d98bbd-5cfb-4e26-aa56-f70b054b350d', 
                        url: 'http://xxx/xxx/xxx']]])
                  }
            }
           //构建
           stage ('Build'){
              steps{
                 bat '''cd "D:\Program Files (x86)\Jenkins\workspace\LoginServiceCore\LoginApi.Hosting.Web"
                      dotnet restore
                      dotnet build
                      dotnet publish --configuration Release --output D:\publish\LoginServiceCore'''
                      }
                }
           //部署
          stage ('Deploy'){
              steps{
                   bat '''cd D:\PipelineScript\LoginServiceCore
                      python LoginServiceCore.py'''
                      }
                 }
          //自动化测试(python代码实现)
          stage ('Test'){
              steps{
                   bat'''cd D:\PipelineScript\LoginServiceCore
                  python LoginServiceCoreApitest.py'''   
                      }
                 }
        }
     }
    

    Scripted Pipeline

    node('master') {     //master节点运行,以下stage也可指定节点
        stage 'Prepare'  //清空发布目录
            bat '''if exist D:\publish\LoginServiceCore (rd/s/q D:\publish\LoginServiceCore)
                   if exist C:\Users\Administrator\.nuget (rd/s/q C:\Users\Administrator\.nuget)
                   exit'''
    
        //拉取git代码仓库
        stage 'Checkout'
            checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [],        submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'c6d98bbd-5cfb-4e26-aa56-f70b054b350d', 
                url: 'http://xxx/xxx/xxx']]])
       
        //构建
        stage 'Build'
            bat '''cd "D:\Program Files (x86)\Jenkins\workspace\LoginServiceCore\LoginApi.Hosting.Web"
                dotnet restore
                dotnet build
                dotnet publish --configuration Release --output D:\publish\LoginServiceCore'''
        
        //部署
        stage 'Deploy'
            bat '''
            cd D:\PipelineScript\LoginServiceCore
            python LoginServiceCore.py
            '''
        //自动化测试(python代码实现)    
        stage 'Test'
            bat'''
            cd D:\PipelineScript\LoginServiceCore
            python LoginServiceCoreApitest.py
            '''   
    }
    

    Pipeline Docker脚本示例

    node{  
      // 代码检出
      stage('get Code') {
        git credentialsId: 'git-credentials-id', url: 'http://192.168.19.250/libo/test.git'
      }
      
        // 镜像中进行单元测试
      stage('unit testing'){ 
        // 启动golnag:1.7并在golang内编译代码
        docker.image('golang:1.7').inside {
          sh './script/unittest.sh'
        }
      }
      
      // 镜像中代码构建
      stage('Build'){    
        def confFilePath = 'conf/app.conf'
        def config = readFile confFilePath
        writeFile file: confFilePath, text: config
        // 启动golnag:1.7并在golang内编译代码
        docker.image('golang:1.7').inside {
          sh './script/build.sh'
        }
      }
      
      // 编译镜像并push到仓库
      def imagesName = '192.168.18.250:5002/ufleet/uflow:v0.9.1.${BUILD_NUMBER}'  
      stage('Image Build And Push'){
        docker.withRegistry('http://192.168.18.250:5002', 'registry-credentials-id') {
          docker.build(imagesName).push()
        }
      }
      
      // 启动刚运行的容器
      stage('deploy iamegs'){    
        // 需要删除旧版本的容器,否则会导致端口占用而无法启动。
        try{
          sh 'docker rm -f cicdDemo'
        }catch(e){
            // err message
        }
        docker.image(imagesName).run('-p 9091:80 --name cicdDemo') 
      }
    }
    

    git操作认证

    withCredentials([usernamePassword(credentialsId: '<credentials-id>', passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
        sh '''
            printf "machine github.com
    login $GIT_USERNAME
     password $GIT_PASSWORD" >> ~/.netrc
            // continue script as necessary working with git repo...
        '''
    }
    

    git拉取代码

    checkout scm: ([
                        $class: 'GitSCM',
                        userRemoteConfigs: [[credentialsId: '******',url: ${project_url}]],
                        branches: [[name: 'refs/tags/${project_tag}']]
    ])
    
    极限就是为了超越而存在的
  • 相关阅读:
    Spring@Profile注解
    day 32 子进程的开启 及其用法
    day 31 udp 协议SOCK_DGRAM
    day 30 客户端获取cmd 命令的步骤
    day 29 socket 理论
    day 29 socket 初级版
    有关 组合 继承
    day 27 多态 接口 类方法 静态方法 hashlib 摘要算法模块
    新式类和经典类的区别
    day 28 hasattr getattr serattr delattr 和带__内置__ 类的内置方法
  • 原文地址:https://www.cnblogs.com/liboware/p/15114555.html
Copyright © 2011-2022 走看看