Jenkins自动构建 CI/CD流水线学习笔记(从入门到入土,理论+示例)

简介: Jenkins自动构建 CI/CD流水线学习笔记(从入门到入土,理论+示例)

1、什么是Jenkins的流水线?

Jenkins 流水线是一套插件,它支持实现和集成持续交付流水线到 Jenkins。流水线提供了一组可扩展的工具,用于通过流水线 DSL 将简单到复杂的交付流水线建模为“代码”。

对Jenkins 流水线的定义被写在一个文本文件中 (成为 Jenkinsfile),该文件可以被提交到项目的源代码的控制仓库。这是"流水线即代码"的基础; 将CD 流水线作为应用程序的一部分,像其他代码一样进行版本化和审查。 创建 Jenkinsfile并提交它到源代码控制中提供了一些即时的好处:

  • 自动地为所有分支创建流水线构建过程并拉取请求。
  • 在流水线上代码复查/迭代 (以及剩余的源代码)。
  • 对流水线进行审计跟踪。
  • 该流水线的真正的源代码 [3], 可以被项目的多个成员查看和编辑。

2、流水线语法

Jenkinsfile 能使用两种语法进行编写 - 声明式和脚本化。

声明式和脚本式流水线都是 DSL 语言,[1]用来描述软件交付流水线的一部分。 脚本式流水线是用一种限制形式的 Groovy 语法编写的。

声明式和脚本化的流水线从根本上是不同的。 声明式流水线的是 Jenkins 流水线更近的特性:

  • 相比脚本化的流水线语法,它提供更丰富的语法特性,
  • 是为了使编写和读取流水线代码更容易而设计的。

然而,写到Jenkinsfile中的许多单独的语法组件(或者 “步骤”), 通常都是声明式和脚本化相结合的流水线。

2.1、声明式流水线

在声明式流水线语法中, pipeline 块定义了整个流水线中完成的所有的工作。

pipeline {
    agent any 
    stages {
        stage('Build') { 
            steps {
                // 
            }
        }
        stage('Test') { 
            steps {
                // 
            }
        }
        stage('Deploy') { 
            steps {
                // 
            }
        }
    }
}

说明:

  1. 在任何可用的代理上,执行流水线或它的任何阶段。
  2. 定义 “Build” 阶段。
  3. 执行与 “Build” 阶段相关的步骤。
  4. 定义"Test" 阶段。
  5. 执行与"Test" 阶段相关的步骤。
  6. 定义 “Deploy” 阶段。
  7. 执行与 “Deploy” 阶段相关的步骤

2.2、脚本化流水线

在脚本化流水线语法中, 一个或多个 node 块在整个流水线中执行核心工作。 虽然这不是脚本化流水线语法的强制性要求, 但它限制了你的流水线的在node块内的工作做两件事:

  1. 通过在Jenkins队列中添加一个项来调度块中包含的步骤。 节点上的执行器一空闲, 该步骤就会运行。
  2. 创建一个工作区(特定为特定流水间建立的目录),其中工作可以在从源代码控制检出的文件上完成。
    Caution: 根据你的 Jenkins 配置,在一系列的空闲后,一些工作区可能不会自动清理 。
node {  
    stage('Build') { 
        // 
    }
    stage('Test') { 
        // 
    }
    stage('Deploy') { 
        // 
    }
}

说明:

  1. 在任何可用的代理上,执行流水线或它的任何阶段。
  2. 定义 “Build” 阶段。 stage 块 在脚本化流水线语法中是可选的。 然而, 在脚本化流水线中实现 stage 块 ,可以清楚的显示Jenkins UI中的每个 stage 的任务子集。
  3. 执行与 “Build” 阶段相关的步骤。
  4. 定义 “Test” 阶段。
  5. 执行与 “Test” 阶段相关的步骤。
  6. 定义 “Deploy” 阶段。
  7. 执行与 “Deploy” 阶段相关的步骤

3、流水线示例

3.1、使用声明式流水线的语法编写的 Jenkinsfile 文件

pipeline { 
    agent any 
    stages {
        stage('Build') { 
            steps { 
                sh 'make' 
            }
        }
        stage('Test'){
            steps {
                sh 'make check'
                junit 'reports/**/*.xml' 
            }
        }
        stage('Deploy') {
            steps {
                sh 'make publish'
            }
        }
    }
}

