K8S部署Java项目(Gitlab CI/CD自动化部署终极版)
天行健,君子以自强不息;地势坤,君子以厚德载物。
每个人都有惰性,但不断学习是好好生活的根本,共勉!
文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。
文章目录
- 一、平台搭建
- 1. `K8S`搭建
- 2. `Gitlab`代码仓库部署
- 3. `Gitlab Runner`执行工具部署
- 4. `Harbor`镜像仓库部署
- 4.1 部署Harbor
- 4.2 创建仓库项目
- 二、`Java Springboot`项目上传到Gitlab
- 1. 项目demo获取
- 2. pom配置
- 3. Dokcerfile和.gitlab-ci.yml配置
- 4. Dokcerfile和.gitlab-ci.yml拓展信息
- 4.1 Dockerfile文件配置
- 4.2 .gitlab-ci.yml文件配置
- 5. 上传项目到Gitlab
- 三、CI功能打包、构建镜像
- 1. 流程介绍
- 2. 打包阶段
- 3. 构建镜像阶段
- 4. Harbor查看镜像
- 四、部署镜像(项目)
- 1. yaml文件配置
- 2. 将文件上传到服务器
- 3. 创建命名空间
- 4. 部署yaml文件
- 4.1 部署pvc
- 4.2 部署deploy
- 4.3 部署svc
- 5. 查看服务
- 5.1 查看pvc
- 5.2 查看deploy
- 5.3 查看svc
- 5.4 查看pod
- 5.5 查看logs
- 5.6 查看describe
- 五、访问验证
- 1. 服务所在节点IP
- 2. deploy配置的端口
- 3. Java项目接口URL
- 4. 完整访问URL
- 5. 访问服务接口
- 5.1 curl访问
- 5.2 浏览器访问
- 六、拓展(尚未成功,继续研究,仅供参考)
- 1. 配置Ingress
- 2. 访问服务
- 七、报错汇总
- 1. pod启动失败的查看命令
- 2. 报错内容汇总
一、平台搭建
在K8S集群中,配合Gitlab、Harbor实现自动化部署Java springboot服务
首先需要搭建K8S集群、Gitlab及Gitlab Runner、Harbor,如已部署或有相同平台可忽略
1. K8S
搭建
首先你要有一个K8S集群,如已搭建可跳过,没有可以参考链接搭建
K8S搭建(centos)完整版
k8s搭建(ubuntu)详细演示完整一篇
2. Gitlab
代码仓库部署
用于管理项目代码和使用CI自动化工具
如已有可用环境可忽略,如无可参考安装使用
K8S部署GitLab(详细完整版)
3. Gitlab Runner
执行工具部署
用于执行自动化脚本实现自动化打包、构建镜像等操作
如已有可用环境可忽略,如无可参考安装使用
gitlab runner 安装、注册、配置、使用(Docker部署)
4. Harbor
镜像仓库部署
4.1 部署Harbor
用于存储自动化构建的镜像,后续部署服务会从仓库拉取
如已有可用环境可忽略,如无可参考安装使用
K8S部署Harbor镜像仓库(含离线安装包harbor-offline-installer国内下载链接)
K8S部署Harbor(三部曲之一:配置)
K8S部署Harbor(三部曲之二:部署)
K8S部署Harbor(三部曲之三:使用)
4.2 创建仓库项目
创建harbor镜像仓库项目用于存放推送的项目镜像,项目名为k8s-demo
二、Java Springboot
项目上传到Gitlab
需要提前准备好Java项目,并上传到Gitlab代码仓库
1. 项目demo获取
如果没有现成的springboot项目可以从下面链接获取
下载:Java项目-基于Gitlab CI/CD功能实现自动化部署(在k8s中部署)
其中主要包含了如下文件:
- 一个简单的请求接口用于后续验证部署是否成功
- 构建镜像用的
Dockerfile
配置文件,构建项目镜像使用的文件 - Gitlab的
.gitlab-ci.yml
配置文件,该文件用于执行自动化部署脚本等操作 - 后续部署需要用到的yaml文件
sb-pvc.yaml、sb-dplm.yaml、sb-svc.yaml
、以及配置域名的sb-igs.yaml
- 一些Java项目相关的文件
项目截图:
2. pom配置
需要在pom中添加maven插件依赖、maven插件并定义jar包名称(需要与springboot版本保持一致)
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.6.3</version></dependency></dependencies><build><!--配置后最终生成的jar包名称就是该元素中的名称指定package打包后生成的jar包文件名称为app.jar,package打包后会在target文件夹中看到app.jar文件--><finalName>app</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.6.3</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
3. Dokcerfile和.gitlab-ci.yml配置
可根据Java项目情况参考文章配置这两个文件的内容
我是用的两个文件的模板连接如下:
三个都一样,推荐使用第一个
Dockerfile和.gitlab-ci.yml文件模板(标准版)
Dockerfile和.gitlab-ci.yml文件模板(精简无注释)
Dockerfile和.gitlab-ci.yml文件模板(含详细注释)
4. Dokcerfile和.gitlab-ci.yml拓展信息
下面是拓展介绍,可忽略
4.1 Dockerfile文件配置
Dockerfile文件配置参考:Dockerfile文件参数配置和使用
4.2 .gitlab-ci.yml文件配置
.gitlab-ci.yml文件配置参考:.gitlab-ci.yml文件参数配置和使用
.gitlab-ci.yml文件参数汇总及解释参考:.gitlab-ci.yml文件参数
5. 上传项目到Gitlab
配置文件配置好之后就可以将项目上传到Gitlab代码仓库中了
可参考下方链接文章,虽然是gitee但与gitlab相似
通过GIT将本地项目上传到gitee
当然前面搭建Gitlab的文章中也有介绍如何上传本地项目到Gitlab
三、CI功能打包、构建镜像
在上面我们将代码上传到Gitlab上以后即可触发CI/CD流程
1. 流程介绍
Gitlab检测到.gitlab-ci.yml文件会调用Gitlab Runner执行该文件中的脚本,进行流程化作业部署
执行过程会根据yml文件中的阶段进行,流程如下:
- 打包
- 构建镜像
- 将镜像推送到镜像仓库
- 在主节点服务器中执行kubectl命令(即部署yaml文件)部署项目
- 后续更新镜像,yaml文件会根据镜像地址拉取新的镜像,实现服务自动部署
提交即部署,体验还不错
接下来是在gitlab中自动执行的操作
2. 打包阶段
job1_package执行过程
准备docker执行器—准备环境—仓库资源拉取—执行job的脚本—开始jar打包—下载依赖—打包完成
此处省略下载过程(略长)。。。。。。
job中的脚本执行完毕后会输出Job succeed
表示这个job已经执行结束
3. 构建镜像阶段
job2_build执行过程
构建镜像阶段:先用docker命令登录harbor仓库–通过Dockerfile文件构建镜像放到本地—推送到harbor镜像仓库—删除本地镜像
构建镜像阶段任务完成
表示构建镜像并推送成功
4. Harbor查看镜像
此时可以到harbor镜像仓库中查看是否成功上传,可以看到已经存在
到此表示gitlabCI任务的打包、构建镜像两个阶段结束
以上两个阶段为gitalb自动化执行的文件脚本,接下来看需要部署yaml文件,但部署yaml只需要一次,后续更新镜像后会自动部署
四、部署镜像(项目)
根据Java项目情况配置三个yaml文件,其中deploy的yaml文件中镜像的拉取地址为上面自动化构建后推送的镜像仓库地址
1. yaml文件配置
可参考文章配置三个yaml文件用于部署Java项目:K8S部署Java项目的yaml配置文件模板
2. 将文件上传到服务器
需要将yaml文件上传到集群中的节点服务器中,我这里是可执行kubectl命令的主节点k8s-master
放到自己创建的文件夹springboot-yaml中
3. 创建命名空间
在主节点k8s-master中执行kubectl命令
创建命名空间用于管理部署的服务
kubectl create namespace ns-sb
查看所有命名空间
kubectl get namespace -A
4. 部署yaml文件
依次部署pvc文件、deploy文件、svc文件
4.1 部署pvc
kubectl apply -f springboot-yaml/sb-pvc.yaml
4.2 部署deploy
kubectl apply -f springboot-yaml/sb-dplm.yaml
4.3 部署svc
kubectl apply -f springboot-yaml/sb-svc.yaml
5. 查看服务
以下查看命令都可尝试在最后加上-o wide参数来查看更为详细的信息
注:由于部署过程中出现了很多问题,所以会删除部署的服务重新部署,截图中有些服务名称变了,请忽略该细节,最终的结果是成功的。然后遇到的问题也都总结在最后一章了,如遇到类似可供参考
5.1 查看pvc
kubectl get pvc -n ns-sb
刚开始时Pending
绑定后是Bound
5.2 查看deploy
kubectl get deployment -n ns-sb
5.3 查看svc
kubectl get svc -n ns-sb
5.4 查看pod
kubectl get pod -n ns-sb
还可以加-o wide参数来查看pod所在节点以及集群ip
kubectl get pod -n ns-sb -o wide
5.5 查看logs
查看pod的logs日志
kubectl logs sb-dplm-898c9564-v8nq7 -n ns-sb
5.6 查看describe
查看pod的describe描述
kubectl describe pod sb-dplm-898c9564-v8nq7 -n ns-sb
五、访问验证
部署完成后,进行访问(如果从节点未配置kubectl命令执行权限则需要再主节点进行操作)
IP+端口+接口请求
1. 服务所在节点IP
需要先确定我们部署的项目pod所在的服务器是哪个(可使用第四章3.5.4小节查看pod的第二个命令进行查看)
如查看我的pod所在位置为k8s-worker2节点,该节点的iP为173.33.0.222
2. deploy配置的端口
我们在部署的deploy配置文件中配置的端口参数即nodePort值为30089
3. Java项目接口URL
最后是我们Java项目的接口请求url为test/java
4. 完整访问URL
所以我们访问的url为
173.33.0.222:30089/test/java
5. 访问服务接口
5.1 curl访问
可在命令窗口通过curl执行get请求(接口注解为@GetMapping)
curl 173.33.0.222:30089/test/java
如图输出我们返回的内容就表示服务可正常访问,表示springboot在k8s中部署成功
5.2 浏览器访问
也可通过浏览器访问
173.33.0.222:30089/test/java
输出返回内容表示服务正常,部署成功
六、拓展(尚未成功,继续研究,仅供参考)
通常只有开发测试环境才会使用nodePort方式访问,生产环境需要使用更为安全的访问方法(LoadBalncer或者配置ingress)
我们配置ingress使用自己定义的域名进行访问
1. 配置Ingress
和sb-pvc.yaml、sb-dplm.yaml、sb-svc.yaml放在同一位置,我们可以直接使用vim命令创建并编辑Ingress文件
vim springboot-yaml/sb-igs.yaml
依旧可参考K8S部署Java项目的yaml配置文件模板中的ingress配置文件进行编辑,保存后部署
2. 访问服务
部署后可使用定义的域名进行访问
hs.sb.com/test/java
七、报错汇总
1. pod启动失败的查看命令
如果pod启动状态有问题,可执行以下两个命令进行检查
查看pod描述信息
kubectl describe pod podname -n namespacename
如
kubectl describe pod sb-dplm-898c9564-qm425 -n ns-sb
查看pod日志信息
kubectl logs podname -n namespacename
如
kubectl logs sb-dplm-898c9564-qm425 -n ns-sb
2. 报错内容汇总
以下为整个过程中遇到的问题以及解决方法,供大家参考,希望有所帮助
- /usr/bin/bash: line 136: docker:command not found
Gitlab CI/CD docker命令报错:/usr/bin/bash: line 136: docker:command not found - ERROR: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker running?
Gitlab CI/CD ERROR: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker running? - error during connect: Post http://docker:2375/v1.40xxxxxx: dial tcp: lookup docker o
Gitlab CI/CD报错: error during connect: Post http://docker:2375/v1.40xxxxxx: dial tcp: lookup docker o - ERROR: error during connect : Get “http://docker:2375/_ping“: dial tcp:lookup docker on 10
Gitlab CI ERROR: error during connect : Get “http://docker:2375/_ping“: dial tcp:lookup docker on 10 - /usr/bin/bash: line 137: kubectl: command not found
Gitlab CI 报错: /usr/bin/bash: line 137: kubectl: command not found - Error: Unable to access jarfile app.jar
K8S部署Java项目 pod的logs报错为:Error: Unable to access jarfile app.jar - Error: A JNI error has occurred, please check your installation and try again
Error: A JNI error has occurred, please check your installation and try again - CrashLoopBackOff
K8S部署Java项目(Springboot项目)pod状态:CrashLoopBackOff - cannot access org.springframework.context.ConfigurableApplicationContext bad class file: /root/.m2/r
cannot access org.springframework.context.ConfigurableApplicationContext bad class file: /root/.m2/r - no main manifest attribute, in app.jar
no main manifest attribute, in app.jar - no main manifest attribute, in app.jar备用方案,请现尝试上一个再用这个
K8S部署Java项目 pod报错 logs日志内容:no main manifest attribute, in app.jar
感谢阅读,祝君暴富!
相关文章:

K8S部署Java项目(Gitlab CI/CD自动化部署终极版)
天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…...

对Redis锁延期的一些讨论与思考
上一篇文章提到使用针对不同的业务场景如何合理使用Redis分布式锁,并引入了一个新的问题 若定义锁的过期时间是10s,此时A线程获取了锁然后执行业务代码,但是业务代码消耗时间花费了15s。这就会导致A线程还没有执行完业务代码,A线程…...

【高德地图】Android高德地图初始化定位并显示小蓝点
📖第3章 初始化定位并显示小蓝点 ✅第1步:配置AndroidManifest.xml✅第2步:设置定位蓝点✅第3步:初始化定位✅完整代码 ✅第1步:配置AndroidManifest.xml 在application标签下声明Service组件 <service android:n…...

继电器测试中需要注意的安全事项有哪些?
继电器广泛应用于电气控制系统中的开关元件,其主要功能是在输入信号的控制下实现输出电路的断开或闭合。在继电器测试过程中,为了确保测试的准确性和安全性,需要遵循一定的安全事项。以下是在进行继电器测试时需要注意的安全事项:…...

Java向ES库中插入数据报错:I/O reactor status: STOPPED
Java向ES库中插入数据报错:java.lang.IllegalStateException: Request cannot be executed; I/O reactor status: STO 一、问题问题原因 二、解决思路 一、问题 在使用Java向ES库中插入数据时,第一次成功插入,第二次出现以下错误:…...
vue3实现页面跳转
有需求是在vue项目中实现点击按钮完成页面跳转。这里不适用a标签,而是用vue自带的vue-router。 首先看一下项目结构 src │ App.vue │ main.js │ ├─router │ index.js │ └─views index.vue content.vue 可以看到&…...

