Day 19 / 共 20 天 · 第 4 周 AI 网关/部署

部署 + 内嵌 istio/envoy

前 18 天讲的组件(控制器、istiod、Envoy、插件),今天看它们怎么被打包部署到一起:一 Pod 双容器、两级 xDS、helm 伞形 chart,以及它怎么内嵌 Istio/Envoy 的 fork。这一天会把 Day 01 的架构图落到"真实的 Pod 和容器"上——也把前两站(Envoy/Istio)的源码正式接回来。

📍 你在第 4 周(AI 网关 / 部署)的位置
D16 ai-proxy D17 AI 增强插件 D18 hgctl CLI D19 部署 + 内嵌 istio/envoy D20 收官
🤔 痛点:Higress、istiod、Envoy 三块,装到 K8s 里到底是几个 Pod、谁跟谁通信? 前 18 天讲的都是"逻辑上"谁给谁发配置,但真部署时你会问:它们是一个进程还是几个容器?端口 15051/15012 分别谁在听?内嵌的 istio/envoy 是从哪来的代码?不落到真实的 Pod/容器/端口,架构图始终是悬空的。
💡 先兜住今天(把 Day 01 的架构落成"真实房间") Day 01 讲过"Higress Core 喂配置给 istiod、istiod 喂给 Envoy"——那是抽象箭头。今天把它变成看得见的办公室:控制面是一间办公室(Pod)里坐着两个同事——higress(Core,负责翻译)和 discovery(istiod,负责生成 xDS),同屋所以能小声用 127.0.0.1:15051 传纸条;数据面 Envoy 是另一栋楼的一群外勤(可扩缩容),通过 :15012 定期回办公室取最新指令。配置就这样两级传话一路热更下去。
L01

一 Pod 双容器

# helm/core/templates/controller-deployment.yaml
# higress-controller Deployment 一 Pod 两容器:
#   higress   容器(:38):镜像 higress/higress,命令 serve(本课的控制器)
#   discovery 容器(:112):镜像 higress/pilot,命令 discovery(istiod fork)
# pilot 通过 HIGRESS_CONTROLLER_SVC=127.0.0.1 + PORT=15051 从同 Pod 控制器拉 MCP 配置
部署实况:控制面一间办公室(Pod)两同事,数据面另一栋楼 higress-controller Pod(控制面) higress Core / serve 起 MCP :15051 (本课主角) discovery istiod fork 起 xDS :15012 127.0.0.1:15051 传纸条 higress-gateway(数据面·多副本) Envoy(proxy router) 执行流量 + 跑 Wasm/Go 插件 :15012 取指令
图注:同屋两同事(Core+istiod)低延迟传纸条(15051);外勤 Envoy 回屋取指令(15012)。这就是 Day 01 抽象箭头的物理落地。
"一 Pod 两容器"的巧妙 Higress Controller 是一个 Pod 里跑两个容器higress(Higress Core,Day 02-05 的控制器,起 15051 的 MCP Server)+ discovery(istiod fork,起 15012 的 xDS)。因为在同一个 Pod,它们能通过 127.0.0.1:15051 通信——discovery 容器(istiod)从 higress 容器(Core)拉 MCP 配置。这坐实了 Day 01-05 的架构:Higress Core 喂配置给 istiod。放同 Pod 是为了低延迟通信 + 生命周期绑定(一起启停)。数据面 Envoy 是另一个 Deployment(L04)。
L02

两级 xDS

Ingress/CRD ──▶ higress 容器(serve) :15051 以 MCP 吐配置
                    │ (configSource: xds://127.0.0.1:15051)
                    ▼
              discovery 容器(istiod) :15012 生成真正的 LDS/CDS/RDS/EDS
                    ▼
              higress-gateway(Envoy) 执行流量 + 加载 Wasm/Go 插件
两级 xDS 是 Higress 架构的精髓
第一级 MCP-over-xDS(15051):higress 容器 → discovery 容器,传 Istio 配置对象(VirtualService 等,Day 05)。
第二级 标准 xDS(15012):discovery 容器 → Envoy,传 LDS/CDS/RDS/EDS(Istio 课)。
两级串联:Higress Core 生成配置 → istiod 转 xDS → Envoy 执行。这就是三站(Higress/Istio/Envoy)的物理连接图。
📝 举个例子:你新增一条 Ingress 路由,它怎么两级传到 Envoy kubectl apply 一条 Ingress(/api → svc-a)→ ① higress 容器监听到变更,翻译成 Istio 的 VirtualService,从 :15051 以 MCP 推给隔壁 discovery 容器 → ② discovery(istiod)把它算成 Envoy 能懂的 RDS 路由配置,从 :15012 下发给 Envoy → ③ Envoy 热加载,下一个 /api 请求就命中 svc-a。全程不重启,几秒内生效——这就是"两级 xDS + 热更新"跑起来的样子。
L03

helm 伞形 chart

# helm/higress/Chart.yaml 伞形 chart =
#   higress-core(本地 file://../core)+ higress-console(远程)
# helm/core 部署三类工作负载:
#   higress-controller Deployment(一 Pod 双容器,L01)
#   higress-gateway Deployment/DaemonSet(Envoy,L04)
#   higress-console(远程 chart)
读法:用 helm"伞形 chart"(一个 chart 依赖多个子 chart)组织部署——core(控制器+网关)+ console(控制台)。helm install higress helm/higress 一键装全套。配置分发核心是 higress-config ConfigMap(Day 01 的 configSources)。
L04

Gateway 数据面

higress-gatewayhelm/core/templates/deployment.yaml 或 daemonset):Envoy 容器,命令 proxy routerdiscoveryAddress = higress-controller.<ns>.svc:15012(连 discovery 容器拿 xDS)。