说明:

  1. pipeline 是声明式流水线的一种特定语法,他定义了包含执行整个流水线的所有内容和指令的 “block” 。
  2. agent是声明式流水线的一种特定语法,它指示 Jenkins 为整个流水线分配一个执行器 (在节点上)和工作区。
  3. stage 是一个描述 stage of this Pipeline的语法块。在 Pipeline syntax 页面阅读更多有关声明式流水线语法的stage块的信息。如 above所述, 在脚本化流水线语法中,stage 块是可选的。
  4. steps 是声明式流水线的一种特定语法,它描述了在这个 stage 中要运行的步骤。
  5. sh 是一个执行给定的shell命令的流水线 step (由 Pipeline: Nodes and Processes plugin提供) 。
  6. junit 是另一个聚合测试报告的流水线 step (由 JUnit plugin提供)。
  7. node 是脚本化流水线的一种特定语法,它指示 Jenkins 在任何可用的代理/节点上执行流水线 (和包含在其中的任何阶段)这实际上等效于 声明式流水线特定语法的agent

3.2、Pipeline 各种语言示例

3.2.1 Java:
pipeline {
    agent { docker 'maven:3.3.3' }
    stages {
        stage('build') {
            steps {
                sh 'mvn --version'
            }
        }
    }
}
3.2.2 Node.js / JavaScript
pipeline {
    agent { docker 'node:6.3' }
    stages {
        stage('build') {
            steps {
                sh 'npm --version'
            }
        }
    }
}
3.2.3 Python
pipeline {
    agent { docker 'python:3.5.1' }
    stages {
        stage('build') {
            steps {
                sh 'python --version'
            }
        }
    }
}

4、一套完整的Devops Jenkinsfile流水线

本示例流水线包括以下八个阶段。

说明:

  • 阶段 1:Checkout SCM:从 GitHub 仓库检出源代码。
  • 阶段 2:单元测试:待该测试通过后才会进行下一阶段。
  • 阶段 3:SonarQube 分析:SonarQube 代码质量分析。
  • 阶段 4:构建并推送快照镜像:根据策略设置中选定的分支来构建镜像,并将 SNAPSHOT-B R A N C H N A M E − BRANCH_NAME-BRANCHNAMEBUILD_NUMBER 标签推送至 Docker Hub,其中 $BUILD_NUMBER 为流水线活动列表中的运行序号。
  • 阶段 5:推送最新镜像:将 SonarQube 分支标记为 latest,并推送至 Docker Hub。
  • 阶段 6:部署至开发环境:将 SonarQube 分支部署到开发环境,此阶段需要审核。
  • 阶段 7:带标签推送:生成标签并发布到 GitHub,该标签会推送到 Docker Hub。
  • 阶段 8:部署至生产环境:将已发布的标签部署到生产环境。
pipeline {
  agent {
    node {
      label 'maven'
    }
  }
  stages {
    stage('clone code') {
      steps {
        container('maven') {
          checkout([$class: 'GitSCM', branches: [[name: '*/$BRANCH_NAME']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: 'https://github.com/kubesphere/devops-python-sample.git']]])
        }
      }
    }
    stage('unit test') {
      steps {
        container('maven') {
          sh 'mvn clean -o -gs `pwd`/configuration/settings.xml test'
        }
      }
    }
    stage('build & push') {
      steps {
        container('maven') {
          sh 'mvn -o -Dmaven.test.skip=true -gs `pwd`/configuration/settings.xml clean package'
          sh 'docker build -f Dockerfile-online -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER .'
          withCredentials([usernamePassword(passwordVariable : 'DOCKER_PASSWORD' ,usernameVariable : 'DOCKER_USERNAME' ,credentialsId : "$DOCKER_CREDENTIAL_ID" ,)]) {
            sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
            sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER'
          }
        }
      }
    }
    stage('push latest') {
      when {
        branch 'master'
      }
      steps {
        container('maven') {
          sh 'docker tag  $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
          sh 'docker push  $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest '
        }
      }
    }
    stage('deploy to dev') {
      steps {
        container('maven') {
          input(id: 'deploy-to-dev', message: 'deploy to dev?')
          withCredentials([kubeconfigContent(credentialsId : 'KUBECONFIG_CREDENTIAL_ID' ,variable : 'KUBECONFIG_CONFIG' ,)]) {
            sh 'mkdir -p ~/.kube/'
            sh 'echo "$KUBECONFIG_CONFIG" > ~/.kube/config'
            sh 'envsubst < deploy/dev-ol/deploy.yaml | kubectl apply -f -'
          }
        }
      }
    }
    stage('deploy to production') {
      steps {
        container('maven') {
          input(id: 'deploy-to-production', message: 'deploy to production?')
          withCredentials([kubeconfigContent(credentialsId : 'KUBECONFIG_CREDENTIAL_ID' ,variable : 'KUBECONFIG_CONFIG' ,)]) {
            sh 'mkdir -p ~/.kube/'
            sh 'echo "$KUBECONFIG_CONFIG" > ~/.kube/config'
            sh 'envsubst < deploy/prod-ol/deploy.yaml | kubectl apply -f -'
          }
        }
      }
    }
  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    REGISTRY = 'docker.io'
    DOCKERHUB_NAMESPACE = 'docker_username'
    GITHUB_ACCOUNT = 'kubesphere'
    APP_NAME = 'devops-java-sample'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}