【Linux运维系列】vim操作
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Centos服务器部署前后端项目
目录 准备工作1. 准备传输软件2. 连接服务器 部署Mysql1.下载Mysql(Linux版本)2. 解压3. 修改配置4. 启动服务另一种方法Docker 部署后端1. 在项目根目录中创建Dockerfile文件写入2. 启动 部署前端1. 在项目根目录中创建Dockerfile文件写入2. 启动 准备工作 1. 准备传输软件 …...

【初始RabbitMQ】延迟队列的实现
延迟队列概念 延迟队列中的元素是希望在指定时间到了之后或之前取出和处理消息,并且队列内部是有序的。简单来说,延时队列就是用来存放需要在指定时间被处理的元素的队列 延迟队列使用场景 延迟队列经常使用的场景有以下几点: 订单在十分…...
spark为什么比mapreduce快?
spark为什么比mapreduce快? 首先澄清几个误区: 1:两者都是基于内存计算的,任何计算框架都肯定是基于内存的,所以网上说的spark是基于内存计算所以快,显然是错误的 2;DAG计算模型减少的是磁盘I/O次数&…...

Unity通过XXpermission插件获取MANAGE_EXTERNAL_STORAGE权限
最近公司准备用Unity做一个安卓端的文件管理器功能,文件管理器已经做完了。刚开始的时候想要申请一下所有文件权限,发现在Unity里面申请所有文件权限(android.permission.MANAGE_EXTERNAL_STORAGE)相对来说比较麻烦。所以准备写一下文章记录一下如何申请…...
「连载」边缘计算(二十一)02-26:边缘部分源码(源码分析篇)
(接上篇) DeviceTwin struct组成剖析 该部分对DeviceTwin struct的组成进行剖析。接着devicetwin struct调用链剖析的实例化DeviceTwin struct(dt : DeviceTwin{})往下剖析,进入DeviceTwin struct的定义,…...

