CICD Jenkins实现Pipline

一、安装

1、由于 Jenkins 是基于 Java 的,首先需要确保你的系统中安装了 Java。推荐使用 OpenJDK 11。可以通过以下命令安装:

shell 复制代码
apt update
apt install openjdk-11-jdk

2、在安装 Jenkins 之前,你需要将其仓库添加到你的系统中。首先,导入 Jenkins 仓库的密钥:

shell 复制代码
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -

3、然后,将 Jenkins 仓库添加到系统的软件源列表:

shell 复制代码
sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

4、安装jenkins

shell 复制代码
apt update
apt-get install jenkins

5、配置清华源

https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

6、安装中文插件
Localization: Chines

安装后需要重启

shell 复制代码
systemctl restart jenkins

二、配置jenkins

1、安装Git、Git client插件、Docker Pipeline、Pipeline、Blue Ocean、Pipeline: Stage View、user build vars

Pipeline: Stage View这个插件我很推荐,感觉比Blue好用

user build vars pipline调用内置变量,用户名和分支较为常用

2、生成公钥免密拉取代码

shell 复制代码
# 运行jenkins的用户执行
ssh-keygen -t rsa -b 4096 -C "baga@baga.com"
公钥添加到jenkins用户中(服务运行账户就是jenkins)
私钥添加到jenkins凭据中,jenkins任务需要指定凭据运行

3、测试jenkins

shell 复制代码
运行jenkins的用户执行
$ ssh -p 2222 git@192.168.31.20
PTY allocation request failed on channel 0
Welcome to GitLab, @jenkins!
# 到这里基本可以确定jenkins ssh gitlab没问题

4、添加凭据,选择ssh用户名和私钥

5、选择凭据登录git仓库

6、修改jenkins目录

shell 复制代码
# 启动脚本必须修改
vim /lib/systemd/system/jenkins.service
Environment="JENKINS_HOME=/data/jenkins"
WorkingDirectory=/data/jenkins
vim /etc/default/jenkins
JENKINS_HOME=/data/$NAME
# 拷贝文件
rsync -avzh /var/lib/jenkins/ /data/jenkins/
# 然后重启jenkins

三、Jenkins DOCKERFILE

文件/data/Dockerfile-tmp,给容器一个基础的Dockerfile去构建镜像

yaml 复制代码
FROM golang:1.19-alpine AS builder
WORKDIR /app
# 设置代理
ENV HTTP_PROXY http://192.168.31.115:1070
ENV HTTPS_PROXY http://192.168.31.115:1070
COPY . /app
# 只有当 go.mod 不存在时才初始化模块
RUN if [ ! -f go.mod ]; then go mod init yourmodule.com/m; fi
RUN go mod tidy
# 构建应用程序
RUN go build -o {{APP_NAME}}

# 使用 alpine 镜像作为运行环境
FROM alpine:latest

# 设置工作目录
WORKDIR /app

# 从构建器镜像中复制编译好的应用程序
COPY --from=builder /app/{{APP_NAME}} .

# 暴露端口
EXPOSE 8080

# 设置启动命令
CMD ["./{{APP_NAME}}"]

四、Pipline测试

控制台可以看到构建人和分支

由于是jenkins用户运行的jenkins服务,所以需要用jenkins用户去docker login baga仓库,这样pipeline中就不需要再配置用户名密码了

