微服务CI/CD实践(六)Jenkins Docker 自动化构建部署Java微服务

微服务CI/CD实践系列:
 
微服务CI/CD实践(一)环境准备及虚拟机创建
微服务CI/CD实践(二)服务器先决准备
微服务CI/CD实践(三)gitlab部署及nexus3部署
微服务CI/CD实践(四)Jenkins部署及环境配置
微服务CI/CD实践(五)Jenkins + Dokcer 部署微服务前端VUE项目
微服务CI/CD实践(六)Jenkins + Dokcer 部署微服务后端项目
微服务CI/CD实践(七)Minio服务器部署及应用

文章目录

  • 一、先决条件
    • 1.1 服务器先决条件
    • 1.2 项目配置
      • 1.2.1 Dockerfile
      • 1.2.2 pom配置
      • 1.2.3 部署脚本
  • 二、Jenkins构建部署
    • 2.1 创建项目
    • 2.2 配置项目基本信息
    • 2.3 定义 Pipeline script
    • 2.4 构建部署项目
  • 三、其他方式构建部署后端服务
    • 使用Maven构建Docker镜像

后端微服务项目是基于JDK1.8 + SpringCloudAlibaba框架开发,我们通过Jenkins流水线作业将后端工程打包成Docker镜像的方式进行部署。构建部署流程如下:

  • 拉取代码
  • jenkins服务器maven编译代码
  • 使用dockerfile构建镜像并打包镜像
  • 上传镜像包
  • 执行sh

一、先决条件

1.1 服务器先决条件

Jenkins 和 server服务器先决条件参考微服务CI/CD实践(二)服务器先决准备 和 微服务CI/CD实践(四)Jenkins部署及环境配置

1.2 项目配置

后端项目基于maven Dockerfile 构建镜像。

1.2.1 Dockerfile

# docker image deploy
FROM openjdk:8-jdk-alpine
COPY  /uaa-center-server/target/app.jar /app.jarENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev","/app.jar"]

上述配置仅是一个最基本Java工程镜像构建脚本,如果需要集成其他插件需要对应修改脚本
以下示例展示了如何通过Dockerfile集成arshs 和 skywalking:

