jenkins pipeline实现CI/CD

在企业级的架构中,CI/CD是必不可少的一个环节,它可以让开发人员只关注于开发,而不必去关注项目的构建和部署,从而提高开发人员的效率。

本文我们来介绍一下使用jenkins 的pipeline来进行java项目的自动构建以及部署。我们通过脚本来生成docker镜像,并推送到镜像仓库,供k8s使用。

整体思路是先通过maven构建项目,然后通过build_docker.sh脚本来打包生成镜像,该脚本接收3个参数,-j 需要执行的jar包的名字,-F 项目文件名 -p ,镜像需要推送的环境

根据参数会打包成相应的镜像,并且推送到镜像仓库。

一 基础镜像环境

1 因为是基于springboot的java项目启动项目需要java环境,我们构建一个自己的jdk环境,使用jdk8。

Dockerfile 如下

FROM ubuntu
WORKDIR /usr/local/jdk1.8.0_301
ADD jdk-8u301-linux-x64.tar.gz /usr/local
ENV JAVA_HOME=/usr/local/jdk1.8.0_301
ENV PATH=$JAVA_HOME/bin:$PATH
CMD ["java","-version"]

构建自己的jdk8镜像

docker build -f Dockerfile -t jdk8img .

2 Jenkins我们也通过docker的方式来运行,基于官方jenkins镜像我们加进去自己的jdk版本(因为目前项目大部分使用jdk8,而最新jenkins官方镜像为jdk11),以及使用宿主机的maven,docker环境,来制作一个jenkins镜像。

这里基于官方镜像,这里安装libltdl7是为了运行宿主机docker环境需要。

FROM jenkins/jenkins
ADD jdk-8u301-linux-x64.tar.gz /usr/local
ENV JAVA_HOME=/usr/local/jdk1.8.0_301
ENV PATH=/usr/local/maven/bin:$JAVA_HOME/bin:$PATH
USER root
RUN apt-get update && apt-get install -y libltdl7

    

这里的前提是宿主机提前安装好maven和docker环境,具体安装方式这里就不详细讲述了。

启动jenkins

这里启动命令挂载了宿主机的docker,以及maven目录

docker run --name jenkins -d -v /etc/localtime:/etc/localtime:ro -v /data1/services/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -v /usr/local/maven:/usr/local/maven  -p 8080:8080 -p 50000:50000 --dns=8.8.8.8 jenkins

二 脚本编写

前面我们制作好了各个基础镜像,现在需要编写脚本来将镜像编译打包以及镜像生成,并推送到镜像仓库

我们有4个脚本要编写

1 jenkins pipeline的配置文件Jenkinsfile,这个是jenkins多分支流水线作业必须的配置文件

2 Dockerfile:构建应用镜像的描述文件

3 build_docker.sh:打包镜像的脚本,我们的项目通过maven打包以后,需要按一定规范存放文件,并且执行启动应用的脚本

4 start.sh项目启动的脚本,用于在镜像启动时执行

Jenkinsfile

pipeline {agent anystages {stage('package') {steps {sh 'mvn -Dmaven.test.skip=true -Dmaven.source.skip=true  -am clean package -U'}}stage('Test') {steps {sh './build_docker.sh -j smart4-api-1.0-SNAPSHOT.jar -F smart4-api'sh './build_docker.sh -j smart4-web-1.0-SNAPSHOT.jar -F smart4-web'}}}
}

   Dockerfile

FROM jdk8img
ARG jarfile
RUN rm -f /etc/localtime && ln -sv /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \&& echo "Asia/Shanghai" > /etc/timezoneWORKDIR /data/app/smart4ENV DWPROJECTNO=smart4
ENV EXECJAR=$jarfileADD workspace /data/app/smart4EXPOSE 8081CMD ["sh","-c","shell/start.sh $EXECJAR"]

    build_docker.sh

