TT Lab
开始
学习 学习路径 课程

Istio 实测实验室

两扇门就要两个守卫

在 TT Lab 中继续学习

一句话总结

进入网格的入口(入口网关,ingress gateway)是单独运行的 Envoy,而不是 sidecar。在 Istio 中打开这个入口有两种方法——选中一个已经在运行的网关并在其上叠加配置的 Istio Gateway,以及用一个 Gateway 资源新建网关的 Kubernetes Gateway API。

为什么需要它

sidecar 处理的是 Pod 内部出入的流量。来自集群外用户的请求,必须在一个不属于任何 Pod 的 sidecar 的地方接收,并在那里解开 TLS、按主机名分流、拦住可疑的路径。Kubernetes 的 Ingress 资源要做这些事,表达能力不足——请求头条件、权重、TLS 方式,全都是各控制器各自不同的注解。

Istio 最初用自己的 API(Gateway + VirtualService)解决了这个问题,Kubernetes 汇集了这些经验,做出了厂商中立的 Gateway API。Istio 文档表示,今后会把 Gateway API 作为默认的流量管理 API。所以现在两种方式并行使用,同一个网格里出现两个入口是常有的事。

工作原理

Istio Gateway——选定网关,并规定要接收什么。

Gateway mall-gw          selector: istio=ingressgateway   ← 이미 떠 있는 파드를 고른다
  servers: 80 HTTP  mall.example.com
           443 HTTPS mall.example.com  credentialName: mall-cred
VirtualService mall-ingress   gateways: [mall-gw]          ← 어디로 보낼지는 여기서

只有 Gateway 的话,网关虽然会接收,但不知道往哪里转发,会返回 404。VirtualService 要在 gateways 中写上那个名称,两者才会连接起来。

TLS 通过 SDS 获取。credentialName 不是文件路径,而是 Secret 的名称。istiod 读取该 Secret,并通过 SDS 下发给网关 Envoy,所以更换证书时不需要重启网关。作为代价,Secret 必须与网关 Pod 位于同一个命名空间。

Gateway API——由 Gateway 来建立网关。

Istio Gateway Gateway API Gateway
网关 Pod 用选择器选取预先安装好的网关 为每个 Gateway 创建 <이름>-istio(占位符为名称)的 Deployment 和 Service
所在位置 通常是 istio-system Gateway 所在的命名空间
路由 VirtualService(gateways:) HTTPRoute(parentRefs:)
细节调整 IstioOperator、Helm 值 infrastructure.parametersRef 指向的 ConfigMap

自己建立网关,意味着各团队可以单独扩缩自己的入口。相应地 Pod 会增多,而且最重要的是每个入口都要单独设置策略。

授权策略同样挂在工作负载上。网关是 Envoy 工作负载,所以可以用选择器给它挂上 AuthorizationPolicy,在那里被拦下的请求不会进入网格内部。但如果选择器是 istio: ingressgateway,就不会作用于 Gateway API 新建的网关。

在现场相遇的样子

“Gateway 已创建,但 Programmed 没有成立”——自动部署出来的服务拿不到 LoadBalancer 地址时就会这样。在云上,常见原因是负载均衡器配额;在本地部署中,常见原因是没有 LB 实现。在这台 VM 的 k3s 上,80 端口已被另一个网关占用,新服务一直停在 <pending>。

“证书换了,但看到的还是旧证书”——Secret 创建在了别的命名空间,或者名称与 credentialName 不一致。用 istioctl proxy-config secret 查看网关实际收到的证书,马上就能分清。

“管理路径明明拦住了,从新网关却进得来”——新开了入口,却没有把守卫也一并布置过去。这就是添加网关时要一并检查授权策略的选择器(或 targetRefs)的原因。

官方文档:Ingress Gateways、Secure Gateways、Kubernetes Gateway API、Authorization on ingress gateways

下一项实验要做什么

在 VM 内真实的网格(k3s + Istio 1.31.0)中部署两套应用,用 Istio Gateway 打开 HTTP 和 HTTPS 入口,再用 Gateway API 建立第二个入口,按请求头和权重做分流。比较两个网关各自所处的位置,并用状态码确认:加在第一个入口上的 /admin 拦截,并不会作用于第二个入口。