读法:数据面 Envoy 是独立的 Deployment(可扩缩容)。它连 higress-controller:15012(discovery 容器)拿 xDS——就是 Istio 课/Envoy 课讲的那个 xDS 连接。控制面(controller Pod)和数据面(gateway Pod)分离部署——控制面少而稳、数据面多而弹。可选 Deployment(云 LB)或 DaemonSet(每节点一个)。
L05

内嵌 istio/envoy

Higress 仓库根的 istio/envoy/git submodule(本地未 checkout),指向 higress-group 的 fork:Istio istio-1.27、Envoy envoy-1.36。即 Higress 基于 Istio 1.27 + Envoy 1.36 的定制 fork

这就是本系列前两站的源码! 你前两站学的 higress-group/istiohigress-group/envoy,就是 Higress 内嵌的这两个 submodule!Higress 用它们的 fork(带 // Added by ingress 定制)编译出 pilot 镜像(istiod)和 gateway 镜像(Envoy)。所以三站不是孤立的——Envoy 是 Higress 的数据面代码、Istio 是 Higress 的控制面代码,Higress 在它们之上加控制器 + 插件 + AI 能力。学完三站,你就完整掌握了这个 fork 生态的全部层次。

👶 小白:既然内嵌了 Istio 和 Envoy,为什么不直接用官方版,非要 fork 一份?

👨‍🏫 老师:因为 Higress 要给它俩加"官方没有的定制"。比如 Envoy 侧加了 proxy_redis_call 等增强 ABI(Day 11/14 限流要用)、istiod 侧加了 Ingress 相关的翻译逻辑(源码里的 // Added by ingress 标记)。这些改动只能在自己的 fork 上做,再用 build-envoy.patch 这类编译期补丁打进去(下面 L06 的"构建胶水")。所以你前两站读的 higress-group/istiohigress-group/envoy,正是这两个带定制的 fork——它们就是今天这两个 submodule。三站在这里合体。

L06

构建胶水

# tools/hack/ + Makefile.core.mk
# build-envoy(:156)→ build-envoy.sh:打补丁 build-envoy.patch 后编译定制 Envoy
# build-pilot/build-istio(:159/:187):产 docker.pilot(istiod 镜像)
# build-gateway(:169):先 build-golang-filter(.so)再产 docker.proxyv2(Envoy 镜像)
# 三类镜像:控制器 ← ./cmd/higress;pilot ← external/istio;gateway ← external/proxy+envoy+golang-filter
读法:Higress 用 Makefile + tools/hack 脚本把 istio/envoy 的 fork 编译成镜像:pilot 镜像(istiod)、proxyv2 镜像(Envoy + golang-filter)、控制器镜像(本仓库 cmd/higress)。build-envoy.patch 是 Higress 对 Envoy 的编译期补丁。golang-filter(Day 15)编进 Envoy 镜像。
L07

单机 vs K8s

  • 单机(standalone):一个 all-in-one 容器(console+controller+envoy),配置落本地文件。适合试用/边缘(实际编排在独立仓库 higress-standalone)。
  • K8s:至少 3 类 Pod(controller/gateway/console),配置经 CRD/ConfigMap+xDS 分发,支持 HPA/LoadBalancer/可观测。
读法:两种拓扑:单机(简单、一个容器搞定,适合尝鲜)vs K8s(生产级、组件分离、可扩缩容)。docker/Dockerfile.higress 只构建控制器单二进制镜像;all-in-one 在独立仓库。
L08

今日小结 + 动手

🧠 今天你应该能回答

  • 一 Pod 双容器是哪两个?为什么放同 Pod?
  • 两级 xDS 分别是什么?(15051 MCP + 15012 标准)
  • helm 伞形 chart 部署哪三类工作负载?
  • 内嵌的 istio/envoy submodule 是什么?和前两站什么关系?
  • 三类镜像怎么构建?单机 vs K8s 的区别?

✋ 动手

cd /Users/bitmart/work/codes/github/higress-group/higress
sed -n '30,120p' helm/core/templates/controller-deployment.yaml | head -50
cat .gitmodules
grep -n 'build-envoy\|build-pilot\|build-gateway' Makefile.core.mk
明天预告 · Day 20(结业)收官串讲——一次 AI 请求的完整路径、Higress 全景回顾,以及 higress-group 三站(Envoy/Istio/Higress)的完整串讲,承上启下引出剩余两站。
← Day 18 hgctl Day 20 · 收官串讲 →