拓冰建站拓冰建站
首页 / 资讯中心 / 正文

如何用 Cilium Egress Gateway 将 Pod 出集群流量经固定网关节点 SNAT 转发

如何用 Cilium Egress Gateway 将 Pod 出集群流量经固定网关节点 SNAT 转发【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium如果你的 Pod 出集群的流量需要集中走某台固定节点例如老防火墙只放行固定出口 IPCilium 的 Egress Gateway 功能可以把来自特定 Pod、发往集群外 CIDR 的 IPv4/IPv6 连接统一重定向到指定的网关节点并用该节点上可预测的出口 IP 做 masqueradeSNAT。本文基于 Cilium 官方文档 Egress Gateway覆盖启用功能、编写CiliumEgressGatewayPolicy、按官方测试流程验证的完整路径。适用前提Cilium 已正确安装在 Kubernetes 集群中可运行cilium status确认。前提条件在动手之前确认以下条件都满足网关节点的网卡与 IP 已由运维预先配好。Cilium 直接使用网关节点上的网络接口和 IP这部分取决于你的网络环境。例如在 AWS/EKS 上通常需要创建并挂载一个或多个 Elastic Network Interface 并配上 IP其他云厂商有类似的构造方式。必须同时开启 BPF masquerade 和 kube-proxy replacement二者是 egress gateway 的硬性要求。身份存储必须用 Kubernetes CRD 模式。egress gateway 与kvstore身份分配模式不兼容需保证identityAllocationMode为crd新安装的默认值。与以下功能不兼容Cluster Mesh网关节点必须与所选 Pod 在同一集群、CiliumEndpointSlice。无论以哪种方式配置出口 IP都要通过 agent 选项--devices确保 Cilium 运行在所选的出集群网卡上。启用 Egress Gateway 功能文档给出两种等价方式任选其一。Helm 方式升级 Cilium chart 并追加三个--set参数。chart引用替换为你安装 Cilium 时使用的 chart 引用chart 名称加版本或 OCI 镜像地址与现有安装保持一致helm upgrade cilium chart引用 \ --namespace kube-system \ --reuse-values \ --set egressGateway.enabledtrue \ --set bpf.masqueradetrue \ --set kubeProxyReplacementtrueConfigMap 方式在 Cilium 的 ConfigMap 中设置以下三个键enable-bpf-masquerade: true enable-egress-gateway: true kube-proxy-replacement: true无论用哪种方式改完后都要滚动重启 agent 和 operator 使配置生效kubectl rollout restart ds cilium -n kube-system kubectl rollout restart deploy cilium-operator -n kube-system编写 CiliumEgressGatewayPolicy驱动该功能的 API 是集群作用域的CiliumEgressGatewayPolicyCRD因此metadata中不要写namespaceapiVersion: cilium.io/v2 kind: CiliumEgressGatewayPolicy metadata: name: example-policy选择源 Podselectors通过标签选择器匹配源 Pod支持matchLabels和matchExpressions也可以写多个podSelector。要限定某个 namespace用特殊标签io.kubernetes.pod.namespace要限定 Pod 所在的节点可追加nodeSelector它不能单独使用必须与podSelector搭配。注意只有安全身份相关的标签才会被计入selectors: - podSelector: matchLabels: org: empire class: mediabot io.kubernetes.pod.namespace: default nodeSelector: # 可选不写则策略对所有节点生效 matchLabels: node.kubernetes.io/name: node1选择目的地址用destinationCIDRs指定一条或多条出集群 CIDR集群内部 IPPod、Node、API Server即使落在范围内也会被自动排除在 SNAT 逻辑之外。可用excludedCIDRs在大段中挖出例外例如destinationCIDRs为a.b.0.0/16而excludedCIDRs为a.b.c.0/24时只有发往a.b.c.0/24的流量不走 egress gatewaydestinationCIDRs: - a.b.c.d/32 - e.f.g.0/24 - a:b::/48 excludedCIDRs: - a.b.c.0/24选择网关节点与出口 IPegressGateway.nodeSelector按节点标签匹配网关节点。若多个节点同时匹配会取按名称字典序的第一个若没有任何节点匹配Cilium 会直接丢弃命中这些目的 CIDR 的流量。出口网卡和出口 IP 有三种配置方式三选一# 方式 1指定网卡使用该网卡上的第一个 IPv4 与 IPv6 地址 egressGateway: nodeSelector: matchLabels: testLabel: testVal interface: ethX # 方式 2显式指定出口 IP出集群网卡由数据通路按报文动态做路由查找确定 # 注意该 IP 必须已分配到节点上的某个网络设备 egressGateway: nodeSelector: matchLabels: testLabel: testVal egressIP: a.b.c.d # 方式 3两者都省略选择拥有默认路由的网卡并用其第一个 IPv4/IPv6 作为出口 IP egressGateway: nodeSelector: matchLabels: testLabel: testVal使用限制均直接来自文档配置前务必核对egressIP和interface不能同时出现同时出现的策略会被 Cilium 忽略如果 Cilium 无法为策略选出出口 IP例如egressIP没有配置在网关节点的任何网卡上网关节点会以No Egress IP configured为由丢弃命中策略的流量Cilium 选定或选定失败网卡与出口 IP 后不会自动响应网关节点网络配置的后续变化如 IP 被添加或删除。此时重新 apply 一次该策略可以强制重新选择也可以在同一策略里用egressGateways列表选择多个网关节点每个条目配置项与egressGateway完全相同同一端点只会被分配到其中一个网关按 CiliumEndpoint 的 UID 决定列表成员发生变化时端点会重新分配。完整测试流程客户端 Pod 外部 Nginx文档给出的测试假设一个两节点集群节点 IP 分别为192.168.60.11node1和192.168.60.12node2客户端 Pod 部署在 node1策略把 node2 选为网关节点。准备一个可观测出口的外部服务可选如果没有现成的外部服务可以在集群之外的一台 Linux 主机上装 Nginx用它的访问日志观察请求实际来自哪个 IP。以下两条命令会在该外部主机上安装并启动系统 nginx 服务需要 root 权限sudo apt install nginx sudo systemctl start nginx文档示例中该主机的 IP 为192.168.60.13把它作为出口流量的目的地址。部署客户端 Pod仓库中提供了现成的客户端示例 examples/kubernetes-dns/dns-sw-app.yaml名为mediabot的 Pod带org: empire和class: mediabot标签kubectl create -f examples/kubernetes-dns/dns-sw-app.yaml kubectl get pods文档示例输出仅供对照实际时间戳和镜像解析结果会有差异NAME READY STATUS RESTARTS AGE mediabot 1/1 Running 0 14s先做一次基线请求kubectl exec mediabot -- curl http://192.168.60.13:80此时在外部主机上查看 Nginx 访问日志tail /var/log/nginx/access.log文档示例输出192.168.60.11 - - [04/Apr/2021:22:06:57 0000] GET / HTTP/1.1 200 612 - curl/7.52.1因为客户端 Pod 跑在192.168.60.11节点上且尚未配置 egress gateway 策略流量会带着所在节点的 IP 出集群——这正是没有策略时的预期行为。给网关节点打标签并应用策略仓库中的示例策略文件是 examples/kubernetes-egress-gateway/egress-gateway-policy.yaml按文档要求做两处调整把destinationCIDRs改成包含你的外部服务 IP例如192.168.60.13/32egressIP字段是可选的。为了简化可以把它注释掉此时 agent 会使用默认路由网卡上分配的 IPv4/IPv6 地址作为出口 IP。另外说明一点该示例文件里除了单网关的egressGateway字段还带有一个egressGateways多网关示例块若使用egressGateways字段egressGateway字段的内容会被忽略单网关测试时可以将其移除。给目标网关节点打标签egress-gateway-node替换为你选定的网关节点名注意它应与mediabotPod 所在节点不同kubectl label nodes egress-gateway-node egress-nodetrue然后应用策略kubectl apply -f egress-gateway-policy.yaml应用后mediabotPod 的全部出集群流量都会经网关节点转发并以该节点配置的出口 IP 做 SNAT。验证结果再次从客户端 Pod 发起请求kubectl exec mediabot -- curl http://192.168.60.13:80回到外部主机看 Nginx 访问日志。策略生效的标志是日志中的来源 IP 从客户端所在节点 IP 变成了选定的出口 IP。文档示例输出192.168.60.100 - - [04/Apr/2021:22:06:57 0000] GET / HTTP/1.1 200 612 - curl/7.52.1策略不生效时如何排查策略行为不符合预期时可以查看任意一个 cilium agent 容器中的 egress 配置配置会同步到所有 agentkubectl -n kube-system exec ds/cilium -- cilium-dbg bpf egress list文档示例输出Source IP Destination CIDR Egress IP Gateway IP 192.168.2.23 192.168.60.13/32 0.0.0.0 192.168.60.12各列含义Source IP命中策略podSelector的每个 Pod 的 IPGateway IP命中策略nodeSelector的网关节点的内部 IPEgress IP除网关节点上的 agent 外其他 agent 上显示为0.0.0.0网关节点上的 agent 应显示实际使用的出口 IP若策略指定了egressIP即该值。如果列表中没有预期条目按文档提示检查 Pod 与网关节点的标签是否与策略选择器匹配。另外两个已知边界要注意新启动的 Pod 存在策略生效前的延迟窗口期间其流量可能以 Pod IP 或节点 IP 出集群且不经网关网关节点的网络配置发生变化后需要重新 apply 策略才会触发出口 IP 重选。进阶SNAT 连接数限制当大量客户端经同一个出口 IP 连接同一个远端端点时Cilium 的 SNAT map 会到达容量上限旧连接会被驱逐导致连接中断。该上限等于 NAT 最大端口值65535减去--node-port-range上界默认 32767即默认 32768 条到同一远端地址同一出口 IP的连接。详细分析与处理见 SNAT Connection Limitsagent 会统计 top 30 的连接五元组每 30 秒刷新一次可在 agent 容器内查看kubectl -n kube-system exec ds/cilium -- cilium-dbg shell -- db/show nat-stats输出文档示例形如# IPFamily Proto EgressIP RemoteAddr Count ipv4 TCP 172.18.0.2 104.198.14.52:443 294 ipv4 TCP 172.18.0.2 172.18.0.4:6443 50若某一行连接数接近默认上限 32768即可能出现了 SNAT 连接溢出文档给出的唯一解决方向是减少经同一出口 IP 到同一远端地址的 SNAT 连接数让客户端少建连接或用多个出口 IP / 拆分远端地址分散流量。小结与限制到这里一个连续的验证路径是启用三项配置并重启 Cilium → 应用CiliumEgressGatewayPolicy→ 用客户端 Pod 对外部 Nginx 的请求日志确认来源 IP 从节点 IP 变为出口 IP → 用cilium-dbg bpf egress list核对每条策略的 Source/Destination/Egress/Gateway 四列。需要记住的边界该功能与 Cluster Mesh、CiliumEndpointSlice、kvstore身份模式互斥egressIP与interface不能同设网关节点标签无匹配时命中流量会被丢弃更换网关节点会断开已有的出集群连接。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门