Cilium 本地重定向策略(LRP)实战指南:从 cilium-dbg lrp 命令到 eBPF 数据面原理 📅 发布时间:2026/9/13 14:29:49 👁 浏览次数: Cilium 本地重定向策略LRP实战指南从 cilium-dbg lrp 命令到 eBPF 数据面原理【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium导读本文以 Cilium 的cilium-dbg lrp命令族为主线系统讲解 Local Redirect Policy本地重定向策略简称 LRP的完整使用闭环如何用命令行管理策略、如何在 Kubernetes 中通过CiliumLocalRedirectPolicyCRD 定义AddressMatcher与ServiceMatcher两种策略类型、如何在 eBPF 数据面验证重定向生效并深入节点级 DNS 缓存等典型场景。读完本文你将掌握从策略创建、查询到故障排查的完整实战技能同时理解 LRP 在 pkg/loadbalancer/redirectpolicy 控制器与 BPF 数据面中的底层工作方式。cilium-dbg lrp 命令概览cilium-dbg lrp是 Cilium 命令行工具中负责管理本地重定向策略的子命令族其定义位于 cilium-dbg/cmd/lrp.govar LRPCmd cobra.Command{ Use: lrp, Short: Manage local redirect policies, }命令文档见 Documentation/cmdref/cilium-dbg_lrp.md其顶层命令本身不执行任何操作仅作为命名空间承载list子命令cilium-dbg lrp顶层选项选项说明-h, --help显示lrp命令的帮助信息继承自父命令的全局选项所有cilium-dbg子命令都会继承以下全局选项在通过kubectl exec进入 Cilium agent Pod 内执行时通常无需改动但了解其含义有助于在独立运行调试时正确连接 API选项默认值说明--config string$HOME/.cilium.yaml配置文件路径-D, --debug关闭输出调试日志-H, --host string本地 Unix socket服务端 API 的 URI--log-driver strings-日志端点示例syslog--log-opt map-日志驱动选项示例formatjson核心子命令cilium-dbg lrp listcilium-dbg lrp list用于列出当前节点上生效的本地重定向策略完整命令文档见 Documentation/cmdref/cilium-dbg_lrp_list.mdcilium-dbg lrp list [flags]专属选项选项说明-h, --help显示list命令帮助-o, --output string输出格式支持json、yaml、jsonpath{}list同时注册了别名ls源码见 cilium-dbg/cmd/lrp_list.go因此cilium-dbg lrp ls与cilium-dbg lrp list等价。输出字段解读不带-o参数时命令通过tabwriter输出人类可读的表格printLRPListLRP namespace LRP name FrontendType Matching Service每个策略条目包含四个核心列LRP namespace / LRP name策略对象的元数据与kubectl get ciliumlocalredirectpolicies中的命名空间与名称一一对应FrontendType策略匹配的前端类型常见取值为clusterIP all svc portsServiceMatcher 且未限定端口等Matching Service命中的 Kubernetes Service格式为namespace/serviceName。每个策略下方还会逐行打印前端到后端的映射明细格式由 getPrintableMapping 生成frontend-ip:frontend-port/protocol - backend-ip:backend-port(pod-namespace/pod-name), ...例如在节点级 DNS 缓存场景中的典型输出LRP namespace LRP name FrontendType Matching Service kube-system nodelocaldns clusterIP all svc ports kube-system/kube-dns | 10.96.0.10:53/UDP - 10.244.1.49:53(kube-system/node-local-dns-72r7m), | 10.96.0.10:53/TCP - 10.244.1.49:53(kube-system/node-local-dns-72r7m),这表示发往 ClusterIP10.96.0.10的 UDP/TCP53端口流量会被重定向到本节点node-local-dns-72r7mPod 的53端口。底层实现调用链从源码调用链看listLRPs会先通过 Cilium agent 的客户端调用client.GetLRPs()获取策略列表cilium-dbg/cmd/lrp_list.go该 API 返回[]*models.LRPSpec其中FrontendMappings携带每个前端地址对应的本节点后端 Pod 列表。当指定-o参数时命令改用结构化输出json/yaml/jsonpath便于脚本与自动化工具消费此时每个条目会完整暴露LRPSpec的全部字段。Local Redirect Policy 功能原理理解命令输出前需要先掌握 LRP 的定位LRP 使发往某个 IP:端口/协议 元组或 Kubernetes Service 的 Pod 流量在节点本地被 eBPF 重定向到本节点上的后端 Pod且后端 Pod 的命名空间需与策略命名空间一致。LRP 通过CiliumLocalRedirectPolicyCustomResourceDefinition 进行配置完整功能文档见 Documentation/network/kubernetes/local-redirect-policy.rst。策略 CRD 的类型定义位于 pkg/k8s/apis/cilium.io/v2/clrp_types.go其 Spec 由三部分组成字段必填说明redirectFrontend是待重定向的流量匹配条件addressMatcher与serviceMatcher二选一不可同时为空redirectBackend是重定向目标localEndpointSelector选择本节点上的后端 PodtoPorts指定目标端口skipRedirectFromBackend否默认false见后文“高级配置”注意 CRD 通过 OpenAPIXValidation规则将redirectFrontend、redirectBackend、skipRedirectFromBackend标记为不可变immutable即策略一旦创建后这些字段不可修改这也是官方文档强调“更新需删除重建”的底层原因。策略如何处理控制器视角从源码结构看LRP 的编排由 pkg/loadbalancer/redirectpolicy 包负责控制器监听CiliumLocalRedirectPolicy资源与 Pod/Service 变更动态维护LRPSpec与后端映射关系最终将结果同步为LocalRedirect类型的负载均衡服务条目同一目录下的testdata/*.txtar测试用例如 pkg/loadbalancer/redirectpolicy/testdata/address.txtar、node-local-dns.txtar覆盖了端口命名、地址冲突、Pod 就绪状态等边界场景可用于深入理解控制器行为。启用 LRP前置条件LRP 默认未启用需要通过 Helm 开启并重启相关组件helm upgrade cilium cilium/cilium --namespace kube-system --reuse-values \ --set localRedirectPolicies.enabledtrue kubectl rollout restart deploy cilium-operator -n kube-system kubectl rollout restart ds cilium -n kube-system随后验证 agent 与 operator Pod 恢复 Running并确认 CRD 已注册kubectl -n kube-system get pods -l k8s-appcilium kubectl -n kube-system get pods -l namecilium-operator kubectl get crds | grep ciliumlocalredirectpolicies # ciliumlocalredirectpolicies.cilium.io 2020-08-24T05:31:47Z数据面选型四种 Helm 组合LRP 支持 socket 级负载均衡与 tc 负载均衡两种数据面实现官方文档给出了四种经过验证的 Helm 组合完整 kube-proxy 替换用 Cilium eBPF 实现替代 kube-proxy 并启用 LRPkubeProxyReplacement: true localRedirectPolicies: enabled: true绕过 Pod 命名空间内的 socket 级负载均衡适用于 Pod 命名空间存在自定义重定向规则、与 socket 负载均衡冲突的场景kubeProxyReplacement: true socketLB: hostNamespaceOnly: true localRedirectPolicies: enabled: true仅启用 socket 级负载均衡保留 kube-proxy 处理整体 Service仍可使用 LRPkubeProxyReplacement: false socketLB: enabled: true localRedirectPolicies: enabled: true仅处理来自 Pod 的 ClusterIP 访问其余 kube-proxy 替换全部关闭注意此配置下宿主机命名空间的 Pod 流量不受 LRP 处理kubeProxyReplacement: false localRedirectPolicies: enabled: true部署示例后端与客户端 Pod以官方示例 examples/kubernetes-local-redirect/backend-pod.yaml 部署后端 Pod其标签、容器端口/协议需与后续 LRP 的localEndpointSelector、toPorts一致kubectl apply -f examples/kubernetes-local-redirect/backend-pod.yaml kubectl get pods | grep lrp-pod # lrp-pod 1/1 Running 0 46s再部署用于产生流量的客户端 Podexamples/kubernetes-dns/dns-sw-app.yamlkubectl create -f examples/kubernetes-dns/dns-sw-app.yaml kubectl wait pod/mediabot --forconditionReady策略类型一AddressMatcher按 IP:端口 匹配AddressMatcher 用IP 地址 L4 端口/协议精确匹配不属于任何 Kubernetes Service 的流量。要点前端toPorts中配置多个端口时端口必须命名端口名用于前端端口与后端端口的映射redirectBackend.toPorts指定的端口必须真实存在于后端 Pod 的 spec 中localEndpointSelector用于在本节点选择接收重定向流量的后端 Pod。完整示例见 examples/kubernetes-local-redirect/lrp-addrmatcher.yaml将发往169.254.169.254:8080/TCP的流量重定向到标签为appproxy、监听80/TCP的后端 PodapiVersion: cilium.io/v2 kind: CiliumLocalRedirectPolicy metadata: name: lrp-addr spec: redirectFrontend: addressMatcher: ip: 169.254.169.254 toPorts: - port: 8080 protocol: TCP redirectBackend: localEndpointSelector: matchLabels: app: proxy toPorts: - port: 80 protocol: TCP应用并验证kubectl apply -f examples/kubernetes-local-redirect/lrp-addrmatcher.yaml kubectl get ciliumlocalredirectpolicies | grep lrp-addr从类型定义看clrp_types.goaddressMatcher.ip支持 IPv4 与 IPv6toPorts[].protocol仅接受TCP与UDPtoPorts[].port必须是合法的 uint16 端口字符串。验证service list 与 curl在与lrp-pod同一节点的 Cilium Pod 中执行cilium-dbg service list可以看到 eBPF kube-proxy replacement 创建了一条LocalRedirect类型的服务条目其后端正是策略选中的lrp-pod的 IPkubectl describe pod lrp-pod | grep IP: # IP: 10.16.70.187 kubectl exec -it -n kube-system cilium-5ngzd -- cilium-dbg service list # ID Frontend Service Type Backend # 4 172.20.0.51:80 LocalRedirect 1 10.16.70.187:80从客户端 Pod 发起请求验证重定向生效kubectl exec mediabot -- curl -I -s http://169.254.169.254:8080/index.html # HTTP/1.1 200 OK # Server: nginx/1.19.2最后用 tcpdump需在lrp-pod所在节点执行确认流量确实打到了后端 Pod 的 80 端口sudo tcpdump -i any -n port 80 # 01:36:24.608566 IP 10.16.215.55.60876 10.16.70.187.80: Flags [S], seq 2119454273, ... # 01:36:24.609007 IP 10.16.70.187.80 10.16.215.55.60876: Flags [P.], seq 1:239, ... HTTP/1.1 200 OK集群级地址白名单可通过 Helm 的localRedirectPolicies.addressMatcherCIDRs选项在全集群范围内约束允许被 AddressMatcher 重定向的地址例如只允许169.254.169.254localRedirectPolicies: enabled: true addressMatchCIDRs: - 169.254.169.254/32超出白名单的地址会被 cilium-agent 拒绝并输出警告日志。冲突保护AddressMatcher 仅面向不属于任何 Kubernetes Service 的 IP。若redirectFrontend.addressMatcher中的 IP:端口/协议 与某个ClusterIPService 前端重合策略不会覆盖该地址——Cilium 拒绝覆盖其他 Service 拥有的前端并记录日志LocalRedirectPolicy matches an address owned by an existing service refusing to override此时应改用 ServiceMatcher 类型。策略类型二ServiceMatcher按 Service 匹配ServiceMatcher 用Kubernetes Service 的名称与命名空间匹配需要重定向的流量要求 Service 类型为clusterIP。要点若redirectFrontend不指定toPorts则该 Service 的全部端口流量都会被重定向只重定向部分端口时需在 spec 中显式列出且多端口时必须命名端口名用于前后端端口映射策略应用后eBPF kube-proxy replacement 创建的既有 Service 条目会被替换为类型LocalRedirect的新条目且该条目只允许包含节点本地的后端 Pod。先部署 Serviceexamples/kubernetes-local-redirect/k8s-svc.yaml并确认其 ClusterIP 与 Service 条目kubectl apply -f examples/kubernetes-local-redirect/k8s-svc.yaml kubectl get service | grep my-service # my-service ClusterIP 172.20.0.51 none 80/TCP 2d7h kubectl exec -it -n kube-system ds/cilium -- cilium-dbg service list # ID Frontend Service Type Backend # 4 172.20.0.51:80 ClusterIP再创建 ServiceMatcher 类型的策略examples/kubernetes-local-redirect/lrp-svcmatcher.yamlapiVersion: cilium.io/v2 kind: CiliumLocalRedirectPolicy metadata: name: lrp-svc spec: redirectFrontend: serviceMatcher: serviceName: my-service namespace: default redirectBackend: localEndpointSelector: matchLabels: app: proxy toPorts: - port: 80 protocol: TCP应用后再次查看 Service 条目可见其类型已变为LocalRedirect后端为本节点上被策略选中的 Podkubectl apply -f examples/kubernetes-local-redirect/lrp-svcmatcher.yaml kubectl get ciliumlocalredirectpolicies | grep svc kubectl exec -it -n kube-system cilium-5ngzd -- cilium-dbg service list # ID Frontend Service Type Backend # 4 172.20.0.51:80 LocalRedirect 1 10.16.70.187:80客户端请求与 tcpdump 验证方式与 AddressMatcher 一致只是目标改为 ClusterIPkubectl exec mediabot -- curl -I -s http://172.20.0.51/index.html # HTTP/1.1 200 OK高级配置skipRedirectFromBackend默认情况下skipRedirectFromBackend: false包括后端 Pod 自身在内的所有来源只要流量匹配前端都会被重定向。某些场景下用户希望后端 Pod 发往策略前端的流量不要被重定向回自身而是直接转发到原始前端地址此时可在 spec 中设置spec: skipRedirectFromBackend: true该能力依赖getsockopt()的SO_NETNS_COOKIE选项判断来源网络命名空间该选项自 Linux 内核 5.7 起对 BPF 程序可用5.12 起对用户空间暴露因此要求内核版本 5.12。此外自 Cilium 1.16.0 起若要对已应用策略启用该配置需要先删除并重新创建既有策略及其选中的后端 Pod该字段同样被 CRD 标记为不可变。已知限制不迁移既有连接LRP 只重定向策略生效后新建的连接对策略匹配范围内已存在的、指向远端 Pod 的活动连接可能不会重定向。要确保全部连接都走本地重定向应在配置策略后重启客户端 Pod。不支持更新LRP 更新目前不被支持任何变更都需要删除旧策略后重新创建与 CRD 的字段不可变校验一致。典型场景Node-local DNS Cache节点级 DNS 缓存LRP 最经典的用例是让集群内 DNS 查询优先命中节点本地的 DNS node-cache Pod避免应用 Pod 的 DNS 请求跨节点转发到kube-dns后端从而降低延迟并减少网络开销。部署 node-local-dns两种部署方式快速部署使用仓库提供的 examples/kubernetes-local-redirect/node-local-dns.yaml其默认值已填充__PILLAR_LOCAL_DNS__与__PILLAR_DNS_DOMAIN__若集群 DNS Service 不同需按官方 NodeLocal DNSCache 配置说明替换__PILLAR__DNS__SERVER__等模板变量kubedns$(kubectl get svc kube-dns -n kube-system -o jsonpath{.spec.clusterIP}) \ sed -i s/__PILLAR__DNS__SERVER__/$kubedns/g; node-local-dns.yaml kubectl apply -f node-local-dns.yaml手动配置需保证 node-local DNS 镜像版本 1.15.16以获得禁用 dummy 网卡创建/删除的开关为 node-cache 追加-skipteardowntrue、-setupinterfacefalse、-setupiptablesfalse参数DaemonSet 设置hostNetwork: false使其运行在非宿主机命名空间Corefile 中绑定0.0.0.0而非静态 IP并相应调整 health-check 与 readinessProbe 的地址配置。部署对应的 LRP使用 examples/kubernetes-local-redirect/node-local-dns-lrp.yaml 将 DNS 流量导向本地缓存kubectl apply -f examples/kubernetes-local-redirect/node-local-dns-lrp.yaml注意事项示例默认以kube-dns作为集群 DNS Service若实际名称不同需修改策略命名空间需与集群 DNS Service 所在命名空间一致示例使用dns、dns-tcp两个端口名需与部署 yaml 中的端口名保持一致。验证与排障所有node-local-dnsPod 就绪后DNS 流量即会先走本地缓存。可通过访问node-local-dns Pod IP:9253/metrics观察coredns_dns_requests_total指标是否随应用 Pod 发起 DNS 请求而增长来确认。排障三步走确认 node-local-dns Pod 运行就绪kubectl --namespace kube-system get pods --selectork8s-appnode-local-dns # node-local-dns-72r7m 1/1 Running 0 2d2h用本文主角cilium-dbg lrp list检查策略是否在所有 agent 上正确生效kubectl exec -it cilium-mhnhz -n kube-system -- cilium-dbg lrp list # LRP namespace LRP name FrontendType Matching Service # kube-system nodelocaldns clusterIP all svc ports kube-system/kube-dns # | 10.96.0.10:53/UDP - 10.244.1.49:53(kube-system/node-local-dns-72r7m), # | 10.96.0.10:53/TCP - 10.244.1.49:53(kube-system/node-local-dns-72r7m),检查LocalRedirectService 条目是否创建若条目缺失可能是策略应用与 node-local DNS DaemonSet Pod 资源之间存在竞态可尝试重启 node-local DNS DaemonSet Pod问题持续时建议在官方仓库提交 issue 并附带 sysdump 数据kubectl exec -it cilium-mhnhz -n kube-system -- cilium-dbg service list | grep LocalRedirect # 11 10.96.0.10:53 LocalRedirect 1 10.244.1.49:53 (active)总结Local Redirect Policy 借助 Cilium eBPF 数据面将“匹配指定地址/Service 的流量在节点内就地重定向”变成了声明式配置cilium-dbg lrp list负责从 agent 侧快速查看策略与前后端映射CiliumLocalRedirectPolicyCRD 负责声明AddressMatcher与ServiceMatcher两种匹配语义pkg/loadbalancer/redirectpolicy控制器与LocalRedirect服务条目则构成其数据面落地路径。无论是节点级 DNS 缓存、还是将特定 IP:端口 流量导向本机代理掌握上述命令、配置与验证手段即可在生产集群中可靠落地并通过cilium-dbg lrp list与cilium-dbg service list的组合完成日常巡检与排障。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考