简介本资源是一套面向Kubernetes初学者与云原生实践者的完整部署方案聚焦阿里云K8s环境下Vue2前端、SpringBoot2.5后端、Nacos2.0.3服务注册中心及Nginx反向代理的一站式集成部署。适用于微服务架构落地、容器化迁移学习及企业级前后端分离项目实战演练尤其适合具备基础Docker与K8s概念的中级开发者快速上手。压缩包共16个文件含8个YAML覆盖Deployment、StatefulSet、Ingress、Service等核心资源定义、2个Shell脚本实现一键部署与环境初始化、2个Dockerfile分别构建Vue静态站点与SpringBoot应用镜像以及SQL数据库初始化脚本、Nginx配置文件、JAR包和GZ压缩包等关键组件整体大小为34.69MB。已有1340人学习下载提供开箱即用的目录结构与模块化配置涵盖前端dist打包、Nacos高可用部署、MySQL持久化配置及全链路服务暴露方案显著降低K8s多组件协同部署门槛。1. 阿里云 K8s 上跑 Vue2 SpringBoot2.5 Nacos2.0.3不是堆组件是理清三类服务的生命周期边界你手头有个老 Vue2 单页应用后端是 SpringBoot 2.5JDK 8 兼容性刚需注册中心必须用 Nacos 2.0.3因历史服务强依赖其 gRPC 接口和命名空间隔离策略还要上阿里云 ACKKubernetes——这不是“把 Dockerfile 写完就完事”的玩具项目。真实踩坑点在于Vue2 的静态资源怎么在 Nginx 容器里热更新不重启SpringBoot 启动时连不上 Nacos到底是网络策略没开、Service DNS 解析失败还是 Nacos 客户端版本和 Server 2.0.3 不兼容更隐蔽的是Nacos 自身在 K8s 里用 PV 持久化后升级时 etcd 数据迁移失败导致整个服务发现雪崩。我去年在金融客户现场复现过这套组合最终稳定运行的关键不是调参而是把 Vue纯静态、SpringBoot有状态中间件依赖、Nacos有状态核心中间件这三类服务在 K8s 中拆成完全独立的部署单元、网络域和健康检查逻辑。适合正在迁移老系统、被 SpringCloud Alibaba 版本锁死、又必须上云原生的中型团队——别信“一键部署脚本”先搞懂每个 Pod 为什么活、为什么死。2. 构建可复现的镜像Vue2 静态资源打包与 SpringBoot 可执行包分离策略2.1 Vue2 项目构建用 nginx:alpine 基础镜像做最小化静态服务容器Vue2 项目不能直接npm run serve上 K8s必须走生产构建 Nginx 托管。关键不是“能访问”而是“构建产物路径可控、Nginx 配置可注入、缓存策略可灰度”。我们放弃nginx:latest固定用nginx:1.22-alpine对应 OpenSSL 1.1.1兼容老浏览器 TLS 1.2并把dist/目录结构和 Nginx 配置解耦# Dockerfile.vue2 FROM nginx:1.22-alpine # 删除默认配置避免冲突 RUN rm -f /etc/nginx/conf.d/default.conf # 复制自定义 Nginx 配置支持环境变量注入 COPY nginx.conf.template /etc/nginx/nginx.conf.template # 复制构建产物注意dist 目录必须存在且 index.html 在根 COPY dist/ /usr/share/nginx/html/ # 启动前用 envsubst 替换模板中的环境变量如 API 域名 CMD sed -i s/\$\$API_BASE_URL/$API_BASE_URL/g /etc/nginx/nginx.conf.template \ mv /etc/nginx/nginx.conf.template /etc/nginx/nginx.conf \ nginx -g daemon off;提示nginx.conf.template中必须用$$API_BASE_URL双$是 shell 转义否则envsubst会误替换$host等 Nginx 内置变量。这是 Vue2 项目在 K8s 里实现“一套镜像、多环境域名”的核心技巧。2.2 SpringBoot 2.5 构建禁用内嵌 Tomcat打成 thin jar 并用 jre-alpine 运行SpringBoot 2.5 默认带 Tomcat但在 K8s 里它和 Nginx 形成双层代理增加故障点。我们强制用 Undertow并打成thin jar依赖不打进包由 K8s InitContainer 下载减小镜像体积、加速拉取!-- pom.xml 片段 -- properties maven.compiler.source8/maven.compiler.source maven.compiler.target8/maven.compiler.target spring-boot.version2.5.17/spring-boot.version /properties dependencies !-- 移除 spring-boot-starter-tomcat -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency !-- 加入 undertow -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-undertow/artifactId /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId configuration !-- 打成 thin jar -- layoutZIP/layout executablefalse/executable /configuration /plugin /plugins /build构建命令mvn clean package -DskipTests # 输出 target/myapp-1.0.0.jarthin jar然后写 SpringBoot 专用 Dockerfile# Dockerfile.springboot FROM openjdk:8-jre-alpine3.18 # 创建非 root 用户安全基线要求 RUN addgroup -g 1001 -f appgroup adduser -S appuser -u 1001 # 复制 thin jar COPY target/myapp-1.0.0.jar /app.jar # 设置启动用户 USER appuser # 启动命令显式指定 JVM 参数避免 OOM Kill ENTRYPOINT [java,-Xms256m,-Xmx512m,-XX:UseG1GC,-Dfile.encodingUTF-8,-jar,/app.jar]参数说明-Xms256m -Xmx512m是硬性要求。阿里云 ECS 的 cgroup v1 默认限制容器内存为 512MB若不设-XmxJVM 会按宿主机内存比例分配可能超限被 kill。-XX:UseG1GC是 JDK 8u212 对容器内存感知的必要开关。2.3 Nacos 2.0.3 部署用官方 Helm Chart但必须重写 StatefulSet 的 volumeClaimTemplatesNacos 2.0.3 的 K8s 部署最易翻车——官方 Helm Chartnacos-k8s默认用emptyDirPod 重建后集群元数据全丢。我们必须强制用阿里云 NAS 或云盘 PV并修改volumeClaimTemplates使其匹配阿里云存储类# nacos-values.yamlHelm values 文件 persistence: enabled: true # 必须匹配阿里云 ACK 集群中已创建的 StorageClass storageClassName: alicloud-disk-ssd accessModes: - ReadWriteOnce size: 20Gi # 关键覆盖 StatefulSet 的 volumeClaimTemplates确保 PVC 名称唯一且可预测 nacos: # 关闭自动创建 ServiceAccountACK 默认有 createServiceAccount: false # 指定 Nacos 配置中心使用 MySQL生产必需不能用内嵌 Derby mysql: enabled: true host: rds-mysql-xxx.mysql.rds.aliyuncs.com port: 3306 database: nacos_config user: nacos_user password: your_secure_password # 阿里云 RDS 必须开启白名单添加 ACK 集群节点 IP 段安装命令helm repo add nacos https://nacos-group.github.io/nacos-k8s/ helm repo update helm install nacos nacos/nacos --version 1.2.0 -f nacos-values.yaml -n middleware注意Helm Chart 版本1.2.0对应 Nacos Server 2.0.3。不要用latest否则会升级到 2.2.x其 gRPC 端口和客户端 SDK 不兼容 SpringBoot 2.5 的nacos-client:2.0.3。3. K8s 资源编排Namespace、NetworkPolicy 与 Service 的三层隔离设计3.1 按业务域划分 Namespacefrontend / backend / middleware绝不把 Vue、SpringBoot、Nacos 放进同一个 Namespace。这是血泪经验某次 Nacos Pod 因磁盘满被驱逐kubectl delete ns middleware误删了同名的 backend 命名空间导致整个订单服务不可用。正确做法# namespace.yaml apiVersion: v1 kind: Namespace metadata: name: frontend labels: team: web --- apiVersion: v1 kind: Namespace metadata: name: backend labels: team: java --- apiVersion: v1 kind: Namespace metadata: name: middleware labels: team: infra为什么重要阿里云 ACK 的 NetworkPolicy 默认作用于 Namespace 级别。frontend只能访问backend的 8080 端口backend只能访问middleware的 8848 端口middleware之间用 ClusterIP 通信——这种隔离让故障域收敛也满足等保三级“网络区域划分”要求。3.2 Service 类型选择ClusterIP 为主Ingress 仅用于 Vue2 流量入口Vue2 服务用Service TypeClusterIPIngress暴露。因为 Vue2 是纯静态Nginx 容器本身无状态Ingress Controller如 ALB Ingress可做 SSL 卸载、WAF 防护、灰度发布。SpringBoot 服务只用ClusterIP。前端通过 Ingress 访问 Vue2Vue2 的 axios 请求发往http://springboot-svc.backend:8080/api/xxxK8s DNS 自动解析不经过公网。Nacos 服务ClusterIP Headless ServiceclusterIP: None。因为 Nacos 集群节点需互相发现必须用 Pod DNSnacos-0.nacos-headless.middleware.svc.cluster.local而非 Service VIP。# service-nacos-headless.yaml apiVersion: v1 kind: Service metadata: name: nacos-headless namespace: middleware spec: clusterIP: None ports: - port: 8848 name: client - port: 9848 name: raft selector: app: nacos3.3 NetworkPolicy精确控制跨 Namespace 流量这是阿里云 ACK 生产环境的硬性要求。以下 Policy 确保frontend只能访问backend的 8080且backend只能访问middleware的 8848 和 3306MySQL# network-policy.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: frontend-to-backend namespace: frontend spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: name: backend ports: - protocol: TCP port: 8080 --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: backend-to-middleware namespace: backend spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: name: middleware ports: - protocol: TCP port: 8848 - protocol: TCP port: 3306验证命令kubectl exec -n frontend vue2-pod -- curl -I http://springboot-svc.backend:8080/health应返回 200curl http://nacos-svc.middleware:8848/nacos应超时被 NetworkPolicy 拦截。4. 避坑Nacos 连接失败、Vue2 404、SpringBoot 启动卡住的五大真实故障4.1 现象SpringBoot 启动日志卡在Waiting for nacos server to start...30 秒后报No available server原因SpringBoot 客户端nacos-client:2.0.3默认用grpc协议连接 Nacos Server但阿里云 ACK 的 CoreDNS 默认不解析nacos-0.nacos-headless.middleware.svc.cluster.local的 SRV 记录gRPC 依赖 SRV 发现端口。解决在 SpringBoot 的bootstrap.yml中强制关闭 gRPC回退到 HTTPspring: cloud: nacos: discovery: server-addr: nacos-svc.middleware:8848 # 关键禁用 gRPC用 HTTP 心跳 metadata: preserved.heart.beat.interval: 5000 config: server-addr: nacos-svc.middleware:8848 # 强制用 HTTP 拉取配置 endpoint: http://nacos-svc.middleware:88484.2 现象Vue2 页面打开后所有 API 请求 404但curl http://springboot-svc.backend:8080/actuator/health返回 200原因Vue2 的axios默认请求/api/xxx而 Nginx 容器内未配置反向代理规则请求直接 404Nginx 找不到/api目录。解决修改nginx.conf.template添加 location 代理块location /api/ { proxy_pass http://springboot-svc.backend:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 关键去除 /api 前缀再转发 proxy_redirect off; }注意proxy_pass末尾的/它会 strip/api/前缀。没有这个/请求会变成http://.../api/xxx后端收不到。4.3 现象Nacos 控制台登录成功但 SpringBoot 服务列表为空nacos-server日志报failed to request原因Nacos Server 2.0.3 默认开启auth权限认证但 SpringBoot 客户端未传 token。解决在 Nacos 控制台http://nacos-svc.middleware:8848/nacos创建用户springboot密码123456然后在 SpringBoot 的bootstrap.yml中加spring: cloud: nacos: discovery: username: springboot password: 123456 config: username: springboot password: 1234564.4 现象kubectl get pods -n middleware显示nacos-0一直CrashLoopBackOff日志Failed to connect to MySQL原因阿里云 RDS 白名单未放通 ACK 集群节点网段或 RDS 安全组未开放 3306 端口。解决进入阿里云 RDS 控制台 → 白名单分组 → 编辑default分组 → 添加 ACK 集群 VPC 网段如172.20.0.0/16RDS 实例 → 安全组 → 添加入方向规则端口3306授权对象0.0.0.0/0测试用或集群节点 IP 段在nacos-values.yaml中确认mysql.host是 RDS 的内网地址非公网避免走公网延迟。4.5 现象Vue2 页面加载极慢F12 查看 Networkindex.html200但app.js、chunk-vendors.js返回 404原因Vue2vue.config.js中publicPath配置错误。若用publicPath: /构建产物路径为/js/app.js但 Nginx 容器内index.html在/usr/share/nginx/html/相对路径解析失败。解决vue.config.js中设publicPath: ./相对路径并确保dist/目录结构扁平module.exports { publicPath: ./, // 关键生成相对路径引用 outputDir: dist, assetsDir: static }构建后检查dist/index.html中 script 标签是否为script src./js/app.js而非script src/js/app.js。5. 生产级验证用 kubectl curl Prometheus 三步闭环检测服务健康5.1 第一步K8s 层面验证 Pod 就绪与 Service 连通性不要只看kubectl get pods的Running状态要验证Ready列如1/1和STATUS列非CrashLoopBackOff。对三个 Namespace 分别执行# 检查 frontendVue2 kubectl get pods -n frontend # 验证 Vue2 容器内能否解析 backend Service kubectl exec -n frontend deploy/vue2 -- sh -c nslookup springboot-svc.backend # 检查 backendSpringBoot kubectl get pods -n backend # 验证 SpringBoot 能否连通 Nacos从容器内 curl kubectl exec -n backend deploy/springboot -- curl -s -o /dev/null -w %{http_code} http://nacos-svc.middleware:8848/nacos/v1/ns/service/list # 检查 middlewareNacos kubectl get pods -n middleware # 验证 Nacos 集群节点数StatefulSet 应为 3 kubectl get statefulset -n middleware关键指标nslookup必须返回springboot-svc.backend.svc.cluster.local的 A 记录curl对 Nacos 的/nacos/v1/ns/service/list必须返回200非503证明服务发现接口可用。5.2 第二步业务层面验证 API 链路绕过 Ingress直击 ClusterIP用kubectl port-forward暴露内部 Service模拟前端真实调用链# 在本地终端执行保持长连接 kubectl port-forward svc/springboot-svc 8080:8080 -n backend kubectl port-forward svc/nacos-svc 8848:8848 -n middleware # 验证 SpringBoot 健康接口直连 ClusterIP curl http://localhost:8080/actuator/health # 验证 Nacos 配置中心直连 ClusterIP curl http://localhost:8848/nacos/v1/cs/configs?dataIdmyapp-dev.yamlgroupDEFAULT_GROUP # 验证 Vue2 静态资源需先构建并推镜像 kubectl port-forward svc/vue2-svc 8081:80 -n frontend curl http://localhost:8081/ # 应返回 index.html curl http://localhost:8081/js/app.js # 应返回 JS 内容玄学排查若curl http://localhost:8080/actuator/health返回404检查 SpringBoot 的management.endpoints.web.base-path是否为/actuator默认值且management.endpoints.web.exposure.include包含health。5.3 第三步接入 Prometheus Grafana监控 Nacos 注册实例数与 SpringBoot GC 时间阿里云 ACK 内置 ARMS Prometheus只需添加 ServiceMonitor。创建monitoring.yamlapiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: nacos-monitor namespace: middleware spec: selector: matchLabels: app: nacos endpoints: - port: prometheus interval: 30s path: /actuator/prometheus --- apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: springboot-monitor namespace: backend spec: selector: matchLabels: app: springboot endpoints: - port: management interval: 30s path: /actuator/prometheus然后在 Grafana 中导入 Dashboard ID12856Spring Boot Actuator重点关注jvm_memory_used_bytes确认内存使用率 70%process_uptime_seconds确认进程未频繁重启nacos_monitor_instance_countNacos 自带指标确认注册实例数 0。血泪经验曾因nacos_monitor_instance_count为 0排查 3 小时才发现 SpringBoot 的spring.cloud.nacos.discovery.group配置成了PROD_GROUP而 Nacos 控制台创建的是DEFAULT_GROUP大小写敏感导致服务注册失败。6. 进阶技巧用阿里云 ARMS 实现 Vue2 前端错误追踪与 SpringBoot 链路染色6.1 Vue2 前端错误捕获用 ARMS Web SDK 替代 Sentry直连阿里云 SLSSentry 需自建服务而阿里云 ARMS 提供开箱即用的前端监控。在 Vue2 的main.js中注入// main.js import Arms from alicloud/alipay-arms-web Arms.start({ pid: your-arms-pid, // 阿里云 ARMS 控制台获取 enableLinkTrace: true, // 开启链路追踪 enableResourceReport: true, // 上报 JS/CSS 加载性能 enableErrorReport: true, // 上报 JS 错误 enableConsoleReport: true, // 上报 console.error // 关键设置采样率避免日志爆炸 sampleRate: 0.1, // 关键过滤敏感字段如 token、手机号 ignoreFields: [token, phone, idCard] }) new Vue({ render: h h(App), }).$mount(#app)效果ARMS 控制台 → 前端监控 → 错误分析可看到TypeError: Cannot read property xxx of undefined的完整堆栈、影响用户数、发生页面 URL。比console.log高效 10 倍。6.2 SpringBoot 链路染色用 ARMS Java Agent 实现 Vue2 → SpringBoot → Nacos 全链路不改一行代码用阿里云 ARMS Java Agent 实现分布式追踪。步骤下载 ARMS Agent 官网链接 上传到 ACK 集群某节点修改 SpringBoot Deployment挂载 Agent 并注入 JVM 参数# deployment-springboot.yaml apiVersion: apps/v1 kind: Deployment metadata: name: springboot namespace: backend spec: template: spec: containers: - name: app image: your-registry/springboot:1.0.0 # 挂载 ARMS Agent volumeMounts: - name: arms-agent mountPath: /opt/arms volumes: - name: arms-agent hostPath: path: /path/to/arms-agent # 注入 JVM 参数 args: [-javaagent:/opt/arms/arms-agent.jar, -Darms.pidyour-arms-pid, -Darms.appNamespringboot-prod]在application.yml中启用 Spring Cloud SleuthARMS Agent 会自动识别spring: sleuth: sampler: probability: 1.0 # 100% 采样生产建议 0.1 zipkin: base-url: http://arms-zipkin.arms.svc.cluster.local:9411 # ARMS 内置 Zipkin 地址验证方法在 Vue2 页面触发一个 API 请求 → ARMS 控制台 → 分布式追踪 → 搜索该请求 TraceID → 查看完整链路Vue2 Browser → SpringBoot Pod → Nacos Server → MySQL每段耗时、状态码、SQL 语句一目了然。6.3 最后一道防线用阿里云 SLS 日志审计抓取所有4xx/5xx请求K8s 的kubectl logs只能看实时日志而 SLS 可做长期审计。在 ACK 控制台开启日志采集采集源frontendNamespace 下所有 Pod 的 stdout过滤条件status 400Nginx access log告警规则count(*) 100 in 5m通知钉钉群。这样当 Vue2 页面突然大量401 UnauthorizedSLS 告警会立刻推送你不用等用户投诉。从那以后我每次上线新版本都强制走一遍kubectl port-forward直连验证 ARMS 链路追踪截图 SLS 错误日志快照三份证据存档。不是怕出问题是怕出问题时找不到第一现场。希望帮到你。本文还有配套的精品资源点击获取