FROM openjdk:8-jdk-alpine
COPY  /uaa-center-server/target/app.jar /app.jar
# copy arthas
COPY ‐‐from=hengyunabc/arthas:latest /opt/arthas /opt/arthas
# copy skywalking
COPY /uaa-center-server/agent /usr/local/agent
# 这里可以传递skywalking‐agent 配置
ENTRYPOINT [ "sh", "‐c", "java ‐javaagent:/usr/local/agent/skywalking‐agent.jar ‐
Dskywalking.agent.service_name=yourappname ‐
Dskywalking.collector.backend_service=xx.xx.xx.xx:11800 ‐Dspring.profiles.active=dev ‐
jar /app.jar" ]

可以在ENTRYPOINT 端点指定相关agent配置,也可以在docker run执行脚本中指定。

1.2.2 pom配置

后端工程pom添加maven打包依赖:

<build><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot-dependencies.version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version> <!-- 使用与你的 Maven 版本兼容的版本 --><configuration><source>1.8</source><target>1.8</target><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version> <!-- 使用与你的 Maven 版本兼容的版本 --></path><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version></path></annotationProcessorPaths><compilerArgs><arg>-Aprojectlombok.classpath=${project.build.outputDirectory}</arg></compilerArgs></configuration></plugin></plugins></build>

后端工程Dockerfile目录结构如下:
Dockerfile 和 具体的server工程在同级目录
在这里插入图片描述

1.2.3 部署脚本

后端服务和前端服务部署脚本基本一致,也是通过传入动态参数方式执行sh脚本,sh脚本执行步骤解释参考 微服务CI/CD实践(五)Jenkins + Dokcer 部署微服务前端VUE项目 1.2 项目配置。完整的后端部署脚本如下:

#!/usr/bin/env bashecho "param validate"
if [ $# -lt 5 ]; thenecho "you must use like this : /usr/docker-sh/publish_project_name.sh <container_name> <image_name> <version> [portal port] [server port] [portal ssl port] [server ssl port]"  exit  
ficontainer_name="$1"
image_name="$2"
version="$3"
portal_port="$4"
server_port="$5"
if [ "$6" != "" ]; thenportal_ssl_port="$6"
fi
echo "portal_ssl_port=" $portal_ssl_port
if [ "$7" != "" ]; thenserve_sslr_port="$7"
fiecho "执行docker ps"
docker ps
if [[ "$(docker inspect $container_name 2> /dev/null | grep $container_name)" != "" ]];
thenecho $container_name "容器存在,停止并删除"echo "docker stop" $container_namedocker stop $container_nameecho "docker rm" $container_namedocker rm $container_name
elseecho $container_name "容器不存在"
fi
# 删除镜像
echo "执行docker images"
docker images
if [[ "$(docker images -q $image_name 2> /dev/null)" != "" ]];
thenecho $image_name '镜像存在,删除镜像'docker rmi $(docker images -q $image_name 2> /dev/null) --force
elseecho $image_name '镜像不存在'
fi#bak image
echo "bak image" $image_name
BAK_DIR=/opt/bak/docker/$image_name/`date +%Y%m%d`
mkdir -p "$BAK_DIR"
cp "/opt/tmp/$container_name.tar" "$BAK_DIR"/"$image_name"_`date +%H%M%S`.tarecho "docker load" $image_name
docker load --input /opt/tmp/$container_name.tarecho "docker run" $image_name
# 这里因为服务本身还运行了netty,所以需要将netty的端口也做映射,如果没有仅需要配置server_port 
docker run -d -p $portal_port:$server_port -p $portal_ssl_port:$portal_ssl_port --name=$container_name --network=my-network -e TZ="Asia/Shanghai" --restart=always -v ./logs:/usr/local/server-log/uaa-center-server $image_nameecho "remove tmp " $image_name
rm -rf /opt/tmp/$container_name.tarecho "Docker Portal is starting,please try to access $container_name conslone url"

二、Jenkins构建部署

2.1 创建项目

新建一个流水线任务
在这里插入图片描述

2.2 配置项目基本信息

创建完成项目,点击项目进入项目页面,点击左侧菜单》配置,进行项目基本配置
step1 项目构建历史存储策略配置
在这里插入图片描述
这里存储策略根据自己项目要求进行配置。

step2 配置参数化构建过程
Jenkins List Git Branches插件 构建选择指定git分支,点击添加参数选择List Git branchers选项进行Jenkins List Git Branches插件配置
在这里插入图片描述
Jenkins List Git Branches插件配置流程如下:

  • 配置name
  • 配置仓库并选择凭证
  • 选择Parameter Type
  • 配置Branch Filter

2.3 定义 Pipeline script

pipeline {agent anyenvironment {   REPOSITORY="http://192.168.1.101:8929/hka/hkabackgroud/business/uaa-center.git"projectdir="uaa-center-pipeline"projectname="uaa-center-server"apiname="uaa-center-api"}stages {stage('获取代码') {steps {echo "start fetch code from git:${REPOSITORY} ${branch}"deleteDir()checkout([$class: 'GitSCM',branches: [[name: '${branch}']],doGenerateSubmoduleConfigurations: false,extensions: [],userRemoteConfigs: [[credentialsId: '2',url: 'http://192.168.1.101:8929/hka/hkabackgroud/business/uaa-center.git']]])}}stage('替换') {steps {echo "start replace"sh " cd ${WORKSPACE}/${projectname} "sh " rm -f target/${projectname}.jar "sh "mv ${WORKSPACE}/${projectname}/src/main/resources/bootstrap.yml.example ${WORKSPACE}/${projectname}/src/main/resources/bootstrap.yml "sh "mv ${WORKSPACE}/${projectname}/src/main/resources/bootstrap-dev.yml.example ${WORKSPACE}/${projectname}/src/main/resources/bootstrap-dev.yml "}}stage('打包') {steps {echo "start build"withMaven(maven: 'maven3.8.1') {sh " mvn -f ${WORKSPACE}/${apiname}/pom.xml clean deploy -DskipDockerTag -DskipDockerPush  "sh " mvn -f ${WORKSPACE}/${projectname}/pom.xml clean install -DskipDockerTag -DskipDockerPush  "}}}stage('Delete Old Docker Container') {steps {echo "delete docker container"sh '''if [[ "$(docker inspect ${projectname} 2> /dev/null | grep ${projectname})" != "" ]]; then echo ${projectname} "容器存在,停止并删除"echo "docker stop" ${projectname}docker stop ${projectname}echo "docker rm" ${projectname}docker rm ${projectname}else echo ${projectname} "容器不存在"fi'''}}stage('Delete Old Docker Image') {steps {echo "delete docker image"sh '''if [[ "$(docker images -q ${projectname} 2> /dev/null)" != "" ]]; then echo ${projectname} \'镜像存在,删除镜像\'docker rmi $(docker images -q ${projectname} 2> /dev/null) --forceelse echo ${projectname} \'镜像不存在,创建镜像\'fi'''}}stage('Build Docker Image') {steps {echo "start docker build ${projectname} code"sh 'docker build -t ${projectname} .'echo "save docker images tar"sh 'docker save -o ${projectname}.tar ${projectname}'}}stage('Delete New Docker Image') {steps {echo "delete docker image"sh '''if [[ "$(docker images -q ${projectname} 2> /dev/null)" != "" ]]; then echo ${projectname} \'镜像存在,删除镜像\'docker rmi $(docker images -q ${projectname} 2> /dev/null) --forceelse echo ${projectname} \'镜像不存在,创建镜像\'fi'''}}stage('Upload img tar') {steps {sshPublisher(publishers: [sshPublisherDesc(configName: '103',transfers: [sshTransfer(cleanRemote: false,excludes: '',makeEmptyDirs: false,noDefaultExcludes: false,patternSeparator: '[, ]+',remoteDirectory: '',remoteDirectorySDF: false,removePrefix: '',sourceFiles: 'uaa-center-server.tar')],usePromotionTimestamp: false,useWorkspaceInPromotion: false,verbose: false)])}}stage('Execute Command sh') {steps {sshPublisher(publishers: [sshPublisherDesc(configName: '103',transfers: [sshTransfer(execCommand: '/usr/docker-sh/publish_uaa-center-server.sh uaa-center-server uaa-center-server latest 10005 10005 9000 9000',execTimeout: 300000)],usePromotionTimestamp: false,useWorkspaceInPromotion: false,verbose: false)])}}stage('Publish Results') {steps {echo "End Publish ${projectname}"  }}}
}

2.4 构建部署项目

回到项目页面,点击参数化构建,选择用于构建的分支点击Build执行构建任务。
在这里插入图片描述
在这里插入图片描述
当jenkins 流水线执行完成后可到对应Server服务器验证服务是否部署成功

[root@k8s-rancher-node02 ~]# docker ps -a
CONTAINER ID   IMAGE                COMMAND                   CREATED       STATUS        PORTS                                                                                      NAMES
5d65d80b5350   uaa-center-server    "java -jar -Dspring.…"   2 days ago    Up 31 hours   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp, 0.0.0.0:10005->10005/tcp, :::10005->10005/tcp   uaa-center-server

三、其他方式构建部署后端服务

上述基于Jenkins流水线方式部署流程稍显复杂,优势是可以灵活配置构建步骤,特别是对于多环境多服务器的支持更加具有优势,比如通过Jenkins实现本地自动化部署并将镜像推送到AWS云原生平台的测试和生产环境,仅需要添加相应流水线流程即可。

stage('push image to aws ecr') {steps {echo "start push"script {docker.withRegistry('https://xxxx.dkr.ecr.cn-north-1.amazonaws.com.cn', 'ecr:cn-north-1:aws_ecr') {docker.image('${projectname}').push('${BUILD_NUMBER}')}}}}stage('push image to aws ecr us-west-2') {steps {echo "start push"script {docker.withRegistry('https://xxxxx.dkr.ecr.us-west-2.amazonaws.com', 'ecr:us-west-2:aws_us_west_2_ecr') {docker.image('${projectname}').push('${BUILD_NUMBER}')}}}}

如果仅在单环境部署,可以考虑使用Maven构建Docker镜像方式构建镜像,该方式流程简单。

使用Maven构建Docker镜像

step1 应用pom文件添加maven-docker-plugin配置

<plugin><groupId>com.spotify</groupId><artifactId>docker-maven-plugin</artifactId><version>1.1.0</version><executions><execution><id>build-image</id><phase>package</phase><goals><goal>build</goal></goals></execution></executions><configuration><imageName>${project.artifactId}:${project.version}</imageName><dockerHost>http://registry服务器地址:2375</dockerHost><baseImage>openjdk:8-jdk-alpine</baseImage><entryPoint>["java", "-jar","/${project.build.finalName}.jar"]</entryPoint><resources><resource><targetPath>/</targetPath><directory>${project.build.directory}</directory><include>${project.build.finalName}.jar</include></resource></resources></configuration>
</plugin>

配置说明:
executions.execution.phase:此处配置了在maven打包应用时构建docker镜像;
imageName:用于指定镜像名称, p r o j e c t . a r t i f a c t I d 为镜像名称, {project.artifactId}为镜像名称, project.artifactId为镜像名称,{project.version}为仓库版本;
dockerHost:打包后上传到的docker服务器地址;
baseImage:该应用所依赖的基础镜像,此处为java;
entryPoint:docker容器启动时执行的命令;
resources.resource.targetPath:将打包后的资源文件复制到该目录;
resources.resource.directory:需要复制的文件所在目录,maven打包的应用jar包保存在target目录下面;
resources.resource.include:需要复制的文件,打包好的应用jar包。
step2 Jenkins创建项目
Jenkins—》添加Items
根据自己所有选择合适项目类型,这里我们选择Freestyle project,以便我们自定义构建流程。也可以从其他项目copy配置。

step3 配置代码源
在这里插入图片描述
说明:
Repository URL:远程代码仓库地址
Credentials:凭据,可选择已添加的全局凭据,或者在此页面自定义全局凭据
指定分支(为空时代表any):指定项目构建分支
构建触发器:可自定义构建触发,如钩子函数、定时任务等

step4 构建流程配置
这一步是因为项目的配置管理策略有关,本地配置均不提交到服务器,如何没有采用该策略可以忽略
点击增加构建步骤>选择执行shell步骤
在这里插入图片描述

在这里插入图片描述
构建步骤5 使用maven打包构建镜像并推送到server
点击增加构建步骤>选择顶层Maven目标步骤
在这里插入图片描述
在这里插入图片描述
构建步骤6 远程执行shell,部署镜像
点击增加构建步骤>选择远程执行shell步骤
在这里插入图片描述
使用maven-docker-plugin方式构建后端项目流程简单且Jenkins服务器不需要安装额外的Docker,也不需要编写Dokcerfile文件,劣势是无法灵活管理构建步骤。

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

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

相关文章

未来餐饮革命:加入我们的智能餐厅代理、自主开拓市场计划!

系统开发集成商&#xff1a;如果您正在开发智慧餐厅系统&#xff0c;忙于寻找各种消费终端接入、那么我们将可以为您提供整套智慧餐厅系统解决方案&#xff0c;从前厅消费到后厨的明厨亮灶的解决方案。 集团公司&#xff1a;想集团化控制子公司食堂运营&#xff0c;又想以最低…

【LeetCode每日一题】——LCR 168.丑数

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目注意】六【题目示例】七【题目提示】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 优先队列 二【题目难度】 中等 三【题目编号】 LCR 168.丑数 四【题目描述…

【大数据】Hadoop里的“MySQL”——Hive,干货满满

【大数据】Hadoop里的“MySQL”——Hive&#xff0c;干货满满 文章脉络 Hive架构 HQL 表类型 创建表语法 分区 数据导入导出 函数 内置函数 UDF Java Python 在阅读本文前&#xff0c;请确保已经对Hadoop的三大组件&#xff08;HDFS、MapReduce、YARN&#xff09;有…

分布式协调服务--ZooKeeper

文章目录 ZooKeeperzk的由来zk解决了什么问题 ZK工作原理ZK数据模型zk功能1.命名服务2.状态同步3.配置中心4.集群管理 zk部署单机启动zk验证zk zk集群集群角色选举过程1.节点角色状态2.选举ID3.具体过程4.心跳机制5.ZAB协议 ZooKeeper 选举示例1.第一轮投票&#xff1a;2.节点收…

Unity TextMeshPro 设置竖排

默认竖排是这样的 但是我们要的竖排效果并不是这样我们要是竖排连续的根据文本限制来进行换行 第一步我们先设置文本的旋转Z轴为90如下图 然后我们给文本加一个Tag <rotate270> 如下图 但是这个效果还是不是我们想要的效果我们可以使用TexeMeshPro提供的一个选项EnableR…

Python画笔案例-041 绘制正方形阶梯

1、绘制正方形阶梯 通过 python 的turtle 库绘制正方形阶梯&#xff0c;如下图&#xff1a; 2、实现代码 绘制正方形阶梯&#xff0c;以下为实现代码&#xff1a; """正方形阶梯.py """ import turtledef draw_square(length):for _ in range(6…

以太网--TCP/IP协议(一)

概述 以太网是局域网的一种&#xff0c;其他的比如还有令牌环、FDDI。和局域网对应的就是广域网&#xff0c;如Internet&#xff0c;城域网等。 从网络层次看&#xff0c;局域网协议主要偏重于低层&#xff08;业内一般把物理层、数据链路层归为低层&#xff09;。以太网协议…

Qt工程使用MQTT-C库与mqtt服务器数据通信

实现mqtt订阅与发布话题&#xff0c;与mqtt服务器进行数据通信 编译环境&#xff1a;Qt5.15.2 vs2019 需要mqttc库&#xff1a;mqttc.lib, mqttc.dll&#xff08;根据MQTT-C源码编译出来的库&#xff0c;参考cmake编译MQTT-C源码-CSDN博客&#xff09; 一、Qt pro文件编写 …

数据结构C //线性表ADT结构及相关函数

数据结构&#xff08;C语言版&#xff09;严蔚敏 吴伟民 线性表ADT结构及相关函数 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&#xff08;头文件&#xff0c;函数文件&#xff0c;主文件&#xff09; list.h头文件 /****…

LeetCode 2181.合并零之间的节点

题目描述 给你一个链表的头节点 head &#xff0c;该链表包含由 0 分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val 0 。 对于每两个相邻的 0 &#xff0c;请你将它们之间的所有节点合并成一个节点&#xff0c;其值是所有已合并节点的值之和。然后将所有 0 …

浏览器百科:网页存储篇-如何在Chrome中打开IndexedDB窗格(十一)

1.引言 在现代Web开发中&#xff0c;网页存储技术扮演着至关重要的角色。IndexedDB作为一种低级API&#xff0c;允许客户端存储大量结构化数据&#xff0c;并提供高性能的搜索能力。在上一篇文章中&#xff0c;我们深入探讨了IndexedDB的基础知识及其应用场景。为了更有效地调…

安全产品概述

防火墙 防火墙的核心功能是过滤掉有害的流量&#xff0c;在专用网络和公共网络之间建立保护屏障。防火墙过滤通常基于一系列规则&#xff0c;如 IP 地址、域名、协议、端口号、关键字等&#xff0c;对入站和出站的流量进行过滤。这些规则也称为访问控制列表&#xff08;ACCESS…

网络编程day04(UDP、Linux IO 模型)

目录 【1】UDP 1》通信流程 2》函数接口 1> recvfrom 2> sendto 3》代码展示 1> 服务器代码 2> 客户端代码 【2】Linux IO 模型 场景假设一 1》阻塞式IO&#xff1a;最常见、效率低、不耗费CPU 2》 非阻塞 IO&#xff1a;轮询、耗费CPU&#xff0c;可以处…

Spring Boot属性注入的多种方式!

Spring Boot的一个问题&#xff0c;证明你是不是真正的 "会用" Spring boot ?Spring Boot的一个问题&#xff0c;直接暴露你是不是真正使用Spring Boothttps://mp.weixin.qq.com/s?__bizMzkzMTY0Mjc0Ng&mid2247484040&idx1&sn64ad15d95e44c874cc890973…

2024年CCPC网络赛A题题解 —— 军训Ⅰ(gym105336A)

个人认为很唐的一道题&#xff0c;考虑到不少人可能懒得写&#xff0c;我这里给大家发个代码叭&#xff0c;还有一点点题解&#xff08;因为真的不是很难&#xff09;。这是题面&#xff1a; 然后我来讲讲怎么做&#xff0c;不觉得会有多少人题目意思都理解不了叭&#xff1f;这…

码上进阶_刷题模块测试_用例设计

码上进阶_刷题模块测试_用例设计 系统概述&#xff1a; 码上进阶是为程序员专门打造的交流平台&#xff0c;采用主流的微服务框架和C端技术栈作为技术基础。在这个平台上&#xff0c;程序员 可以通过刷题、练习和模拟面试来提升自己的面试能力。 功能测试&#xff1a; 登录…

Linux 常用命令 - tail 【显示文件最后几行内容】

简介 tail 这个命令源自英文单词 “尾巴”&#xff0c;它的主要功能是显示文件的最后几行内容。通过使用 tail&#xff0c;用户可以查看文件的最新添加内容&#xff0c;特别是对于监控日志文件来说非常有用。tail 命令默认显示文件的最后 10 行&#xff0c;但这可以通过参数调…

数学建模_数据预处理流程(全)

数据预处理整体流程图 一般数据预处理流程 处理缺失值&#xff1a;填补或删除缺失值。处理异常值&#xff1a;检测并处理异常值。数据编码&#xff1a;将分类变量进行标签编码或独热编码。数据标准化/归一化&#xff1a;对数据进行标准化或归一化处理。连续变量离散化&#xff…

基于JAVA+SpringBoot+Vue的企业级工位管理系统

基于JAVASpringBootVue的企业级工位管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; …

WinCC 中对 VBS 进行单步执行调试

以前应该写过文章给各位展示如何在WinCC 中通过自身控件对脚本&#xff08;C、VBS&#xff09;进行脚本诊断和排错。但是也有用户反馈说在编写了一些相对复杂的脚本后&#xff0c;WinCC自身控件无法做到单步调试&#xff0c;也会影响脚本的诊断调试效率。如果能够对WinCC 中的脚…