Day 19 / 共 20 天 · 第 4 周 前端/部署

部署:从代码到运行的容器

今天把"这堆代码怎么变成集群里跑的服务"讲透:Maven 一体化打包、Docker 镜像、Helm 编排,以及"部署配置怎么通过环境变量一路注入到代码"的完整闭环。

📍 你在整门课的位置 · 第 4 周 前端/部署(Day 16-20)
D16 前端技术栈 D17 前端结构 D18 动态表单 D19 部署 D20 收官串讲
L01

前后端一体化打包

🤔 痛点:一堆代码怎么变成能跑的服务? 前端一套 npm 工程、后端一套 Java 工程,还要装进容器、上 K8s。要是每步手动做——先 build 前端、再拷进后端、再打 jar、再 docker build、再写一堆 K8s YAML——又慢又容易漏。
💡 本质:集装箱 + 一键安装包 部署这条链就三样东西:Maven 把前后端打成一个 jar(一条命令)→ Docker 把 jar 连运行环境封成"集装箱"镜像(到哪都一样跑)→ Helm 是 K8s 的"一键安装包",一条 helm install 就把整套资源部署进集群。
📝 举个例子backend/mvn package → 自动 build 前端、把 frontend/build 塞进 src/main/resources/static、产出一个 higress-console.jar(前端页面也在里面)。前端工程师不用懂 Java,后端不用懂 npm,CI 只需这一条命令。

回收 Day 01 的工程点。backend/console/pom.xml

  • :101-143 frontend-maven-plugin:install node/npm → npm installnpm run build:134-141)。
  • :146-165 maven-resources-plugin:把 frontend/build 拷进 src/main/resources/static
  • backend/pom.xml:406skip.npm=true profile,可跳过前端构建加速纯后端开发。
一条命令搞定前后端 mvn package 一跑:先编译前端(下载 node、装依赖、build),再把前端产物塞进后端资源目录,最后打成一个 higress-console.jar前端工程师不用懂 Java、后端工程师不用懂 npm——CI 只需一条命令。skip.npm 让只改后端时跳过慢吞吞的前端构建。
L02

SPA 回退回顾

