Jenkins来构建一个Pipeline项目

Jenkins来构建一个Pipeline项目

我们来使用 Jenkins 来构建一个真实的Pipeline项目 进行演示

我们要创建一个Jenkinsfile 的文件 ,放在 git repo 项目根目录。

创建 Pipeline 项目任务

1 首先 在首页开始 选择 新建任务

在这里插入图片描述

2 新建任务, 填写任务名称, 以及选择流水线项目构建。

可以看到这里有很多选项, 自由风格,流水线,多配置项目等, 我认为流水线 比较灵活,通过 pipeline 脚本来控制比较方便,

自由风格 当然也是可以的, 自由不需要pipeline ,适合简单的发布场景, 我们这里 需要进行一些控制,后面还要和 K8S 打交道。

在这里插入图片描述

3 流水线的配置

点击OK 之后 ,进入 下面的配置页面,这里 找到 流水线的配置, 这里就是要配置 Pipeline 脚本来自哪里,

第一种: Pipeline script 这种方式 是把他卸载 下面的空白的地方, 这种方式, 方便我们来临时调试脚本。

第二种: Pipeline script from SCM, 选择一个git 代码仓库, 然后把 Jenkinfile 放在 代码仓库里面,这样可以维护这个文件,进行追踪 变化等。建议也是要放到 repo 里面,这也是官方建议的做法。

在这里插入图片描述

作为演示 我来演示这两种方式

先来第一种: 直接把脚本 粘贴在空白处

我准备好了脚本 Jenkinsfile 脚本

environment 这个块中定义了一些变量。

DOCKER_REGISTRY 这个你需要一个 可以推送镜像的仓库,可以自己搭建.

GIT_URL git 地址 要填写真实地址,

CREDENTIALS_ID 凭据ID , 是要 创建出来,用来拉取代码的凭据。

IMAGE_NAME 打包后 放在image路径里面。

CREDENTIALS_ID 如何创建呢?

系统管理 > 凭据
在这里插入图片描述

在这里插入图片描述

凭据的类型 有很多种选一个你认证的方式, 这个用来 去拉取 git repo 的权限用到的。

在这里插入图片描述

创建完成后,就可以看到 这个凭据ID, 这个ID 就是这样生成的。
在这里插入图片描述

pipeline {
    agent any

    environment {
        // 定义全局环境变量
        // 私有仓库地址
        DOCKER_REGISTRY = 'xxx.xx.xx.xxx:12300'
        IMAGE_NAME = 'saas-cloud-job-service'
        SHORT_NAME = 'cloud-job'
        // 填写 git repo 地址 
        GIT_URL = 'http://git.aaabbb.com/xxx/xxxxxxx/saas-cloud-job-service.git'
        // 拉取代码的凭据ID 
        CREDENTIALS_ID = '080912b9-902a-49f1-89e1-4684586ab238'
    }

    parameters {
        choice(name: 'BRANCH', choices: ['cicd','dev', 'test', 'master'], description: 'Select the branch to build')
        choice(name: 'ENV', choices: ['test', 'prod'], description: 'Select the environment to deploy')
    }
    stages {
        stage('Pull code') {
            steps {
                script {
                    // 使用参数化的分支名称进行 checkout
                    def branchName = params.BRANCH
                    checkout scmGit(
                        branches: [[name: "*/${branchName}"]],
                        extensions: [],
                        userRemoteConfigs: [[credentialsId: CREDENTIALS_ID, url: GIT_URL]]
                    )
                }
            }
        }

        stage('Build project') {
            steps {
                script {
                    def branchName = params.BRANCH
                    env.branchName = branchName  // 设置环境变量

                    // 获取 Git SHA 和当前日期
                    def gitSha = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
                    def currentDate = sh(returnStdout: true, script: 'date +%Y%m%d').trim()

                    // 构建 Docker 镜像标签
                    env.IMAGE_TAG = "${DOCKER_REGISTRY}/${IMAGE_NAME}/${SHORT_NAME}:${branchName}-${currentDate}-${gitSha}"

                    // 打印信息
                    // echo "Building Docker image with tag: ${env.IMAGE_TAG}"

                    // 构建 Docker 镜像
                    sh """
                        echo " ============================= 开始构建docker image ============================= "
                        docker build -f Dockerfile . -t ${env.IMAGE_TAG}
                        echo " ============================= docker image 构建完成  ============================= "
                        echo "[TAG]: ${env.IMAGE_TAG}"
                    """
                }
            }
        }

        stage('Push Docker image') {
            steps {
                script {
                    // 登录并推送 Docker 镜像
                    dockerLoginAndPush(env.IMAGE_TAG)
                }
            }
        }

        stage('Deploy project') {
            steps {
                echo 'Publishing project'
                // 这里可以添加部署的具体步骤
            }
        }
    }

    post {
        always {
            echo 'This pipeline will always run, begin cleaning workspace.'
            cleanWs() 
        }
        success {
            echo 'The pipeline succeeded.'
        }
        failure {
            echo 'The pipeline failed.'
        }
        changed {
            echo 'The pipeline status has changed.'
        }
    }
}