go 复制代码
pipeline {
    agent any  // 在任何可用的代理上运行

    environment {
        APP_NAME = "${env.JOB_NAME}"  // 应用名称设置为当前 Jenkins 作业的名称
        GIT_REPO = "ssh://git@192.168.31.20:2222/root/${APP_NAME}.git"  // Git 仓库地址
        STAGE_SUCCESS = "true"  // 跟踪整个 Pipeline 的成功状态
        IMAGE_TAG = "${APP_NAME}:${sh(returnStdout: true, script: 'date +%Y%m%d-%H%M').trim()}"  // 创建镜像标签,包含日期和时间
        SKIP_PUSH = "false"  // 动态控制是否推送镜像到仓库
        CONTAINER_PORT = "8080"  // 定义容器端口
        HOST_PORT = "8888"  // 定义宿主机映射端口
        PUSH_URL = "harbor.baga.live/base"  // 推送的仓库URL
    }

    stages {
        stage('Setup') {
            steps {
                script {
                    // 使用插件提供的变量设置构建描述
                    wrap([$class: 'BuildUser']) {
                        env.BUILD_USER_ID_SAFE = BUILD_USER_ID
                        currentBuild.displayName = "Build #${BUILD_NUMBER} by ${BUILD_USER_ID}"
                        currentBuild.description = "Initiated by ${BUILD_USER_ID} on branch ${BRANCH}"
                        echo "Build initiated by ${BUILD_USER_ID} on ${BRANCH}"
                    }
                }
            }
        }
        stage('Clean Workspace') {  // 清理工作区阶段
            steps {
                deleteDir()  // 删除工作目录中的所有文件
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('Prepare Environment') {  // 准备环境阶段
            steps {
                script { echo "IMAGE_TAG: ${env.IMAGE_TAG}" }  // 输出当前的镜像标签
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('拉取代码') {  // 拉取代码阶段
            steps {
                script {
                    checkout scm: [
                        $class: 'GitSCM',
                        branches: [[name: "${BRANCH}"]],
                        userRemoteConfigs: [[url: "${env.GIT_REPO}"]]
                    ]
                }
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('Prepare Dockerfile') {  // 准备 Dockerfile 阶段
            steps {
                sh "sed 's/{{APP_NAME}}/${APP_NAME}/g' /data/Dockerfile-tmp > Dockerfile"
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('构建镜像') {  // 构建镜像阶段
            steps {
                script { docker.build("${env.IMAGE_TAG}") }  // 使用 Docker 插件构建镜像
            }
            post {
                failure { script { env.STAGE_SUCCESS = "false" } }  // 如果失败,更新 STAGE_SUCCESS 环境变量
            }
        }
        stage('推送镜像') {
            when { expression { env.STAGE_SUCCESS == "true" && env.SKIP_PUSH == "false" } }
            steps {
                script {
                    sh "docker tag ${IMAGE_TAG} ${PUSH_URL}/${IMAGE_TAG}"
                    sh "docker push ${PUSH_URL}/${IMAGE_TAG}"
                }
            }
            post {
                success {
                    echo "Image pushed successfully to ${PUSH_URL}/${IMAGE_TAG}"
                }
                failure {
                    script { env.STAGE_SUCCESS = "false" }
                    echo "Failed to push the image to ${PUSH_URL}/${IMAGE_TAG}"
                }
            }
        }
        stage('部署测试') {  // 部署测试阶段
            steps {
                sh "docker run -d -p ${HOST_PORT}:${CONTAINER_PORT} --name ${APP_NAME} ${IMAGE_TAG}"
            }
        }
    }
    post {
        always {
            script {
                def buildStatus = (currentBuild.currentResult == 'SUCCESS') ? '成功' : '失败'
                sh "/bin/bash /data/ops/send_lark.sh 'Production' '${JOB_NAME}' '${BRANCH}' '${env.BUILD_USER_ID_SAFE}' '${buildStatus}' '${env.BUILD_URL}'"
            }
        }
    }
}
相关推荐
遨游DATA14 小时前
Jenkins 修改 config.xml 后页面仍是旧配置:让 live job 配置真正生效
ci/cd·jenkins·devops·故障排查·config.xml
Dobby_0515 小时前
【CICD】Jenkins Pipeline 快速学习入门
运维·学习·jenkins
上海安当技术1 天前
统一身份认证平台怎么落地?11 个异构业务系统接入 ASP 的完整实施路径
数据库·servlet·架构·kubernetes·jenkins
回眸不遇2 天前
Elasticsearch嵌套类型nested使用指南
大数据·elasticsearch·jenkins
回眸不遇4 天前
类型的区别和应用场景 nested 每个对象独立存储为隐藏的子文档 适合存储数组 查询的时候有特定的语法 nested查询 且字段要 ...
运维·jenkins
X1A0RAN4 天前
容器化部署 Jenkins 教程
运维·docker·jenkins
BullSmall4 天前
jenkins 全局工具变更后,构建的任务为什么没有刷新过来
运维·jenkins
BullSmall5 天前
报错 libatomic.so.1: No such file or directory
jenkins
ji_shuke5 天前
从零深入:基于 Playwright + Pytest + Allure 的企业级 Web 端到端自动化测试框架实战
前端·自动化测试·docker·jenkins·pytest·allure·playwright
上海安当技术5 天前
老系统零改造接入:旁路代理统一认证实战
java·servlet·架构·kubernetes·jenkins