磨你的心智,是为了以后不管你遇见任何人和事,都能稳如泰山。

目录
相关文章
|
2月前
|
JavaScript 前端开发 持续交付
Prettier 高级应用:集成 CI/CD 流水线与插件开发
【10月更文挑战第18天】Prettier 是一款流行的代码格式化工具,它能够自动将代码格式化成一致的风格,从而提高代码的可读性和维护性。对于希望进一步发挥 Prettier 潜力的高级用户而言,将 Prettier 集成到持续集成(CI)和持续部署(CD)流程中,确保每次提交的代码都符合团队标准,是非常重要的。此外,通过开发自定义插件来支持更多语言或扩展 Prettier 的功能也是值得探索的方向。本文将详细介绍这两方面的内容。
54 2
|
2月前
|
jenkins 测试技术 持续交付
Docker最佳实践:构建高效的CI/CD流水线
【10月更文挑战第17天】在现代软件开发实践中,持续集成(Continuous Integration, CI)和持续部署(Continuous Deployment, CD)已成为提高开发效率和软件质量的重要手段。Docker作为一种容器技术,为构建一致且隔离的开发环境提供了强有力的支撑。本文将探讨如何利用Docker来优化CI/CD流程,包括构建环境的标准化、镜像管理以及与CI/CD工具(如Jenkins、GitLab CI)的集成。
70 5
|
2月前
|
运维 jenkins 持续交付
自动化运维之路:构建高效CI/CD流水线
在软件开发的快节奏中,持续集成和持续部署(CI/CD)流水线是提升效率、保障质量的关键。本文将引导你理解CI/CD流水线的重要性,并手把手教你如何搭建一个高效的自动化运维系统。通过实际代码示例,我们将一步步实现从代码提交到自动测试、部署的全流程自动化,确保软件交付过程既快速又可靠。
|
3月前
|
Kubernetes 持续交付 Go
创建一个基于Go程序的持续集成/持续部署(CI/CD)流水线
创建一个基于Go程序的持续集成/持续部署(CI/CD)流水线
|
4月前
|
Java Spring 传感器
AI 浪潮席卷,Spring 框架配置文件管理与环境感知,为软件稳定护航,你还在等什么?
【8月更文挑战第31天】在软件开发中,配置文件管理至关重要。Spring框架提供强大支持,便于应对不同环境需求,如电商项目的开发、测试与生产环境。它支持多种格式的配置文件(如properties和YAML),并能根据环境加载不同配置,如数据库连接信息。通过`@Profile`注解可指定特定环境下的配置生效,同时支持通过命令行参数或环境变量覆盖配置值,确保应用稳定性和可靠性。
66 0
|
4月前
|
敏捷开发 Java 测试技术
阿里云云效产品使用合集之如何下载流水线构建过程中生成的jar
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
4月前
|
敏捷开发 测试技术 持续交付
阿里云云效产品使用合集之如何限制在本地的构建主机创建的流水线的并发数
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
4月前
|
敏捷开发 Java 测试技术
阿里云云效产品使用合集之怎么设置流水线中的全局参数
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
4月前
|
敏捷开发 缓存 5G
阿里云云效产品使用合集之流水线中的webhook是否可以设置为变量
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
4月前
|
敏捷开发 测试技术 持续交付
阿里云云效产品使用合集之流水线同时并发数最高是多少
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。