WebMvcInitializer.java:43-58(Day 02 讲过):/* 映射到 classpath:/static/CacheControl.maxAge(ZERO).mustRevalidate() 禁缓存;自定义 PathResourceResolver 找不到资源就回退 /index.html(排除 /v1/ 和静态目录)。

读法:禁缓存是为了"部署新版后用户立刻拿到新前端"。SPA 回退让刷新任意前端路由都能拿到 index.html。LandingController/landing)返回内置落地页,@AllowAnonymous 免鉴权。
L03

Dockerfile

backend/Dockerfile

FROM eclipse-temurin:21-jdk          # :1 JDK 21
COPY console/target/higress-console.jar /app/   # :9-10 + start.sh
# :12-17 按 TARGETARCH 拷贝 MCP 工具(tools/mcp/{arch}/main + openapiToMcpserver.sh)
EXPOSE 8080                          # :19
CMD ["/app/start.sh"]                # :20
读法:基础镜像带 JDK 21(比编译目标 JDK 8 高,运行更快)。那个 openapiToMcpserver.sh 正是 Day 15 swaggerToMcpConfig 调的外部脚本——按 CPU 架构(amd64/arm64)拷对应二进制。整个应用一个镜像、暴露 8080。
L04

构建 / 启动脚本

  • build.sh:3-8 支持 VERSION/DEV 环境变量;:9 ./mvnw clean package -Dmaven.test.skip=true(触发前端构建);:10 docker build
  • start.sh:3-7 ARM64 Mac 特判(MACOS_COMPATIBLE=true 加 JVM 参数禁 AES/SVE 指令规避兼容问题);:9-14 --local 决定跑本地还是容器内 jar。
为什么要为 ARM Mac 特判? Apple M 系列芯片是 ARM 架构,某些 JVM 优化指令(AES/SVE)在特定 JDK 版本上会崩。作者加了个开关,检测到 ARM Mac 就关掉这些指令保稳定。这种"照顾开发者本机环境"的细节,是成熟开源项目的贴心之处。
L05

Helm Chart

👶 小白 vs 👨‍🏫 老师 👶:Helm 是干嘛的?为什么部署 Console 还要配一堆 Role/ClusterRole?
👨‍🏫:Helm 是 K8s 的"安装包管理器"——把 Deployment、Service、RBAC 等一堆资源模板打包成一个 Chart,helm install 一键装好整套。
👶:那 RBAC(角色权限)为什么必须?
👨‍🏫:回想 Day 03——Console 没有数据库,一切存 K8s,它要读写集群的 Ingress/ConfigMap/Secret/CRD。K8s 默认不给这些权限,所以 Chart 里得声明 Role/ClusterRole 授权,就像新员工得先办好门禁卡才能进各个机房。

helm/Chart.yaml:1-8name: higress-console,version/appVersion 2.1.0。核心模板 helm/templates/deployment.yaml,镜像 :36values.yaml:62-67 replicaCount:1、镜像仓库、:86 service port:8080。还有 service/serviceaccount/role/rolebinding/clusterrole(RBAC)等模板。

Helm 是什么?为什么要 RBAC? Helm 是 K8s 的"安装包管理器"——把一堆 K8s 资源模板打包成一个 Chart,一条 helm install 就部署整套。RBAC(角色权限)很关键:Console 要读写集群的 Ingress/ConfigMap/Secret/CRD,K8s 默认不给权限——所以 Chart 里定义了 Role/ClusterRole 授权。这也印证了 Day 03 "无数据库、一切存 K8s" 的设计:正因为要操作 K8s,才需要这些权限。
L06

环境变量注入(配置闭环)

Helmvalues.yaml deploymentenv HIGRESS_CONSOLE_* Spring @ValueSdkConfig(Day 02) SDKHigressServiceConfig K8s 改配置只改 Helm values,一路注入到代码,无需动源码
配置注入闭环:Helm values → deployment 环境变量 → Spring @Value → SDK → 连 K8s。环境变量就像贴在集装箱外的快递面单,容器一启动就照单办事。
🧭 第一人称:你是一个叫 HIGRESS_CONSOLE_NS 的环境变量 你的值最早写在运维的 helm/values.yaml 里。helm install 时,deployment.yaml 把你渲染成容器的一个环境变量。容器启动,Spring 的 @Value("${higress-console.ns}") 一把把你读进 SdkConfig(Day 02 见过),再传给 HigressServiceConfig,最后 SDK 拿你去连对应命名空间的 K8s。全程没人改过一行 Java 代码——想换命名空间,只改 values 里的你就行。

deployment.yaml:38-52 注入的环境变量,正是 Day 02 SystemConfigKey 定义的键:

HIGRESS_CONSOLE_NS: ...
HIGRESS_CONSOLE_CONTROLLER_SERVICE_NAME: higress-controller
HIGRESS_CONSOLE_CONTROLLER_JWT_POLICY: ...
# :73+ HIGRESS_ADMIN_WASM_PLUGIN_IMAGE_* 控制插件镜像仓库(Day 12)
# :71-72 SPRINGDOC_* 控制 Swagger
配置注入完整链(贯穿全课)
Helm values.yamldeployment.yaml 环境变量 HIGRESS_CONSOLE_* → Spring @Value("${higress-console.*}")(Day 02 SdkConfig)→ HigressServiceConfig → SDK 连 K8s。改配置只需改 Helm values,无需动代码。
L07

可观测栈闭环

Chart 还打包完整可观测性栈:helm/templates/{grafana,prometheus,loki}.yamldeployment.yaml:53-62 注入 HIGRESS_CONSOLE_DASHBOARD_BASE_URL/PROM_URL/LOKI_URL

集成闭环(呼应仪表盘):Helm 部署 Grafana/Prometheus/Loki → env 注入 console → DashboardServiceImpl 判定 built-in → 启动时自动在 Grafana 建数据源 + 导入三份 dashboard(main/ai/logs.json,运行时把 ${datasource.id} 占位替换成真实 UID)→ 前端经 /grafana/** 反代内嵌展示GrafanaController)。

"开箱即用的监控"是怎么做到的? 一般搭监控要手动装 Grafana、配数据源、导仪表盘,很繁琐。Higress Console 把这些全自动化:部署时连监控组件一起装,Console 启动时自动配好 Grafana 数据源、导入预制的仪表盘。用户装完就能在界面里看到网关的流量/Token/日志图表,零配置。这是产品化的体现。
L08

今日小结 + 动手

🧠 今天你应该能回答

  • mvn package 怎么把前后端打成一个 jar?
  • Dockerfile 为什么要拷 MCP 工具?暴露哪个端口?
  • Helm 为什么需要 RBAC?和"无数据库"设计什么关系?
  • 配置注入的完整链(Helm→env→@Value→SDK)?
  • 可观测栈怎么自动集成?

✋ 动手

cd /Users/bitmart/work/codes/github/higress-group/higress-console
cat backend/Dockerfile
sed -n '101,165p' backend/console/pom.xml
sed -n '36,72p' helm/templates/deployment.yaml
sed -n '62,90p' helm/values.yaml
ls helm/templates/
明天预告 · Day 20(收官)全栈回顾 + higress-group 五站串讲——把 Console 的四周内容串成一条主线,再把 Envoy→Istio→Higress→Console 整个 higress-group 系列连起来,看清一个 AI 网关产品的完整全貌。
← Day 18 Day 20 · 收官串讲 →