命名空间开关与注入触发机制
部署 bookinfo 之前,第一步不是编写 Deployment 配置,而是给目标命名空间打上启用注入的标签。在 Kubernetes 体系里,网格控制面会在命名空间上识别特定的启用标签,只有打了这个标签的命名空间,新建 Pod 时才会被自动注入机制拦截。
自动注入机制做的事情很克制:它不改动你的 Deployment 原文,而是在 Pod 创建的那一刻,向 Pod 规约里注入额外的容器和一些注解。命名空间级别的标签作为兜底策略,而具体 Deployment 的模板注解优先级更高,适合灰度个别服务的场景。
注入结果上,原本 bookinfo 里的某个服务 Pod 只有业务容器处于就绪状态,注入后变成两个容器就绪:一个是原有的业务容器,一个是 Sidecar 代理容器,另外还有一个启动完就退出的初始化容器。业务代码一行没改,服务却已经被包裹进了网格。
注入后 Pod 的内部结构
理解流量劫持之前,先把 Pod 内部分清三个角色的职责。
业务容器照常绑定自己的服务端口,它完全不知道旁边多了个代理,发送请求时仍走本地的网络栈和默认路由。它与 Sidecar 代理容器共享同一个网络命名空间,因此两者看到的是同一份网络配置、同一套网络规则。
初始化容器是启动后即退出的临时容器,它的镜像与 Sidecar 代理容器同源。启动时它拿到网络管理权限,在 Pod 的网络命名空间里写入网络转发规则,写入完成后即退出。它特意为 Sidecar 代理进程保留了一个专属的用户标识,规则里自家的流量不再二次重定向就是靠这个标识来规避死循环。
Sidecar 代理容器是常驻容器,里面运行着代理控制进程和代理数据面进程两个角色。代理控制进程负责从控制面拉取配置、启动代理数据面、维护热重启;代理数据面监听两个端口,一个处理入站流量,一个处理出站流量,所有被网络规则拐进来的流量都先到它手里,再由它按照各种路由规则决定往哪里转发。
流量劫持的两条链路
初始化容器退场后,Pod 里留下了关键的转发规则。这些规则覆盖了两个方向的流量。
入站方向:外部发往业务容器服务端口的网络包,进入网络层后被规则匹配,重定向到 Sidecar 代理的入站监听端口。Sidecar 代理在这个端口上解开包,发现目标端口是业务容器的服务端口,查控制面下发的监听器配置,决定转发给本 Pod 的业务容器。这一步对业务容器完全透明——它以为客户端直连,其实中间经过了一次代理。
出站方向:业务容器想调用其他服务时,进程自然发起网络请求到目标服务的地址,包发出后被规则拦截。规则里先排除 Sidecar 代理自身发出的流量,避免代理发出的请求再被自己劫持,其余流量重定向到 Sidecar 代理的出站监听端口。Sidecar 代理在这个端口上按服务发现把目标地址解析成具体的端点,做负载均衡、重试、加密传输卸载,再发往对端的 Sidecar 代理或服务端。
这种重定向模式的代价是原始目标地址在转发给代理时丢失了,需要代理靠协议层的信息来还原。这也是为什么服务网格对七层协议能玩出细粒度路由的原因——协议信息得在代理里重新解析。
bookinfo 调用链上的实际劫持路径
把抽象的逻辑放到 bookinfo 的具体调用链上更容易理解。用户访问产品页面的入口流量,先进产品页面 Pod 的入站监听端口,Sidecar 代理转给本地的产品页面容器;产品页面容器里代码调用详情服务和评论服务的地址,这两个域名解析成服务地址后,出站包被本 Pod 的出站规则劫持;Sidecar 代理按评论服务的目标规则挑选某个版本,发到目标评论服务 Pod 的入站监听端口,再转给目标评论服务容器;评论服务容器内再调用评分服务,同样走一遍评分服务 Pod 的出站到入站的完整路径。
全程多次跨 Pod 调用,业务代码没有任何软件开发工具包的植入,超时、熔断、按请求头切版本、调用链追踪,全在两侧的 Sidecar 代理上完成。这也是 Sidecar 模式的核心卖点:治理逻辑与业务逻辑完全正交,互不干扰。
控制面如何喂饱 Sidecar
仅有网络规则只解决了流量进入代理的问题,代理还得知道收到流量之后怎么处理。控制面通过一套标准协议向每个 Sidecar 代理推送配置信息。
配置信息包括监听器和上游集群的定义,比如某个入站端口对应哪个服务、出站某个服务包含哪些端点;路由规则,bookinfo 里经典的按请求头路由到特定版本就在这里配置;端点发现,Pod 地址变化时自动刷新;证书分发,双向加密传输的客户端和服务端证书由控制面签发下发。
在天翼云服务网格里,这套控制面以托管形式存在,用户不需要自行运维控制面组件,但 Pod 里的代理控制进程仍通过内部地址连接控制面拉取配置。如果命名空间打了注入标签但控制面没有把该集群纳入管理,Pod 会注入成功但代理拿不到配置,入站端口收到流量后只能返回错误或拒绝连接——这是排障时第一眼要区分的注入成功但配置为空的状态。
排障视角:从就绪正常到流量不通
开发工程师在容器控制台看 bookinfo 最常遇到几类现象。
其一是 Pod 起不来,就绪状态卡在业务容器就绪但代理容器未就绪。多半是初始化容器没有权限写入网络规则,检查 Pod 的安全策略是否放行了必要的网络管理权限,或者是否使用了容器网络接口插件来替代初始化容器。天翼云托管网格通常默认配好容器网络接口模式,但自建节点池若关闭了对应插件就会卡在初始化阶段。
其二是 Pod 就绪正常但页面报错。进入产品页面 Pod 检查代理监听端口是否正常、网络规则是否包含预期的转发链、代理容器日志是否报连接控制面超时,能迅速定位是控制面断连还是规则缺失。
其三是部分流量通部分流量不通。这通常与路由规则有关——比如评论服务的某个版本没有正常启动,但目标规则仍然把流量分配到了那个版本。检查目标规则和端点状态,确认所有版本都处于健康状态。
结语
bookinfo 在服务网格里的运行机制,本质上是通过自动注入把 Sidecar 塞进 Pod,通过网络规则把流量拐进代理,通过控制面下发配置让代理知道怎么转发。业务代码一行不改,服务治理能力却全部到位。对于开发工程师来说,理解这套机制的价值不在于记住具体的端口号和规则写法,而在于建立一种思维:在云原生架构里,基础设施和能力是可以与业务逻辑解耦的。Sidecar 注入与流量劫持只是这个思路在服务网格领域的一个具体体现。当你理解了流量怎么进的代理、代理怎么知道往哪转,你就能在排障时快速定位问题,在设计架构时做出更合理的决策。