LabHub
学习 学习路径 课程

ICA — Istio 认证助理

Gateway 开门,VirtualService 修路

在 LabHub 中继续学习

一句话总结

Gateway 只决定以什么端口、host 和 TLS 接收流量,接收后的路由全部由 VirtualService 完成。二者通过 VirtualService 的 gateways 字段连接。

概念图: 以什么端口、host 和 TLS 接收流量 · 职责分离 · 把配置附加到哪个 gateway Pod · Gateway Pod 所在 namespace

为什么需要它

Kubernetes Ingress 把入口与路由混在一个资源中,表达能力有限。基于 header 的路由、权重分配、TLS passthrough 等需求都落入控制器专用 annotation,最终 manifest 被绑定到特定 Ingress 控制器。

Istio 通过职责分离解决:Gateway 声明 gateway Pod 的 listener,路由则复用 mesh 内部的 VirtualService。因此,内部 east-west 路由与外部进入的 north-south 路由可以使用同一语法。

工作原理

Gateway 通过 spec.selector 选择把配置附加到哪个 gateway Pod,通常是 istio: ingressgateway。Gateway 资源不会创建 proxy,只为已有 Gateway Deployment 添加 listener 配置。

必须区分三种 TLS 模式。

模式 Gateway 的工作 所需内容
SIMPLE 终止 TLS,以明文向后转发 服务器证书(credentialName)
MUTUAL 终止 TLS,并验证客户端证书 服务器证书 + CA
PASSTHROUGH 不终止 TLS,只按 SNI 转发 无需证书

PASSTHROUGH 的协议不能写成 HTTPS,必须写成 TLS,因为 Gateway 不解析 HTTP;因此路由也不用 HTTP 规则,而使用 tls 块的 sniHostscredentialName 指向的 kubernetes.io/tls Secret 必须位于Gateway Pod 所在 namespace。把它放在应用 namespace,再疑惑为何未挂载,是常见事故。

绑定必须同时满足两个条件:VirtualService 的 gateways 中包含 Gateway 名称,且其 hosts 与 Gateway 的 server hosts 有交集。若同一规则也应用于 mesh 内流量,应在 gateways 中加入保留字 mesh

ServiceEntry 方向相反,它把mesh 外部服务带入 mesh。注册后,外部 API 也能应用 timeout、retry、mirroring 和 metrics。resolution 分为 STATIC(使用 endpoints 中 IP)、DNS(解析名称)、NONE(使用原请求地址)。若全局启用 outboundTrafficPolicy: REGISTRY_ONLY,不在 ServiceEntry 中的外部 host 会被阻止。

Sidecar 资源用途不同。默认所有 sidecar 都接收 mesh 中全部服务配置;服务数千时,仅配置就可能让 Envoy 内存膨胀数百 MiB。用 Sidecar 缩小 egress.hosts 后,只向 workload 下发其需要的范围。格式为 네임스페이스/호스트./* 表示自身 namespace,istio-system/* 表示控制平面 namespace。

还要了解发展方向:新 Ingress 推荐使用 Kubernetes Gateway API(Gateway + HTTPRoute);ambient 模式的 waypoint proxy 本身也用 Gateway API 的 Gateway 资源声明。Istio 专用 Gateway/VirtualService 会继续支持,但新标准功能会优先进入 Gateway API。

现场会遇到的情况

作者家庭实验室部署 Cilium Gateway API 时曾遇阻。安装 Gateway API CRD v1.2 后,控制器拒绝启动,原因是 tlsroutesreferencegrants 尚非 v1。升级 CRD 到 v1.6.1 后才正常。

同样的教训适用于 Istio:Gateway API 是独立项目,必须先在集群安装 CRD,且实现(Istio、Cilium)要与 CRD 版本匹配。“已执行 istioctl install,为何不能创建 HTTPRoute?”答案就在这里。同一实验室中 hubble-relay 与 hubble-ui 曾保持 Pending,也是类似问题:它们是 Deployment 而非 DaemonSet,不能容忍控制平面 taint;worker 加入后立即恢复。Gateway Deployment 也常因同一原因无法调度。

下一实验要做什么

实际创建 backend workload 与 kubernetes.io/tls Secret,再把 SIMPLE 和 PASSTHROUGH server 放进同一 Gateway,用 VirtualService 绑定;随后把外部支付 API 注册为 ServiceEntry,并用 Sidecar 把该 workload 的视野缩小到三个项目。