def dockerLoginAndPush(String imageTag) {
    /**
    使用 withDockerRegistry 插件来简化 Docker 登录和推送
    */ 
    withDockerRegistry([credentialsId: 'docker-harbor-registry-credentials', url: "http://${env.DOCKER_REGISTRY}"]) {
        try {
            // 推送 Docker 镜像
            sh "docker push ${imageTag}"
            echo "Pushed Docker Image [TAG]: ${imageTag}"
        } catch (err) {
            error "Failed to push Docker image: ${err}"
        }
    }

}

parameters 解释一下 这个块的作用 ,这里定义两个参数,BRANCH ,ENV 方便来选, 从哪个分支来构建,发布到哪个分支。

stages 整个发布流程的阶段 ,这里定义 四个阶段。 每个阶段 会有 steps 下面 会有脚本,表示这个阶段 有步骤 要执行哪些脚本等。

post 表示发布完成后,做的动作,成功,失败之后 怎么处理等。

dockerLoginAndPush 封装了一个函数 方便 用来推送镜像。

4 把脚本粘贴进行保存

在这里插入图片描述

4-2 使用Jenkinsfile 来构建

这里选 Pipeline script from SCM ,

然后选择 Repositories URL , 然后选择 Credentials

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4-3 回到任务列 ,点击立即构建

在这里插入图片描述

构建第一次 的时候, 直接cancel一下, 然后第二次构建。

第二次构建的时候 你可以发现,界面变了,就是 parameters 生效了, 我们选择 对应的分支以及要发布的环境 ,进行发布。

在这里插入图片描述
点击构建就可以了。

5 构建结果分析

在这里插入图片描述

点击 #2 的位置,就可以看到 构建日志,有时候 就是根据构建日志来排查问题。

在这里插入图片描述

完整的日志复制下来 如下:

