AI心情日记后端迁移K8s部署全流程

一、项目背景与目标

今天想将本地以java -jar运行的Spring Boot应用(AI心情日记后端)迁移至Kubernetes集群,实现容器化部署和健康管理,顺便再次回顾一下k8s的操作细节。
因为我引入了springAI组件,这个组件需要springboot版本在3.2以上,jdk要17 以上,在部署的过程中遇到了一些问题。


二、引入健康检查模块(Spring Boot Actuator)

1. 添加Maven依赖(pom.xml
<!-- 引入Spring Boot Actuator实现健康检查 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

三、容器化:Dockerfile配置

# 使用轻量级 OpenJDK 19
FROM openjdk:19# 设置工作目录(避免容器内路径冲突)
WORKDIR /app# 复制编译好的 JAR 文件到容器
COPY target/ai-0.0.1-SNAPSHOT.jar app.jar# 启动命令(可添加 JVM 参数优化性能)
ENTRYPOINT ["java", "-jar", "app.jar"]

四、Kubernetes资源配置

1. Deployment配置(deployment.yaml
# 指定 API 版本(不同资源类型对应不同 API 版本)
apiVersion: apps/v1
# 定义资源类型为 Deployment(副本控制器)
kind: Deployment# 元数据部分(定义资源标识)
metadata:# Deployment 对象名称(集群内唯一)name: ai-app# 标签系统(可用于其他资源关联筛选)labels:app: ai-app# 部署规格(核心配置部分)
spec:# 期望的 Pod 副本数量(此处设置为 1,生产环境建议至少 2)replicas: 1# 标签选择器(告诉 Deployment 如何找到要管理的 Pod)selector:matchLabels:# 必须与 template.metadata.labels 完全匹配app: ai-app# Pod 模板(定义具体 Pod 的配置)template:metadata:labels:# Pod 标签(必须与 selector.matchLabels 一致)app: ai-app# Pod 规格(定义容器细节)spec:containers:- name: ai-container  # 容器名称(同一 Pod 内多个容器需唯一)# 镜像地址(需与 docker build 时设置的名称一致)image: xiajing/ai-service:v1.1# 容器端口声明(仅文档作用,实际暴露需配合 Service)ports:- containerPort: 8100  # 此处存在错误,应与应用实际端口一致(见下方说明)# 资源配额管理(关键配置)resources:# 请求资源(调度依据,节点必须满足才能运行)requests:cpu: "1"    # 0.5 核(500m,即 500 毫核)memory: "1Gi"  # 512MB(二进制单位,1Mi=1024^2 bytes)# 资源上限(防止容器耗尽节点资源)limits:cpu: "2"      # 最多使用 1 核memory: "2Gi" # 最多使用 1GB(二进制单位)# 存活探针(失败则重启容器)livenessProbe:httpGet:  # 使用 HTTP GET 请求检测path: /actuator/health/liveness  # 健康检查路径(需应用实现该接口)port: 8100  # 必须与 containerPort 一致,应为 8100initialDelaySeconds: 30  # 容器启动后 30 秒开始探测periodSeconds: 10        # 每 10 秒检测一次timeoutSeconds: 5        # 超时时间(默认 1 秒)failureThreshold: 3      # 连续失败 3 次标记为不健康# 就绪探针(通过后才接收流量)readinessProbe:httpGet:path: /actuator/health/readinessport: 8100  # 同上错误,应改为 8100
2. Service配置(service.yaml
# 指定 API 版本(Service 使用 core/v1)
apiVersion: v1
# 定义资源类型为 Service
kind: Service# 元数据部分
metadata:# Service 名称(集群内唯一标识)name: ai-service# Service 规格(核心配置)
spec:# 标签选择器(选择要代理的 Pod)selector:# 必须与 Deployment 中 Pod 的标签完全匹配app: ai-app  # 需与 Deployment 的标签一致(原配置中是 app: ai-app)# 端口映射规则ports:- protocol: TCP      # 协议类型(支持 TCP/UDP/SCTP)port: 8101           # Service 对外暴露的端口(集群内访问用)targetPort: 8100   # Pod 容器的实际端口(必须与容器端口一致)nodePort: 31000# Service 类型(决定如何暴露服务)type: NodePort         # 可选值:ClusterIP(默认)、NodePort、LoadBalancer

五、执行部署脚本

# 1. 构建并推送镜像
docker build -t your-registry/diary-backend:1.0 .  # 构建镜像
docker push your-registry/diary-backend:1.0        # 推送到镜像仓库# 2. 部署到Kubernetes
kubectl apply -f deployment.yaml  # 创建Deployment
kubectl apply -f service.yaml      # 创建Service# 3. 验证部署状态
kubectl get pods -o wide          # 查看Pod状态和所在节点
kubectl get svc diary-service    # 获取Service的NodePort端口

六、验证服务状态

# 1. 检查Pod是否就绪
kubectl get pods -l app=diary-backend
# 预期输出:READY 1/1,STATUS Running# 2. 查看健康检查日志
kubectl logs <pod-name> | grep 'actuator/health'
# 预期输出:200 OK# 3. 访问服务接口(通过NodePort)
curl http://<节点IP>:31000/api/diary
# 预期输出:JSON格式的日记数据

七、问题与解决:JDK版本升级

1. 错误现象

部署后Pod状态为CrashLoopBackOff,日志报错:

Caused by: java.lang.NullPointerException: Cannot invoke "jdk.internal.platform.CgroupInfo.getMountPoint()"
2. 原因分析
  • JDK 17的局限性jdk.internal.platform模块在部分镜像(如slim)中缺失。
  • 容器环境兼容性:Kubernetes Cgroup v2与JDK 17的兼容性问题。
3. 解决方案
  • 升级JDK到19:使用完整镜像openjdk:19-jdk
  • 更新Dockerfile
    FROM openjdk:19   # 运行阶段JDK 19
    
  • 验证修复
    kubectl rollout restart deployment/diary-backend  # 触发重建Pod
    kubectl get pods -w  # 观察新Pod状态
    

八、总结

通过本流程,我已实现:

  1. 健康检查集成:通过Actuator实现存活/就绪探针。
  2. 容器化优化:多阶段构建减少镜像体积至200MB以下。
  3. K8s生产级配置:资源限制、滚动更新策略、服务暴露。
  4. 版本问题解决:升级JDK 19彻底修复Cgroup兼容性问题。

最终成果:AI心情日记后端稳定运行于Kubernetes集群,可通过http://<节点IP>:31000访问,后面如果有流量增加可以自动弹性伸缩。

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

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

相关文章

海鲜水产行业wordpress外贸主题

模板采用清新的海洋风格设计&#xff0c;完美契合水产和海鲜行业的特点&#xff0c;让您的网站在众多竞争者中脱颖而出。 高质量的图片展示区域&#xff0c;让您可以展示新鲜捕捞的海鲜产品&#xff0c;吸引客户的注意力。 多功能性&#xff0c;满足业务需求&#xff1a; 模…

调优案例一:堆空间扩容提升吞吐量实战记录

&#x1f4dd; 调优案例一&#xff1a;堆空间扩容提升吞吐量实战记录 &#x1f527; 调优策略&#xff1a;堆空间扩容三部曲 # 原配置&#xff08;30MB堆空间&#xff09; export CATALINA_OPTS"$CATALINA_OPTS -Xms30m -Xmx30m"# 新配置&#xff08;扩容至120MB&am…

【大模型系列】llama.cpp本地运行大模型

上一篇链接: 【大模型系列】使用ollama本地运行千问2.5模型 我们讲了ollama本地运行大模型&#xff0c;这里我们介绍另一种本地运行大模型的方法&#xff1a;llamacpp 软件下载 下载地址&#xff1a;https://github.com/ggml-org/llama.cpp/releases 下载cpu版本的llamacpp&a…

maven之自定义插件

写在前面 在使用maven肯定是离不开插件的&#xff0c;比如执行mvn clean或者时mvn compile其实运行的就是绑定的默认插件。虽然我们一般不需要来自定义插件&#xff0c;但是为了使用的过程中更加的清晰&#xff0c;来尝试自定义插件还是很有必要的&#xff0c;所以本文就一起来…

工程实践:如何使用SU17无人机来实现室内巡检任务

阿木实验室最近发布了科研开发者版本的无人机SU17&#xff0c;该无人机上集成了四目视觉&#xff0c;三维激光雷达&#xff0c;云台吊舱&#xff0c;高算力的机载计算机&#xff0c;是一个非常合适的平台用于室内外巡检场景。同时阿木实验室维护了多个和无人机相关的开源项目。…

【瞎折腾/Dify】使用docker离线部署Dify

文章目录 说在前面安装Docker(外网)获取Dify源码(外网)拉取docker镜像(外网)导出镜像(内网)导入镜像(内网)运行问题 说在前面 外网操作系统&#xff1a;windows内网操作系统&#xff1a;ubuntu外网docker desktop版本&#xff1a;4.29.0外网docker版本&#xff1a;version 26.0…

【Git】配置Git

配置Git 忽略特殊文件 在日常开发中&#xff0c;有些文件不想或不应该提交到远端&#xff0c;如保存数据库密码的配置文件。 在Git工作区的根目录下创建一个特殊的.gitignore文件&#xff0c;把要忽略的文件名填进去&#xff0c;Git就会自动忽略这些文件。 不需要从头写.gi…

mysql学习-常用sql语句

1、安装mysql参考网上链接&#xff0c;进入mysql数据库 mysql -u root -p 2、数据库操作 2.1、创建数据库 create database 数据库名 default character set utf8; 2.2、显示所有数据库 show databases; 2.3、选择数据库 use elementInfo; 2.4、删除数据库 drop database…

PostgreSQL16 的双向逻辑复制

一、配置 双向逻辑复制具体步骤 参考:PostgreSQL 16 双向逻辑复制与事务回环控制 - 墨天轮 1. 安装和准备环境 确保在所有参与复制的服务器上都安装了 PostgreSQL 16。主服务器&#xff1a;192.168.0.100从服务器&#xff1a;192.168.0.102 2. 配置 PostgreSQL 在每个服务…

FastAPI复杂查询终极指南:告别if-else的现代化过滤架构

title: FastAPI复杂查询终极指南:告别if-else的现代化过滤架构 date: 2025/3/14 updated: 2025/3/14 author: cmdragon excerpt: 本文系统讲解FastAPI中复杂查询条件的构建方法,涵盖参数验证、动态过滤、安全防护等18个核心技术点。通过引入策略模式、声明式编程等技术,彻…

C++前缀和

个人主页&#xff1a;[PingdiGuo_guo] 收录专栏&#xff1a;[C干货专栏] 大家好&#xff0c;今天我们来了解一下C的一个重要概念&#xff1a;前缀和 目录 1.什么是前缀和 2.前缀和的用法 1.前缀和的定义 2.预处理前缀和数组 3.查询区间和 4.数组中某个区间的和是否为特定…

机器学习基础

目录 泛化误差 偏差和方差 噪声 生成模型和判别模型 正态分布&#xff08;Normal Distribution&#xff09; 超参数选择 Grid Search 网格搜索 Random Search 随机搜索 Hyperopt Hyperas 参数估计方法对比 MLE 最大似然估计 MAP最大后验估计 贝叶斯估计 距…

中山六院团队发表可解释多模态融合模型Brim,可以在缺少分子数据时借助病理图像模拟生成伪基因组特征|顶刊解读·25-02-14

小罗碎碎念 在癌症诊疗领域&#xff0c;精准预测患者预后对临床决策意义重大。传统的癌症分期系统&#xff0c;如TNM分期&#xff0c;因无法充分考量肿瘤异质性&#xff0c;难以准确预测患者的临床结局。而基于人工智能的多模态融合模型虽有潜力&#xff0c;但在实际临床应用中…

系统可观测性(5)OpenTelemetry基础使用

系统可观测性(5)OpenTelemetry基础概念 Author: Once Day Date: 2025年3月12日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 本文档翻译整理自《OpenTelemetry Docs》&a…

OpenHarmony自定义子系统、部件与模块

如图所示&#xff0c;OpenHarmony系统源码中&#xff0c;大体上按照不同种类的功能分成多个子系统&#xff0c;然后一个子系统内部进一步在同类功能上的差异性划分成一个或多个部件&#xff0c;也就是说一个部件表示一个具体功能的源码集合。最后一个部件的源码再划分成一个或多…

【论文笔记】Contrastive Learning for Compact Single Image Dehazing(AECR-Net)

文章目录 问题创新网络主要贡献Autoencoder-like Dehazing NetworkAdaptive Mixup for Feature PreservingDynamic Feature Enhancement1. 可变形卷积的使用2. 扩展感受野3. 减少网格伪影4. 融合空间结构信息 Contrastive Regularization1. 核心思想2. 正样本对和负样本对的构建…

uni-app打包h5并部署到nginx,路由模式history

uni-app打包有些坑&#xff0c;当时运行的基础路径填写了./&#xff0c;导致在二级页面刷新之后&#xff0c;页面直接空白。就只能换一个路径了&#xff0c;nginx也要跟着改&#xff0c;下面是具体步骤。 manifest.json配置web 运行路径写/h5/&#xff0c;或者写你们网站的目…

SQLiteStudio:一款免费开源跨平台的SQLite管理工具

目录 1.简介 2.下载与安装 3.实现分析 4.总结 1.简介 SQLiteStudio 是一款专门用于管理 SQLite 数据库的图形化工具&#xff0c;由波兰开发者开发并维护。由于 SQLite 以其轻量级、零配置、嵌入式等特性被广泛应用于各种小型项目、移动应用和桌面应用中&#xff0c;而 SQLi…

Java入职篇(2)——开发流程以及专业术语

Java入职篇&#xff08;2&#xff09;——开发流程以及专业术语 开发流程 开发术语 测试用例&#xff08;用例&#xff09; 测试人员写的测试方案&#xff0c;基本上就是编写的测试过程&#xff0c;以及测试的预取结果 灰度测试 现在小部分范围内使用&#xff0c;然后逐步…

Figma介绍(基于云的协作式界面设计工具,主要用于UI/UX设计、原型制作和团队协作)

文章目录 注册和登录简单操作说明Figma介绍**核心特点**1. **云端协作与实时同步**2. **跨平台兼容**3. **高效设计工具**4. **原型交互与动效**5. **开发对接友好**6. **插件生态**7. **版本控制与历史记录** **适用场景**- **团队协作**&#xff1a;远程团队共同设计、评审、…