配置模型 + 证书管理
收官第 2 周:先看 Higress 的 config 模型(复用 Istio),再看它的自动 HTTPS——用 certmagic + ACME Let's Encrypt,还有一个"用自身网关完成 HTTP-01 挑战"的巧妙设计。前 9 天我们看透了"配置怎么翻译下发""服务怎么发现",今天补上产品化的最后一块拼图——让网关自动办好并续期 HTTPS 证书,收官第 2 周,第 3 周将转向插件生态。
配置模型
// pkg/config/envs.go:环境变量配置
// PodNamespace 默认 higress-system、GatewayName 默认 higress-gateway
// McpServerWasmImageUrl 默认阿里云 OCI 镜像
// pkg/config/constants/constants.go:
// DefaultIngressClass/DefaultGatewayClass = "higress"
// ManagedGatewayController = "higress.io/gateway-controller"
// RegistryTypeLabelKey/RegistryNameLabelKey(Day 09 打给 ServiceEntry 的标签)
DefaultIngressClass=higress 决定 Higress 只处理标了这个 class 的 Ingress(避免和其他 Ingress 控制器冲突)。复用 Istio config
config.Config、config.Meta、config.GroupVersionKind(Istio 课 Day 03)。它自己写的是 IngressConfig(Day 03)这个聚合 ConfigStore——把三类来源(Ingress、Gateway API、McpBridge 注册中心)统一转换成 Istio 的 config.Config,用 GVK 区分资源类型。McpBridge 的注册结果最终以 Namespace:"mcp" 的 ServiceEntry 形式融入 Istio 配置体系(Day 09)。Higress 自有 CRD(McpBridge/WasmPlugin/Http2Rpc)的 proto/client 在 api/ 和 client/pkg/。"复用成熟抽象 + 自建聚合层"是 Higress 的一贯策略。自动 HTTPS 概览
Higress 用 certmagic(caddy 的证书库)+ acmez 实现自动 HTTPS。配置在 higress-https ConfigMap,Issuer 支持 aliyunssl、letsencrypt(pkg/cert/config.go:41)。默认续期提前 30 天。
certmagic 引擎
// pkg/cert/certmgr.go:52 InitCertMgr
// 用 ConfigMap 作 certmagic 的 Storage(:59)
// RenewalWindowRatio = RenewBeforeDays/90(:60)
// ACMEIssuer:CA 用 LetsEncryptProductionCA,禁 TLS-ALPN、启用 HTTP-01(:86)
// 注入自定义 ingressSolver(:94)
// Reconcile(:116):配置变化时 manageSync 管理域名证书,触发 XDSUpdater.ConfigUpdate 全量推送
Reconcile 是证书的控制循环(和 Day 07 的 Reconcile 同模式)——配置变了就管理对应域名的证书。证书变更触发 xDS 全量推送(让 Envoy 用新证书)。HTTP-01 挑战(巧妙设计)
// pkg/cert/ingress.go IngressSolver(实现 acmez.Solver)
// Present(:58):挑战时【动态创建一个 Ingress】
// path /.well-known/acme-challenge/{token},后端指向 higress-controller:8889
// CleanUp(:95):验证完删除该 Ingress
你的域名/.well-known/acme-challenge/{token},你能返回正确 token 就证明拥有域名。问题:这个验证请求得能到达 Higress。Higress 的巧妙解法:动态创建一个临时 Ingress,把 /.well-known/acme-challenge/{token} 路由到自己的证书服务(8889 端口)——用自身的网关能力来接 Let's Encrypt 的验证请求!验证完删掉这个临时 Ingress。网关用自己解决自己的证书验证——自举、优雅。这是"用产品自身能力解决产品自身需求"的漂亮设计。higress-https ConfigMap 声明 example.com 用 letsencrypt →certmagic 向 Let's Encrypt 申请 → LE 说"证明你拥有 example.com,我去访问
http://example.com/.well-known/acme-challenge/abc123" →Present 动态建临时 Ingress:把该 path 路由到 higress-controller:8889 → LE 访问,8889 返回正确 token → 验证通过 →LE 签发证书 →
OnEvent(cert_obtained) → 写入 K8s TLS Secret → xDS 推给 Envoy → CleanUp 删临时 Ingress。全程零手动。👶 小白:为什么不直接固定配一条 challenge 路由,非要"动态建、验完删"?
👨🏫 老师:因为 challenge 路由只在申请/续期那几秒有用,平时留着纯属多余、还多一条对外暴露的路径(安全面)。动态建、验完删让这条特殊路由"用时才存在",既不污染常态配置,也把暴露窗口压到最短。这跟 Day 04 的"惰性生成"一个味道——需要时才造,用完即弃。
ConfigMap 存储
pkg/cert/storage.go ConfigmapStorage 实现 certmagic 的 Storage 接口(Exists/Store/Load/Delete/Lock/Unlock),把证书、账户、锁全存进 K8s ConfigMap。
Storage 接口,把这些数据全塞进 ConfigMap。好处:零外部依赖——K8s 集群本身就是存储,多个 Higress 副本共享同一个 ConfigMap(含分布式锁,避免多副本同时申请证书)。这是"复用 K8s 原生能力做持久化"的云原生实践(和 Istio 用 Secret 存证书同理)。证书落地
certmgr.go:203 OnEvent 监听 certmagic 的 cert_obtained 事件——拿到证书后解析有效期,secretMgr.Update 把证书写入 K8s TLS Secret 供网关使用。控制器 pkg/cert/controller.go watch higress-https ConfigMap 触发 Reconcile;pkg/cert/server.go 用 HTTPChallengeHandler 在 8889 处理 ACME 挑战。
第 2 周收官 🎓
🧠 第 2 周(服务发现与配置)你已掌握
- Day 06 多注册中心:8 种类型、Watcher 统一接口、BaseWatcher 组合
- Day 07 McpBridge CRD、Reconciler 控制循环、diff 式协调、watcher 工厂
- Day 08 Nacos 三代、轮询+订阅、generateServiceEntry
- Day 09 共享内存缓存、生产者-消费者、延迟删除、convertServiceEntry、全链路
- Day 10 config 模型复用 Istio、自动 HTTPS certmagic、HTTP-01 自举、ConfigMap 存储
你现在理解了 Higress 的两大特色能力:多注册中心服务发现(连接老微服务生态)和自动 HTTPS。第 3 周进入插件生态——Wasm 插件怎么写和加载。
✋ 动手
cd /Users/bitmart/work/codes/github/higress-group/higress
grep -n 'DefaultIngressClass\|RegistryTypeLabelKey' pkg/config/constants/constants.go
grep -n 'func InitCertMgr\|func.*Reconcile' pkg/cert/certmgr.go
grep -n 'func.*Present\|func.*CleanUp' pkg/cert/ingress.go