#!/bin/bash
DOCKER_REGISTRY="harbor.udblogin.87yy.com:4443"
NAMESPACE="yygame"
BASEDIR=$(pwd)
PRONAME=`basename $BASEDIR`
DIRNAME=`dirname  $BASEDIR`
folder=`basename $DIRNAME`
dockerfile="Dockerfile"
product="test"
jarfile=""while getopts "f:F:p:j:" option
docase "$option" inf)dockerfile="$OPTARG";;F)folder="$OPTARG";;p)product="$OPTARG";;j)jarfile="$OPTARG";;\?)usageexit 1;;esac
doneecho "begin copy workspace"
rm -rf $BASEDIR/workspace
mkdir -p $BASEDIR/workspace/web
mkdir -p $BASEDIR/workspace/lib
mkdir -p $BASEDIR/workspace/shell
mkdir -p $BASEDIR/workspace/configfind . -maxdepth 4 -regex ".*/target/[^\/]*.war"  -exec cp -f {} $BASEDIR/workspace/web/ \;
find . -maxdepth 4 -regex ".*/target/[^\/]*.jar"  -exec cp -f {} $BASEDIR/workspace/lib/ \;
cp -Rf  config/* $BASEDIR/workspace/config/
cp ./start.sh $BASEDIR/workspace/shellecho "workspace is ready"echo "begin build docker"timestamp=$(date "+%Y%m%d%H%M%S")echo "build -f $dockerfile -t ${DOCKER_REGISTRY}/${NAMESPACE}/${folder}:$timestamp . --build-arg jarfile=$jarfile"docker build -f $dockerfile -t ${DOCKER_REGISTRY}/${NAMESPACE}/${folder}:$timestamp . --build-arg jarfile=$jarfileecho "docker build done"echo "start push to registry"
docker login --username=yygame harbor.udblogin.87yy.com:4443 -p xxxxxx
if [[ $product == "test" ]];thendocker push ${DOCKER_REGISTRY}/${NAMESPACE}/${folder}:$timestamp
fi
echo "folder $folder"
echo "product $product"
echo "exec jarfile $jarfile"

start.sh 

#!/bin/bash
jarfile=$1
echo "exec $jarfile"
echo "start app"
echo "java -Xss1m -server -d64 -XX:MaxGCPauseMillis=200 -Dnetworkaddress.cache.ttl=600  -Xms256m -Xmx2048m -cp /data/app/smart4/lib/$jarfile org.springframework.boot.loader.JarLauncher"
java -Xss1m -server -d64 -XX:MaxGCPauseMillis=200 -Dnetworkaddress.cache.ttl=600  -Xms256m -Xmx2048m -cp /data/app/smart4/lib/$jarfile org.springframework.boot.loader.JarLauncher

   

三 jenkins新建多分支流水线

新建任务,选择多分支流水线。主要配置git地址,凭据。配置发现分支策略,这里可以按项目代码规范来配置,比如开发版本就过滤掉,因为每次构建都会去打包生成镜像,如果不过滤会构建所有分支的镜像,比较耗时,耗费资源。配置好以后,运行构建,会自动打包并推送镜像到镜像仓库了。

四 构建

我们在jenkins后台选择smart4项目的master分支,点击构建

然后查看构建日志

待构建完成以后,去镜像仓库后台查看镜像仓库是否生成

我们看到已经生成了新的镜像了。整个流程完成。  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/81530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

InfluxDB 3 Core + Java 11 + Spring Boot:打造高效物联网数据平台

一、 引言:为什么选择InfluxDB 3? 项目背景: 在我们的隧道风机监控系统中,实时数据的采集、存储和高效查询是至关重要的核心需求。风机运行产生的振动、倾角、电流、温度等参数是典型的时序数据,具有高并发写入、数据…

泰国SAP ERP实施如何应对挑战?工博科技赋能中企出海EEC战略

泰国正依托"东部经济走廊(EEC)"与RCEP协定叠加优势,为中国企业提供面向亚太市场的战略机遇。作为2022年泰国主要外资来源国之一,中国企业通过电子制造、智能家电、数据中心及新能源车等领域的投资深度参与泰国"4.0…

【设计模式】- 创建者模式

单例模型 饿汉式 静态方法创建对象 public class Singleton {// 私有构造方法private Singleton(){}private static Singleton instance new Singleton();// 提供一个外界获取的方法public static Singleton getInstance(){return instance;} }静态代码块创建对象 public …

逻辑与非逻辑的弥聚

非逻辑弥聚与逻辑弥聚是复杂系统中两种不同的信息整合方式。逻辑弥聚侧重于通过明确的规则、规律和结构化方法,将分散的信息或功能进行有序的组织和集中处理,强调理性和确定性。而非逻辑弥聚则更多地涉及情感、直觉、经验等非线性、非结构化的因素&#…

Linux进程信号(三)之信号产生2

文章目录 4. 由软件条件产生信号5. 硬件异常产生信号模拟一下除0错误和野指针异常除0错误野指针错误 总结思考一下 4. 由软件条件产生信号 SIGPIPE是一种由软件条件产生的信号,在“管道”中已经介绍过了。 软件条件不就绪,很明显这个软件条件没有直接报错&#xff…

读取18B20的问题,时钟太慢了

使用MSP430,1M时钟,在读取18B20数据时,一直存在问题,使用逻辑分析仪读取的数据也是莫名其妙,查看电路图和器件也没有发现问题,就这样断断续续的卡了一周多。 今天忽然想把时钟升一下试试,原来1…

第12章 Java多线程机制

12.1 进程与线程 4种状态:新建、运行、中断和死亡。 (新建、运行、中断和死亡) 建立线程的两种方法:用Thread类或其子类。 线程新建后,必须调用 start () 方法使其进入就绪队列,才有机会获得 CPU 资源&a…

利用 Amazon Bedrock Data Automation(BDA)对视频数据进行自动化处理与检索

当前点播视频平台搜索功能主要是基于视频标题的关键字检索。对于点播平台而言,我们希望可以通过优化视频搜索体验满足用户通过模糊描述查找视频的需求,从而提高用户的搜索体验。借助 Amazon Bedrock Data Automation(BDA)技术&…

React 19版本refs也支持清理函数了。

文章目录 前言一、refs 支持清理函数二、案例演示1.useEffect写法2.React 19改进 的ref写法 总结 前言 React 19版本发布了ref支持清理函数了,这样就可以达到useEffect一样的效果了。为啥需要清理函数呢,这是因为节约内存。 清理事件监听(避…

城市内涝监测预警系统守护城市安全

一、系统背景 城市内涝是指由于强降水或连续性降水超过城市排水能力,导致城市内产生积水灾害的现象。随着气候变化和城市化进程的加快,城市内涝现象愈发频繁和严重。传统的城市排水系统已难以满足当前的城市排水需求,特别是在暴雨等极端天气条…

Flink 作业提交流程

Apache Flink 的 作业提交流程(Job Submission Process) 是指从用户编写完 Flink 应用程序,到最终在 Flink 集群上运行并执行任务的整个过程。它涉及多个组件之间的交互,包括客户端、JobManager、TaskManager 和 ResourceManager。…

ctr查看镜像

# 拉取镜像到 k8s.io 命名空间 sudo nerdctl --namespace k8s.io pull nginx:1.23.4 # 验证镜像是否已下载 sudo nerdctl --namespace k8s.io images 下载镜像到k8s.io名称空间下 nerdctl --namespace k8s.io pull zookeeper:3.6.2 sudo ctr image pull --namespace k8s.io …

中科院自动化研究所通用空中任务无人机!基于大模型的通用任务执行与自主飞行

作者: Ji Zhao and Xiao Lin 单位:中科院自动化研究所 论文标题:General-Purpose Aerial Intelligent Agents Empowered by Large Language Models 论文链接:https://arxiv.org/pdf/2503.08302 主要贡献 硬件-软件协同设计框…

数据结构 -- 树形查找(三)红黑树

红黑树 为什么要发明红黑树 平衡二叉树AVL:插入/删除很容易破坏平衡性,需要频繁调整树的形态。如:插入操作导致不平衡,则需要先计算平衡因子,找到最小不平衡子树(时间开销大),在进行…

容器化-k8s-使用和部署

一、K8s 使用 1、基本概念 集群: 由 master 节点和多个 slaver 节点组成,是 K8s 的运行基础。节点: 可以是物理机或虚拟机,是 K8s 集群的工作单元,运行容器化应用。Pod: K8s 中最小的部署单元,一个 Pod 可以包含一个或多个紧密相关的容器,这些容器共享网络和存储资源。…

力扣-283-移动零

1.题目描述 2.题目链接 283. 移动零 - 力扣&#xff08;LeetCode&#xff09; 3.题目代码 class Solution {public void moveZeroes(int[] nums) {int dest-1;int cur0;while(cur<nums.length){if(nums[cur]0){cur;}else if(nums[cur]!0){swap(nums,cur,dest1);cur;dest…

前端开发笔记与实践

一、Vue 开发规范与响应式机制 1. 组件命名规范 自定义组件使用大驼峰命名法&#xff08;如 MyComponent&#xff09;&#xff0c;符合 Vue 官方推荐&#xff0c;便于与原生 HTML 元素区分。 2. Proxy vs defineProperty 特性Proxy&#xff08;Vue3&#xff09;Object.defi…

如何给PSCAD添加库文件

1、点击Options 2、选择蓝色的选项 3、查看Intel(R) Visual Fortran Compiler XE 的版本 4、打开原文件的Library 5、打开 6、点击这个文件的右键 7、然后选择第一项project setting 9、先把第8步中link里面原有的路径删除&#xff0c;再点browes[A1] &#xff0c;然后选择 [A…

milvus+flask山寨《从零构建向量数据库》第7章case2

继续流水账完这本书&#xff0c;这个案例是打造文字形式的个人知识库雏形。 create_context_db: # Milvus Setup Arguments COLLECTION_NAME text_content_search DIMENSION 2048 MILVUS_HOST "localhost" MILVUS_PORT "19530"# Inference Arguments…

【第一篇】 创建SpringBoot工程的四种方式

简介&#xff1a; 通过此篇博客你可以使用任何方式进行创建 SpringBoot 项目&#xff0c;并且在文章的最后附上答疑解惑一节&#xff0c;为你排除在使用过程中发生的常见问题。文章内容若存在错误或需改进的地方&#xff0c;欢迎大家指正&#xff01;若对操作有任何疑问欢迎留言…