资讯动态

Vue2+Spring Boot 2.5+Nacos 2.0.3 在 K8s 上的前后端分离部署实战

发布时间:2026/10/28 2:51:07 来源:尧图企业网站定制
简介面向需要在阿里云Kubernetes集群上落地前后端分离项目的开发者与运维人员这套资源给出了一套可直接参考的部署组合Vue2前端经Nginx托管SpringBoot2.5后端以Jar形式运行Nacos2.0.3承担注册与配置中心并配套MySQL初始化脚本。资源包共16个文件以8个YAML清单为核心覆盖Nacos的StatefulSet、Service、Headless、Ingress及MySQL配置另有2个Shell部署脚本、2个Dockerfile、1个SQL、1个Nginx配置、1个Jar与1个前端压缩包整体约34.69MB结构上按Nacos与业务应用两条线组织便于对照修改镜像、副本数与存储参数。已有1342人学习下载适合希望理解K8s多组件编排、服务发现与配置外置、前端静态资源容器化等环节的中级读者可据此快速搭建联调环境并梳理部署排错思路。1. 一套能跑通的前后端分离部署链路Vue2 静态资源、Spring Boot 2.5 与 Nacos 2.0.3 在 K8s 上怎么落很多团队第一次把 Vue2 Nginx Spring Boot 2.5 Nacos 2.0.3 往 K8s 上搬卡住的往往不是镜像构建而是三件事前端静态资源怎么进 Nginx、后端怎么在 Pod 里正确连上 Nacos、Nacos 自己怎么在集群里稳定起来。这套组合在中小规模业务里非常常见前端 Vue2 打包成静态文件交给 Nginx 托管后端 Spring Boot 2.5 通过 Nacos 2.0.3 做注册发现和配置中心整体跑在 K8s 上。它适合已经有一套能本地跑通的前后端项目、准备上容器编排的开发者也适合想把部署链路标准化成 YAML 模板的运维同学。下面按「资源怎么组织 → 各组件怎么配 → 坑在哪」的顺序拆开讲每一步都能照着复现。2. 镜像与配置基线三个组件各自的构建策略上 K8s 之前先把三个组件的镜像和配置基线定下来。这一步做扎实后面写 YAML 才不会反复返工。核心原则是前端镜像只装 Nginx 和静态文件后端镜像只装 JRE 和 jarNacos 直接用官方镜像加自定义配置三者互不耦合。2.1 Vue2 前端多阶段构建把 dist 塞进 NginxVue2 项目常见做法是用 Node 构建、Nginx 托管多阶段构建能避免把 node_modules 带进最终镜像。下面这份 Dockerfile 放在前端项目根目录nginx.conf单独维护。# 阶段一构建 Vue2 静态资源 FROM node:16-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm install --registryhttps://registry.npmmirror.com COPY . . RUN npm run build # 阶段二Nginx 托管 dist FROM nginx:1.24-alpine # 清掉默认站点避免和自定义配置冲突 RUN rm -rf /usr/share/nginx/html/* COPY --frombuilder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80逻辑说明第一阶段用 Node 16 构建npm install指定镜像源加速第二阶段只拷贝dist和自定义 Nginx 配置。参数上Node 版本要和项目package.json的 engines 对齐Vue2 项目用 Node 16 比较稳Node 18 以上偶尔会遇到 OpenSSL 相关的构建报错。nginx.conf里要处理 Vue Router 的 history 模式回退否则刷新子路由会 404server { listen 80; server_name _; root /usr/share/nginx/html; index index.html; # history 模式回退找不到文件就回 index.html location / { try_files $uri $uri/ /index.html; } # 后端接口反向代理指向 K8s 内部 Service location /api/ { proxy_pass http://backend-svc:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }proxy_pass末尾带斜杠会把/api/前缀剥掉再转发后端 Controller 就不用再写/api前缀不带斜杠则保留前缀两种写法选一种统一即可混用是接口 404 的高发原因。2.2 Spring Boot 2.5 后端分层 jar 与 JRE 精简镜像Spring Boot 2.5 支持分层 jar配合 Docker 分层缓存能让改代码后的镜像构建快很多。构建时在pom.xml里开启分层plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration layers enabledtrue/enabled /layers /configuration /plugin然后 Dockerfile 用layertools拆层FROM eclipse-temurin:11-jre-alpine WORKDIR /app # 先拷贝分层产物依赖层变化少能命中缓存 COPY target/*.jar app.jar RUN java -Djarmodelayertools -jar app.jar extract COPY --from0 /app/dependencies/ ./ COPY --from0 /app/spring-boot-loader/ ./ COPY --from0 /app/snapshot-dependencies/ ./ COPY --from0 /app/application/ ./ ENTRYPOINT [java, -XX:MaxRAMPercentage75.0, -jar, app.jar]这里有个容易翻车的点COPY --from0引用的是当前阶段写法上更稳妥的是分成两个 FROM 阶段第一个阶段做 extract第二个阶段拷贝。参数-XX:MaxRAMPercentage75.0让 JVM 按容器内存上限的 75% 设置堆比写死-Xmx更适合 K8s 动态调整 resources。Spring Boot 2.5 默认 JDK 11 兼容良好如果项目用了 JDK 8 语法特性把基础镜像换成eclipse-temurin:8-jre-alpine即可。2.3 Nacos 2.0.3单机模式与集群模式的选择Nacos 2.0.3 在 K8s 上有两种跑法单机模式MODEstandalone适合开发和测试环境集群模式需要外置数据库并配置集群节点列表。生产环境必须用集群模式加 MySQL单机模式的数据存在容器内Pod 重建就丢配置。官方镜像nacos/nacos-server:2.0.3通过环境变量控制模式环境变量单机模式集群模式说明MODEstandalonecluster运行模式SPRING_DATASOURCE_PLATFORM可不填mysql集群模式必须外置库MYSQL_SERVICE_HOST不填数据库地址建议用 K8s Service 名NACOS_SERVERS不填节点列表格式 ip:8848,ip:8848JVM_XMS / JVM_XMX512m按需2.0.3 默认堆偏小集群模式下NACOS_SERVERS要填每个 Pod 的稳定地址这也是为什么 Nacos 通常配 StatefulSet 而不是 Deployment——StatefulSet 给每个 Pod 固定的网络标识重启后地址不变集群成员关系才不会乱。3. K8s 资源编排从 ConfigMap 到 Service 的完整 YAML镜像准备好之后落到 K8s 资源对象。这一章按「配置 → 工作负载 → 服务暴露」的顺序给可直接套用的 YAML重点讲清楚每个字段为什么这么填。3.1 用 ConfigMap 管理 Nacos 地址与后端配置后端连 Nacos 的地址、命名空间、分组这些不该硬编码在镜像里统一放 ConfigMap。Spring Boot 2.5 读取 Nacos 配置的bootstrap.yml内容可以整体塞进 ConfigMapapiVersion: v1 kind: ConfigMap metadata: name: backend-config namespace: demo data: application.yml: | spring: cloud: nacos: discovery: server-addr: nacos-svc:8848 namespace: ${NACOS_NAMESPACE:public} config: server-addr: nacos-svc:8848 file-extension: yaml namespace: ${NACOS_NAMESPACE:public}逻辑说明server-addr用 K8s Service 名nacos-svc同命名空间内 DNS 直接解析不用写 IP。namespace用占位符加默认值不同环境通过环境变量覆盖避免一份配置改来改去。注意 Nacos 2.0.3 除了 8848 端口还额外监听 9848gRPC 客户端端口和 9849gRPC 服务端端口Service 里必须把这三个端口都暴露只开 8848 会导致客户端连上却一直报连接超时这是 2.x 版本最典型的坑。3.2 后端 Deployment探针、资源限制与环境变量注入后端 Deployment 的关键在探针和资源限制。Spring Boot 启动慢initialDelaySeconds给太小会被 K8s 反复重启形成 CrashLoopBackOff。apiVersion: apps/v1 kind: Deployment metadata: name: backend namespace: demo spec: replicas: 2 selector: matchLabels: app: backend template: metadata: labels: app: backend spec: containers: - name: backend image: registry.example.com/demo/backend:1.0.0 ports: - containerPort: 8080 env: - name: NACOS_NAMESPACE value: prod - name: SPRING_PROFILES_ACTIVE value: k8s resources: requests: cpu: 500m memory: 1Gi limits: cpu: 1 memory: 2Gi readinessProbe: httpGet: path: /actuator/health/readiness port: 8080 initialDelaySeconds: 40 periodSeconds: 10 livenessProbe: httpGet: path: /actuator/health/liveness port: 8080 initialDelaySeconds: 90 periodSeconds: 20参数说明requests决定调度limits决定上限JVM 的MaxRAMPercentage会按 limit 算堆所以 limit 别设太小。readiness 探针 40 秒延迟是给 Spring Boot 加载 Nacos 配置留时间liveness 90 秒更保守避免启动期被误杀。探针路径依赖spring-boot-starter-actuator且 Spring Boot 2.5 要开启management.endpoint.health.probes.enabledtrue否则/actuator/health/readiness返回 404Pod 永远不 Ready。3.3 前端与 Nacos 的 Service 暴露方式前端是纯静态资源用 Deployment Service 即可对外通过 Ingress 暴露Nacos 用 StatefulSet Headless Service集群内部访问。前端 ServiceapiVersion: v1 kind: Service metadata: name: frontend-svc namespace: demo spec: selector: app: frontend ports: - port: 80 targetPort: 80 type: ClusterIPNacos 的 Headless Service 要设clusterIP: None让每个 Pod 有独立 DNS 记录StatefulSet 的serviceName指向它。Ingress 配置里前端走/后端接口如果不想让 Nginx 代理也可以直接在 Ingress 里按路径分流到backend-svc:8080两种方式选一种别同时配导致请求绕两圈。4. 避坑与排查这套组合最容易翻车的五个地方部署链路跑通不代表稳定下面五条是这套组合里出现频率最高的故障每条按现象、原因、解决写照着排查能省不少时间。4.1 Nacos 客户端连上但注册失败现象后端日志显示Nacos registry failed或注册成功但服务列表里看不到实例。原因多半是 Nacos 2.0.3 的 gRPC 端口 9848 没在 Service 里暴露客户端 HTTP 8848 能通gRPC 长连接建不起来。解决检查 Nacos Service 的 ports 是否包含 8848、9848、9849且targetPort与容器实际监听一致K8s 网络策略如果开了 NetworkPolicy也要放行这三个端口。4.2 前端刷新子路由 404现象首页正常点进/user/list再刷新就 404。原因是 Nginx 没配 history 回退请求直接打到文件系统找不到对应文件。解决location /里加try_files $uri $uri/ /index.html;改完重建前端镜像。注意如果 Ingress 层也做了路径重写要确认重写后仍能回退到 index.html两层都配容易互相干扰。4.3 后端 Pod 反复重启现象Pod 状态在 Running 和 CrashLoopBackOff 之间跳。原因通常是 liveness 探针initialDelaySeconds太小Spring Boot 还没启动完就被判定死亡。解决把 liveness 延迟调到 90 秒以上readiness 单独设短一些只影响流量接入同时看kubectl logs --previous确认是不是 OOMKilled如果是就把 memory limit 调大或降MaxRAMPercentage。4.4 配置中心改了配置后端不生效现象Nacos 控制台改了配置后端日志没反应。原因可能是bootstrap.yml没生效——Spring Boot 2.5 需要引入spring-cloud-starter-bootstrap依赖否则bootstrap.yml被忽略Nacos 配置压根没加载。解决加依赖后确认启动日志里有Located property source相关输出另外检查file-extension与实际配置格式是否一致yaml 写成 properties 会解析失败但不报错。4.5 镜像拉取失败或版本漂移现象Pod 卡在 ImagePullBackOff或不同节点拉到的镜像行为不一致。原因是镜像 tag 用了latest或私有仓库认证 Secret 没配到对应命名空间。解决镜像 tag 用明确版本号Deployment 里配imagePullSecrets并设imagePullPolicy: IfNotPresent多环境用同一 tag 时靠 ConfigMap 和环境变量区分不要靠重新打镜像。5. 上线前的验证清单与一个压测小技巧部署完别急着交付按一条固定链路验证一遍能挡掉大部分低级问题。我一般按这个顺序走先kubectl get pods -n demo确认三个组件都 Ready再kubectl exec进后端 Pod 用curl nacos-svc:8848/nacos/v1/ns/instance/list?serviceNamebackend看注册列表然后从前端 Pod 里curl backend-svc:8080/actuator/health验证服务间连通最后通过 Ingress 域名走一遍真实请求。这套顺序的好处是逐层排除出问题能立刻定位是注册、网络还是应用本身。验证通过后建议做一次小规模压测确认资源限制合理。用kubectl top pod观察后端在并发下的内存曲线如果接近 limit就把MaxRAMPercentage从 75 降到 60 左右给堆外内存留余量。下面这个命令可以快速看 Pod 资源使用# 持续观察后端 Pod 的 CPU 与内存5 秒刷新一次 kubectl top pod -n demo -l appbackend --containers参数说明-l appbackend按标签过滤--containers显示容器级数据。压测时重点看内存是否持续上涨不回落如果涨到 limit 附近被 OOMKilled优先查是否有大对象缓存没设上限而不是一味加内存。还有一个容易被忽略的点Nacos 2.0.3 集群模式下节点间数据同步依赖NACOS_SERVERS配置正确如果 StatefulSet 扩容后新 Pod 的地址没加进去集群会出现部分节点数据不一致。我的习惯是每次调整 Nacos 副本数后都进控制台看一遍集群节点列表确认所有节点状态都是 UP 再继续。从那以后我每次改完 Nacos 的 StatefulSet 副本数都强制走一遍「看节点列表 → 看配置同步 → 重启一个后端 Pod 验证注册」这三步宁可多花十分钟也不在上线后被动排查。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