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…...
安全架构设计理论与实践
一、考点分布 安全架构概述(※※)安全模型(※※※)信息安全整体架构设计网络安全体系架构设计区块链技术(※※) 二、安全架构概述 被动攻击:收集信息为主,破坏保密性 主动攻击&#…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...
