微服务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.丑数 四【题目描述…

uts+uniapp踩坑记录(vue3项目

杂记&#xff1a; web-view方面 内嵌html使用web-view时&#xff0c;直接用 uni.postMessage({data: {action: message // 你要传的信息}}); 示例上写的是用 document.addEventListener(UniAppJSBridgeReady, function() { uni.postMessage({ data: { action: postMe…

nohup与

在 Unix/Linux 系统中&#xff0c;nohup 命令和 & 符号都是用来在后台运行命令的工具&#xff0c;但它们有一些区别。 nohup nohup 命令允许你在终端关闭之后继续运行进程。通常情况下&#xff0c;当你退出终端会话时&#xff0c;正在运行的进程会被挂断&#xff08;SIGH…

【大数据】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.节点收…

以下是分析执行计划中索引使用情况的方法:

一、查看是否使用索引 执行计划通常会明确显示是否使用了索引。如果没有使用索引&#xff0c;可能会看到类似“全表扫描”的描述。例如&#xff1a; “TABLE ACCESS FULL (table_name)”表示对表进行了全表扫描&#xff0c;没有使用索引。 如果使用了索引&#xff0c;会有…

《React Native 应用开发最佳实践》

⭐️React Native 应用开发最佳实践⭐️ 近年来&#xff0c;React Native 应用开发因其能够使用 JavaScript 构建原生移动应用的能力而大受欢迎。它提供了跨平台兼容性、更快的开发时间以及更易于维护的特性&#xff0c;成为了许多开发者的首选。然而&#xff0c;要确保 React…

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…

Flutter函数

在Dart中&#xff0c;函数为 一等公民&#xff0c;可以作为参数对象传递&#xff0c;也可以作为返回值返回。 函数定义 // 返回值 (可以不写返回值&#xff0c;但建议写)、函数名、参数列表 showMessage(String message) {//函数体print(message); }void showMessage(String m…

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

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

【软考】知识产权与标准化

【软考】知识产权与标准化 一.保护范围与对象 1.保护范围与对象 法律法规名称保护对象及范围注意事项著作版权法著作权&#xff0c;文学&#xff0c;绘画&#xff0c;影视等作品1、不需要申请&#xff0c;作品完成即开始保护。2、绘画或摄影作品原件出售(赠予)著作权还归原作…

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的基础知识及其应用场景。为了更有效地调…

C语言 - 断言

C语言 断言 用途 单片机编程中的断言主要有以下几个用途&#xff1a; 错误检测&#xff1a;通过检查程序运行时的状态&#xff0c;确保满足预期条件。如果条件不满足&#xff0c;则可以立即发现并处理潜在的错误。 参数验证&#xff1a;在函数或方法的开始处使用断言来验证输…

安全产品概述

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

HarmonyOS云端开发(三)

文章目录 一、操作数据表增删改查二、注册登录1.验证码注册2.验证码登录 一、操作数据表增删改查 更多方法可查看官方文档 // mine.ets // 云服务sdk import cloud from hw-agconnect/cloud // 数据库文件 可看前几篇文章 import {userInfo} from ../bd/userInfo import …