Unity(第四部)新手组件
暴力解释就是官方给你的功能;作用的对象上面如: 创建一个球体,给这个球体加上重力 所有物体都是一个空物体,加上一些组件才形成了所需要的GameObject。 这是一个空物体,在Scene场景中没有任何外在表现,因为…...
【JS】【Vue3】【React】获取鼠标位置的方法:JavaScript、Vue 3和React示例
目录 使用JavaScript原生方法在Vue 3中获取鼠标位置在React中获取鼠标位置 随着Web应用程序的复杂性不断增加,获取用户交互信息变得越来越重要。其中,获取鼠标位置是一项常见的任务,可以用于实现各种交互效果,如拖拽、悬停提示等。…...

[Docker 教学] 常用的Docker 命令
Docker是一种流行的容器化技术。使用Docker可以将数据科学应用程序连同代码和所需的依赖关系打包成一个名为镜像的便携式工件。因此,Docker可以简化开发环境的复制,并使本地开发变得轻松。 以下是一些必备的Docker命令列表,这些命令将在你下一…...

小程序应用、页面、组件生命周期
引言 微信小程序生命周期是指在小程序运行过程中,不同阶段触发的一系列事件和函数。这一概念对于理解小程序的整体架构和开发流程非常重要。本文将介绍小程序生命周期的概念以及在不同阶段触发的关键事件,帮助开发者更好地理解和利用小程序的生命周期。 …...

