【Linkerd】流量重定向:linkerd-init、CNI 与 opaque 端口
内容提要
本文介绍Linkerd 2.20中Pod流量如何透明进入linkerd-proxy。默认路径通过linkerd-init容器设置iptables重定向TCP流量;启用CNI插件时由节点级DaemonSet写入规则,无需init容器。opaque端口跳过协议探测但流量仍经proxy,skip端口则完全旁路。排障需先确认重定向机制生效,再检查identity或destination问题。
延伸解读
两条重定向路径的差异与选择
Linkerd 提供两种将流量透明引入 proxy 的方式:默认的 linkerd-init 容器通过 iptables 规则实现,需要 Pod 具备 CAP_NET_ADMIN 权限;而 CNI 插件则通过节点级 DaemonSet 写入规则,避免在 Pod 中运行特权容器。选择 CNI 路径时,需注意安装顺序:必须先安装 CNI 插件,再安装控制面并启用 --linkerd-cni-enabled,否则已运行的 Pod 可能缺少规则,导致只有旧 Pod 流量异常。
opaque 端口与 skip 端口的本质区别
opaque 端口和 skip 端口虽然都影响流量路径,但作用完全不同。opaque 端口仍将流量送入 proxy,只是跳过协议探测,按 TCP 流转发,因此 mTLS 和指标仍然保留;而 skip 端口则通过修改 iptables 规则,使流量完全绕过 proxy,不经过 mesh。排障时需先分清是哪种配置,再检查 NetworkPolicy 是否放行 proxy 的 inbound 端口(默认 4143),否则即使配置了 opaque,也可能因策略拒绝而连接失败。
重定向失败的常见表象与排查顺序
当流量未进入 proxy 时,常见表象包括:Pod 内 curl 直连 Service IP 绕过 mesh、linkerd-init CrashLoopBackOff、仅 CNI 集群无 init 但流量未进 proxy 等。排查时应先确认注入与 proxy 监听,再检查 init 或 cniEnabled 是否生效,然后针对可疑端口检查 opaque/skip 与 NetworkPolicy,最后才进入 identity 或 destination 日志。避免一开始就调整 ServiceProfile 超时,而
Q&A
Linkerd 中 linkerd-init 容器的作用是什么?
linkerd-init 是一个 init 容器,在应用容器启动前运行,通过 iptables 规则将 Pod 的 TCP 流量重定向到本机 linkerd-proxy 监听的端口,从而实现透明代理。它需要 CAP_NET_ADMIN 权限,规则写入后容器退出,但规则保留在 Pod 网络命名空间内。
Linkerd CNI 插件与默认的 linkerd-init 路径有什么区别?
默认路径下,proxy-injector 在 Pod 中注入 linkerd-init 容器,由该容器设置 iptables 规则。启用 CNI 插件时,由节点级 DaemonSet(linkerd-cni)在 Pod 网络配置阶段写入等价的 iptables 规则,因此 Pod 中不再需要 linkerd-init 容器。CNI 插件通过 chaining 与现有 CNI 共存,安装时需先安装 CNI DaemonSet,再在控制面安装时指定 --linkerd-cni-enabled。
Linkerd 中 opaque 端口和 skip 端口有什么区别?
opaque 端口(通过 config.linkerd.io/opaque-ports 注解配置)跳过协议探测,但流量仍经过 proxy,因此 mTLS 和 TCP 指标保留。skip 端口(如 skip-inbound-ports 和 skip-outbound-ports)则修改 iptables,使流量完全不经过 proxy,因此没有 mTLS 和指标。
在 Linkerd 中,如果启用了 CNI 但未正确安装,会出现什么现象?
如果先安装控制面再补装 CNI DaemonSet,已运行的 meshed Pod 可能长期缺少节点级规则,导致流量未重定向,而新建 Pod 在 CNI 就绪后表现正常,形成只有旧 Pod 不正常的现象。修复通常需要滚动 Pod 或确认节点 CNI 配置已链入。
Linkerd 中 native sidecar 与 legacy 模式在流量重定向方面有何不同?
在 2.20 版本中,默认启用 native sidecar,proxy 在应用 initContainers 之前启动,因此需要网络的 init 容器可以直接出网。在 legacy 模式下,proxy 晚于所有 init 容器启动,init 容器发出的包可能被 iptables 截获而 proxy 尚未监听,此时需让 init 以 proxy UID(默认 2102)运行以跳过规则。
如何排查 Linkerd 中流量未进入 proxy 的问题?
排查时先确认注入(轴1)和重定向机制(轴2)是否生效:检查 Pod 中是否有 linkerd-init 容器或集群是否启用 cniEnabled;确认 iptables 规则是否存在;检查是否误用 skip 注解。然后检查 proxy 监听端口(inbound 4143、outbound 4140)和 NetworkPolicy 是否放行。最后才进入 identity 或 destination 日志。