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

devtools/2025/3/14 18:32:26/

一、项目背景与目标

今天想将本地以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.ppmy.cn/devtools/166762.html

相关文章

C++11语法糖:auto和范围for循环详解

C11语法糖&#xff1a;浅谈auto和范围for循环 C11语法糖&#xff1a;浅谈auto和范围for循环github地址前言一、auto1. C类型系统演进1.1 从C到C的类型困境1.2 typedef的局限性1. const pstring p1;2. const pstring* p2 关键总结对比其他写法核心规则 2. auto关键字的革命性意义…

【MySQL篇】MySQL内置函数

目录 1&#xff0c;日期函数 2&#xff0c;字符串函数 3&#xff0c;数学函数 4&#xff0c;其他函数 实战OJ 1&#xff0c;日期函数 日期类型在之前文章【数据类型】中有描述 传送门&#xff1a;【MySQL篇】数据类型_mysql 数据类型-CSDN博客 函数名称描述current_dat…

Shell编程:深入了解 Bash 数组操作

Bash 脚本是一种强大的工具&#xff0c;广泛用于自动化任务和处理系统管理操作。数组作为 Bash 脚本中的重要数据结构&#xff0c;能够帮助开发人员高效地管理和操作多个值。本文将详细介绍 Bash 数组的创建、访问、修改和常见操作技巧&#xff0c;帮助你在脚本编写中更加得心应…

Maven工具基础知识(一)

第一章、Maven概述 一、概述 官网地址&#xff1a;Welcome to Apache Maven – Maven Maven是一个基于Java的项目管理工具&#xff0c;专注于项目构建、依赖管理和项目信息标准化。其核心目标 是简化开发流程&#xff0c;通过标准化项目结构和自动化构建流程&#xff…

docker拉取 sentinel 并启动

拉取镜像 docker pull bladex/sentinel-dashboard:latest # 默认拉取最新版启动镜像 访问 账号 密码都是默认的 sentinel

用Qt手搓AI助手,挑战24小时开发DeepSeek Assistant!

一、项目需求分析与技术选型 DeepSeekAssistant是一款基于深度求索&#xff08;DeepSeek&#xff09;API的智能对话助手&#xff0c;核心需求包括&#xff1a; 用户界面友好&#xff1a;支持多轮对话展示数据持久化&#xff1a;历史记录存储与检索异步网络通信&#xff1a;AP…

2025年汇丰控股投行业务扩张战略升级版 笔记

2025年汇丰控股投行业务扩张战略升级版 一、战略重构&#xff1a;后疫情时代的全球投行突围战 2025年12月&#xff0c;汇丰控股&#xff08;HSBC Holdings&#xff09;宣布升级其投行业务扩张计划&#xff0c;拟将投资总额从30亿美元提升至35亿美元&#xff0c;并将招聘规模扩…

4.3 数组和集合的初始及赋值

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的 版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商…