istiod 为什么被合并成一个
一句话总结
Istio 完全分离了“生成配置的一侧(istiod)”与“处理数据包的一侧(Envoy)”。因此,即使控制平面停止,流量仍能继续;反过来,只修改控制平面,也能改变整个 mesh 的行为。
为什么需要它
Istio 1.5 以前,Pilot(流量)、Citadel(证书)、Galley(配置验证)、Mixer(策略与遥测)分别作为独立 Pod 运行。四者相互调用,带来很高运维成本:某组件停止后,很难判断哪些功能受影响;尤其 Mixer 对每个请求都调用控制平面,使数据路径延迟和故障直接依赖控制平面。
因此,1.5 把 Pilot、Citadel、Galley 合并为单一二进制 istiod,Mixer 则在 1.8 完全移除。遥测改由 Envoy 内部 filter 直接生成。重点不是“减少组件”,而是彻底消除数据路径对控制平面的调用。
工作原理
istiod 监视 Kubernetes API,读取 Service、Endpoint、Pod 和 Istio CRD 的变化,将其翻译成 Envoy 可理解的配置,再通过 gRPC stream 推送。这套协议就是 xDS。
| API | 下发内容 |
|---|---|
| LDS | listener——监听哪个端口、使用什么协议 |
| RDS | route——把哪个请求发送到哪个 cluster |
| CDS | cluster——目的地组定义(LB、熔断、TLS) |
| EDS | endpoint——该 cluster 中实际 Pod IP |
| SDS | 证书与密钥 |
Istio 通过一条名为 ADS(Aggregated Discovery Service) 的 gRPC stream 发送这五类配置。原因不是带宽,而是顺序:若 endpoint(EDS)先于 cluster(CDS)到达,Envoy 会得到无处归属的地址;若 route(RDS)先于 listener(LDS),也没有附着位置。单一 stream 可以保证顺序,并原子替换配置。
在 Envoy 内,目的地使用如下名称。
outbound|9080|v2|reviews.default.svc.cluster.local
방향 포트 subset FQDN
能在 istioctl proxy-config cluster 中读懂该字符串,就掌握了一半。subset 位置为空,表示没有 DestinationRule;整个名称不存在,则表示该服务不在此 proxy 的视野中。
Pod 内的 istio-init 容器写入 iptables 规则,把流量转向 proxy。入站走 15006,出站走 15001。此时只有 UID 1337 的流量不重定向,因为它正是 istio-proxy 自身;若不排除,proxy 发出的数据包会再次回到 proxy,形成无限循环。还应记住 15008(HBONE 隧道)、15020(agent 聚合健康与指标)、15021(健康检查)、15090(Prometheus 指标),考试中的端口题就不易遗漏。
最后一个重要性质:即使所有 istiod 都停止,已运行的 Envoy 仍会按最后收到的配置处理流量。 停止的是新配置传播与证书续期,而非数据路径。因此 istiod 故障不是“立即全面故障”,而是“有期限状态”,证书寿命(默认 24 小时)成为实际计时器。
现场会遇到的情况
作者的家庭实验室有 7 个节点(cp-1/2/3 + gpu-a/b/c/d),在内核 6.14、containerd 1.7.27、Kubernetes v1.34.10 上运行 Cilium 1.20.1。它没有部署 sidecar mesh,这种对照反而有助理解 Istio。
该集群通过 kubeadm init --skip-phases=addon/kube-proxy,从一开始就不安装 kube-proxy。只要 kube-proxy 曾运行一次,就会在节点留下 KUBE-SERVICES / KUBE-SVC-* / KUBE-SEP-* chain;即使删除 DaemonSet,规则仍会残留并与 eBPF 数据路径冲突。实测 kube-proxy Pod 为 0,iptables KUBE- chain 也为 0。
同样的教训适用于 Istio:sidecar 注入会在 Pod 网络 namespace 内写入 iptables 规则。之后删除注入 label,已运行 Pod 的规则仍会保留,直到 Pod 重启。“label 已删除,为何仍经过 proxy?”答案就在这里。配置是声明式的,但留在节点和 Pod 中的痕迹是命令式的。
下一测验要确认什么
本模块只讲概念。完成测验检查架构理解后,下一模块会亲自编写 VirtualService 和 DestinationRule,观察前文的 outbound|포트|subset|FQDN 如何生成。