Springboot中如何记录好日志
Springboot中如何记录日志 日志体系整体介绍 日志一直在系统中占据这十分重要的地位,他是我们在系统发生故障时用来排查问题的利器,也是我们做操作审计的重要依据。那么如何记录好日志呢?选择什么框架来记录日志,是不是日志打越…...
vm 虚拟机中ubuntu环境配置共享文件夹的方式
1. 在虚拟机设置中启用共享文件夹选项,映射到Windows中具体的目录。 2. 启动虚拟机。 3. 挂在cd #查看cd设备文件 sudo blkid#创建挂载点 sudo mkdir -p /media/cdrom#挂载cd sudo mount /dev/sr0 /media/cdrom#卸载cd sudo umount /media/cdrom 4. 执行完挂载后…...

EMQX Enterprise 5.5 发布:新增 Elasticsearch 数据集成
EMQX Enterprise 5.5.0 版本已正式发布! 在这个版本中,我们引入了一系列新的功能和改进,包括对 Elasticsearch 的集成、Apache IoTDB 和 OpenTSDB 数据集成优化、授权缓存支持排除主题等功能。此外,新版本还进行了多项改进以及 B…...

安全架构设计理论与实践
一、考点分布 安全架构概述(※※)安全模型(※※※)信息安全整体架构设计网络安全体系架构设计区块链技术(※※) 二、安全架构概述 被动攻击:收集信息为主,破坏保密性 主动攻击&#…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

如何更改默认 Crontab 编辑器 ?
在 Linux 领域中,crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用,用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益,允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...

从数据报表到决策大脑:AI重构电商决策链条
在传统电商运营中,决策链条往往止步于“数据报表层”:BI工具整合历史数据,生成滞后一周甚至更久的销售分析,运营团队凭经验预判需求。当爆款突然断货、促销库存积压时,企业才惊觉标准化BI的决策时差正成为增长瓶颈。 一…...
Linux信号保存与处理机制详解
Linux信号的保存与处理涉及多个关键机制,以下是详细的总结: 1. 信号的保存 进程描述符(task_struct):每个进程的PCB中包含信号相关信息。 pending信号集:记录已到达但未处理的信号(未决信号&a…...