2025-03-15 17:50:14  Started by user admin
2025-03-15 17:50:15  [Pipeline] Start of Pipeline
2025-03-15 17:50:15  [Pipeline] node
2025-03-15 17:50:15  Running on Jenkins in /mnt/var/lib/jenkins/workspace/test-job-demo
2025-03-15 17:50:15  [Pipeline] {
2025-03-15 17:50:15  [Pipeline] withEnv
2025-03-15 17:50:15  [Pipeline] {
2025-03-15 17:50:15  [Pipeline] stage
2025-03-15 17:50:15  [Pipeline] { (Pull code)
2025-03-15 17:50:15  [Pipeline] script
2025-03-15 17:50:15  [Pipeline] {
2025-03-15 17:50:15  [Pipeline] checkout
2025-03-15 17:50:15  The recommended git tool is: NONE
2025-03-15 17:50:15  using credential 080912b9-902a-49f1-89e1-4684586ab238
2025-03-15 17:50:15  Cloning the remote Git repository
2025-03-15 17:50:15  Cloning repository http://gitee.aaa.com/xxx/xxxx-xxxxx/saas-cloud-job-service.git
2025-03-15 17:50:15   > /usr/local/git/git-2.43.0/git init /mnt/var/lib/jenkins/workspace/test-job-demo # timeout=10
2025-03-15 17:50:15  Fetching upstream changes from http://gitee.aaa.com/xxx/xxxx-xxxxx/saas-cloud-job-service.git
2025-03-15 17:50:15   > /usr/local/git/git-2.43.0/git --version # timeout=10
2025-03-15 17:50:15   > git --version # 'git version 2.43.0'
2025-03-15 17:50:15  using GIT_ASKPASS to set credentials gitlab-auth-user-password
2025-03-15 17:50:15   > /usr/local/git/git-2.43.0/git fetch --tags --force --progress -- http://gitee.aaa.com/xxx/xxxx-xxxxx/saas-cloud-job-service.git +refs/heads/*:refs/remotes/origin/* # timeout=10
2025-03-15 17:50:16   > /usr/local/git/git-2.43.0/git config remote.origin.url http://gitee.aaa.com/xxx/xxxx-xxxxx/saas-cloud-job-service.git # timeout=10
2025-03-15 17:50:16   > /usr/local/git/git-2.43.0/git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
2025-03-15 17:50:16  Avoid second fetch
2025-03-15 17:50:16   > /usr/local/git/git-2.43.0/git rev-parse refs/remotes/origin/master^{commit} # timeout=10
2025-03-15 17:50:16  Checking out Revision 1f0345adcfc8f98731c8452fa70d034e60e79417 (refs/remotes/origin/master)
2025-03-15 17:50:16   > /usr/local/git/git-2.43.0/git config core.sparsecheckout # timeout=10
2025-03-15 17:50:16   > /usr/local/git/git-2.43.0/git checkout -f 1f0345adcfc8f98731c8452fa70d034e60e79417 # timeout=10
2025-03-15 17:50:16  Commit message: "合并分支 'colin-0114' 到 'master'"
2025-03-15 17:50:16  First time build. Skipping changelog.
2025-03-15 17:50:16  [Pipeline] }
2025-03-15 17:50:16  [Pipeline] // script
2025-03-15 17:50:16  [Pipeline] }
2025-03-15 17:50:16  [Pipeline] // stage
2025-03-15 17:50:16  [Pipeline] stage
2025-03-15 17:50:16  [Pipeline] { (Build project)
2025-03-15 17:50:16  [Pipeline] script
2025-03-15 17:50:16  [Pipeline] {
2025-03-15 17:50:16  [Pipeline] sh
2025-03-15 17:50:16  + git rev-parse --short HEAD
2025-03-15 17:50:16  [Pipeline] sh
2025-03-15 17:50:16  + date +%Y%m%d
2025-03-15 17:50:16  [Pipeline] sh
2025-03-15 17:50:17  + echo ' ============================= 开始构建docker image ============================= '
2025-03-15 17:50:17   ============================= 开始构建docker image ============================= 
2025-03-15 17:50:17  + docker build -f Dockerfile . -t xxx.xx.xx.xxx:12300/saas-cloud-job-service/cloud-job:master-20250315-1f0345a
2025-03-15 17:50:17  #0 building with "default" instance using docker driver
2025-03-15 17:50:17  
2025-03-15 17:50:17  #1 [internal] load build definition from Dockerfile
2025-03-15 17:50:17  #1 transferring dockerfile: 275B done
2025-03-15 17:50:17  #1 DONE 0.0s
2025-03-15 17:50:17  
2025-03-15 17:50:17  #2 [internal] load .dockerignore
2025-03-15 17:50:17  #2 transferring context: 2B done
2025-03-15 17:50:17  #2 DONE 0.0s
2025-03-15 17:50:17  
2025-03-15 17:50:17  #3 [auth] zhiexa-public/python:pull token for xxx.xx.xx.xxx:12300
2025-03-15 17:50:17  #3 DONE 0.0s
2025-03-15 17:50:17  
2025-03-15 17:50:17  #4 [internal] load metadata for xxx.xx.xx.xxx:12300/zhiexa-public/python:3.10.13-slim-bullseye
2025-03-15 17:50:17  #4 DONE 0.1s
2025-03-15 17:50:17  
2025-03-15 17:50:17  #5 [internal] load build context
2025-03-15 17:50:17  #5 transferring context: 415.52kB 0.0s done
2025-03-15 17:50:17  #5 DONE 0.0s
2025-03-15 17:50:17  
2025-03-15 17:50:17  #6 [1/6] FROM xxx.xx.xx.xxx:12300/zhiexa-public/python:3.10.13-slim-bullseye@sha256:b1c82dbf6dfb5e52cf8f595c9b6881696e4a5e996e5146cb99e19c2228592b6a
2025-03-15 17:50:17  #6 resolve xxx.xx.xx.xxx:12300/zhiexa-public/python:3.10.13-slim-bullseye@sha256:b1c82dbf6dfb5e52cf8f595c9b6881696e4a5e996e5146cb99e19c2228592b6a 0.0s done
2025-03-15 17:50:17  #6 DONE 0.0s
2025-03-15 17:50:17  
2025-03-15 17:50:17  #7 [2/6] WORKDIR /usr/src/app
2025-03-15 17:50:17  #7 CACHED
2025-03-15 17:50:17  
2025-03-15 17:50:17  #8 [3/6] RUN mkdir /usr/src/app/logs
2025-03-15 17:50:17  #8 CACHED
2025-03-15 17:50:17  
2025-03-15 17:50:17  #9 [4/6] COPY requirements.txt ./
2025-03-15 17:50:17  #9 CACHED
2025-03-15 17:50:17  
2025-03-15 17:50:17  #10 [5/6] RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt
2025-03-15 17:50:17  #10 CACHED
2025-03-15 17:50:17  
2025-03-15 17:50:17  #11 [6/6] COPY . .
2025-03-15 17:50:17  #11 DONE 0.1s
2025-03-15 17:50:17  
2025-03-15 17:50:17  #12 exporting to image
2025-03-15 17:50:17  #12 exporting layers 0.0s done
2025-03-15 17:50:17  #12 writing image sha256:67c8b72a89e186f32ac93e33c993a524ca3857b871a7813854e19773afe420e5 done
2025-03-15 17:50:17  #12 naming to xxx.xx.xx.xxx:12300/saas-cloud-job-service/cloud-job:master-20250315-1f0345a done
2025-03-15 17:50:17  #12 DONE 0.1s
2025-03-15 17:50:17  + echo ' ============================= docker image 构建完成  ============================= '
2025-03-15 17:50:17   ============================= docker image 构建完成  ============================= 
2025-03-15 17:50:17  + echo '[TAG]: xxx.xx.xx.xxx:12300/saas-cloud-job-service/cloud-job:master-20250315-1f0345a'
2025-03-15 17:50:17  [TAG]: xxx.xx.xx.xxx:12300/saas-cloud-job-service/cloud-job:master-20250315-1f0345a
2025-03-15 17:50:17  [Pipeline] }
2025-03-15 17:50:17  [Pipeline] // script
2025-03-15 17:50:17  [Pipeline] }
2025-03-15 17:50:17  [Pipeline] // stage
2025-03-15 17:50:17  [Pipeline] stage
2025-03-15 17:50:17  [Pipeline] { (Push Docker image)
2025-03-15 17:50:17  [Pipeline] script
2025-03-15 17:50:17  [Pipeline] {
2025-03-15 17:50:17  [Pipeline] withDockerRegistry
2025-03-15 17:50:17  Using the existing docker config file.
2025-03-15 17:50:17  Removing blacklisted property: auths
2025-03-15 17:50:17  $ docker login -u admin -p ******** http://xxx.xx.xx.xxx:12300
2025-03-15 17:50:17  WARNING! Using --password via the CLI is insecure. Use --password-stdin.
2025-03-15 17:50:17  WARNING! Your password will be stored unencrypted in /mnt/var/lib/jenkins/workspace/test-job-demo@tmp/a08f0084-94c3-405c-b3e5-c0135ff990db/config.json.
2025-03-15 17:50:17  Configure a credential helper to remove this warning. See
2025-03-15 17:50:17  https://docs.docker.com/engine/reference/commandline/login/#credentials-store
2025-03-15 17:50:17  
2025-03-15 17:50:17  Login Succeeded
2025-03-15 17:50:17  [Pipeline] {
2025-03-15 17:50:17  [Pipeline] sh
2025-03-15 17:50:18  + docker push xxx.xx.xx.xxx:12300/saas-cloud-job-service/cloud-job:master-20250315-1f0345a
2025-03-15 17:50:18  The push refers to repository [xxx.xx.xx.xxx:12300/saas-cloud-job-service/cloud-job]
2025-03-15 17:50:18  f392f006c0fa: Preparing
2025-03-15 17:50:18  6639ad0972bc: Preparing
2025-03-15 17:50:18  95aae4bf0704: Preparing
2025-03-15 17:50:18  11cea3feb617: Preparing
2025-03-15 17:50:18  c2798c8f24d6: Preparing
2025-03-15 17:50:18  db2ef8a8a54e: Preparing
2025-03-15 17:50:18  5c7b138ff6a8: Preparing
2025-03-15 17:50:18  fa052c8ec46b: Preparing
2025-03-15 17:50:18  3ddd373c9e01: Preparing
2025-03-15 17:50:18  3c8879ab2cf2: Preparing
2025-03-15 17:50:18  db2ef8a8a54e: Waiting
2025-03-15 17:50:18  5c7b138ff6a8: Waiting
2025-03-15 17:50:18  fa052c8ec46b: Waiting
2025-03-15 17:50:18  3ddd373c9e01: Waiting
2025-03-15 17:50:18  3c8879ab2cf2: Waiting
2025-03-15 17:50:18  95aae4bf0704: Layer already exists
2025-03-15 17:50:18  6639ad0972bc: Layer already exists
2025-03-15 17:50:18  11cea3feb617: Layer already exists
2025-03-15 17:50:18  c2798c8f24d6: Layer already exists
2025-03-15 17:50:18  fa052c8ec46b: Layer already exists
2025-03-15 17:50:18  3ddd373c9e01: Layer already exists
2025-03-15 17:50:18  db2ef8a8a54e: Layer already exists
2025-03-15 17:50:18  5c7b138ff6a8: Layer already exists
2025-03-15 17:50:18  3c8879ab2cf2: Layer already exists
2025-03-15 17:50:18  f392f006c0fa: Pushed
2025-03-15 17:50:18  master-20250315-1f0345a: digest: sha256:29addda92162e51f606f37749f24d28fe278203db782722995a472c263147fa0 size: 2413
2025-03-15 17:50:18  [Pipeline] echo
2025-03-15 17:50:18  Pushed Docker Image [TAG]: xxx.xx.xx.xxx:12300/saas-cloud-job-service/cloud-job:master-20250315-1f0345a
2025-03-15 17:50:18  [Pipeline] }
2025-03-15 17:50:18  [Pipeline] // withDockerRegistry
2025-03-15 17:50:18  [Pipeline] }
2025-03-15 17:50:18  [Pipeline] // script
2025-03-15 17:50:18  [Pipeline] }
2025-03-15 17:50:18  [Pipeline] // stage
2025-03-15 17:50:18  [Pipeline] stage
2025-03-15 17:50:18  [Pipeline] { (Deploy project)
2025-03-15 17:50:18  [Pipeline] echo
2025-03-15 17:50:18  Publishing project
2025-03-15 17:50:18  [Pipeline] }
2025-03-15 17:50:18  [Pipeline] // stage
2025-03-15 17:50:18  [Pipeline] stage
2025-03-15 17:50:18  [Pipeline] { (Declarative: Post Actions)
2025-03-15 17:50:18  [Pipeline] echo
2025-03-15 17:50:19  This pipeline will always run, begin cleaning workspace.
2025-03-15 17:50:19  [Pipeline] cleanWs
2025-03-15 17:50:19  [WS-CLEANUP] Deleting project workspace...
2025-03-15 17:50:19  [WS-CLEANUP] Deferred wipeout is used...
2025-03-15 17:50:19  [WS-CLEANUP] done
2025-03-15 17:50:19  [Pipeline] echo
2025-03-15 17:50:19  The pipeline succeeded.
2025-03-15 17:50:19  [Pipeline] }
2025-03-15 17:50:19  [Pipeline] // stage
2025-03-15 17:50:19  [Pipeline] }
2025-03-15 17:50:19  [Pipeline] // withEnv
2025-03-15 17:50:19  [Pipeline] }
2025-03-15 17:50:19  [Pipeline] // node
2025-03-15 17:50:19  [Pipeline] End of Pipeline
2025-03-15 17:50:19  Finished: SUCCESS

日志 第9行: Stage : (Pull code) 拉取代码 ,检出分支

日志 第37行: [Pipeline] { (Build project) 构建项目

日志 第101行: [Pipeline] { (Push Docker image) 开始推送镜像

日志 第153行: [Pipeline] { (Deploy project) 开始发布部署 ,这里Pipeline 没有写任何东西,因为后面我们会把Image 发布到 K8S 上。

日志 第159行: [Pipeline] { (Declarative: Post Actions) 构建后的处理工作,清理工作空间等

日志 第174行: [Pipeline] End of Pipeline , 完成了整个构建

这就是一个完整的构建流程,当然还有一些细节 优化,比如错误重试,任务超时时间等一些功能。

总结

本来从零到一使用Jenkins 如何构建项目,熟悉整个Pipeline 流程 。

分享快乐,留住感动. '2025-03-15 19:05:37' --frank
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值