ChaosMesh 在 K8s 中注入 Pod 网络丢包,如何排除对监控流量的干扰

解读

在国内金融、运营商、电商等生产级 K8s 集群里,监控指标(Prometheus、夜莺、阿里云 SLS、腾讯云 CLS 等)直接决定告警、限流、HPA 甚至资金结算。ChaosMesh 的 NetworkChaos 基于 Linux qdisc/netem 做丢包,默认对 Pod 内所有出站流量生效,一旦把监控流量也“误杀”,就会出现“Pod 网络丢包 30%,但监控曲线断点→误判为节点故障→触发驱逐”的二次事故。面试时,考官想确认你是否:

  1. 理解 ChaosMesh 的注入路径(initContainer → tc/netem → iptables mark);
  2. 能在不改动业务镜像的前提下,用“白名单”方式精准放过监控流量;
  3. 知道如何在国产芯片/国产 OS(麒麟、统信)+ 自研 CNI(Terway、Cilium-ENI)环境里落地。

知识点

  1. ChaosMesh NetworkChaos 实现原理:
    • 注入 Sidecar 模式或 CRI 模式,最终落到 Pod 网络命名空间的 egress qdisc;
    • 支持 target 字段做“只对指定 Pod 生效”,但不区分端口/标签。
  2. Kubernetes 监控流量特征:
    • Prometheus:Pod 自身 /metrics 被“拉”走,端口多为 8080/9090,源 IP 是 node 或 kube-apiserver;
    • Telegraf/Exporters:主动“推”到 Kafka、Mafka、InfluxDB,端口 8094、9200;
    • 阿里云 Arms、腾讯云 APM:Sidecar 通过 Unix Domain Socket 或 127.0.0.1:9000 上报,不走 Pod 网卡。
  3. Linux tc filter 能力:
    • u32 匹配 IP、端口、DSCP;
    • iptables mark + tc fw 过滤器联动,可把监控流量 mark 为 0x100/0x200,再在 netem 规则里 skip_sw 跳过。
  4. ChaosMesh 高级字段:
    • externalTargets 可写 CIDR,但只能“额外加害”,不能“排除”;
    • device 字段可指定网卡,国产 CNI 多网卡场景(一张 eth0 跑业务,eth1 跑管控)可用来隔离。
  5. 国内合规要求:
    • 央行《金融分布式架构技术规范》要求故障演练期间监控可用性≥99.9%;
    • 等保 2.0 要求“演练不得影响审计日志完整”。

答案

分四层落地,全部基于开源方案,不碰业务代码,兼容国产 CNI。

  1. 监控流量“标记”层
    在业务 Namespace 预置一条 initContainer(镜像用官方 busybox 即可),启动时写 iptables:

    iptables -t mangle -A OUTPUT -p tcp --dport 9090 -j MARK --set-mark 0x100
    iptables -t mangle -A OUTPUT -p tcp -d 100.64.0.0/10 --dport 8094 -j MARK --set-mark 0x100
    

    把 Prometheus 拉取端口、以及主动推送的监控服务器网段全部打 mark 0x100。
    注意:使用 mangle 表,确保在 tc 之前生效;--dport 写全公司统一的 exporter 端口,避免漏网。

  2. ChaosMesh NetworkChaos 精准注入
    编写 NetworkChaos YAML,新增 tc 参数段(ChaosMesh ≥2.6 支持):

    tc:
      excludeMark: 0x100
    

    底层会生成 tc qdisc add dev eth0 root handle 1: netem loss 30% exclude_mark 0x100,实现“打了标记的包直接 bypass”。
    如果集群版本低于 2.6,可改用 device: eth0 + direction: to 并手动写 tc filter add dev eth0 parent 1: protocol ip handle 0x100 fw flowid 1:1,把未丢包的流量重新导向 1:1,效果等价。

  3. 多网卡场景兜底
    在阿里云 Terway ENI-Trunking 或华为 CCE 容器直通网卡环境,Pod 可能有两张网卡:eth0(业务 VPC)、eth1(管控/监控 VPC)。
    NetworkChaos 里只写 device: eth0,监控流量天然走 eth1,物理隔离,无需 mark。

  4. 灰度验证

    1. 先用 kubectl exec 进入目标 Pod,curl <node-ip>:9090/metrics 验证拉取端口可达;
    2. 在 Chaos Dashboard 观察注入成功率 100%,同时通过 Grafana 确认该 Pod 的“up”指标=1,网络丢包面板只显示业务端口下降;
    3. 演练结束后,立即执行 chaosctl logs 查看是否有 ERROR “pkt dropped by mark”,确认无监控包被误杀。

一句话总结:用 iptables 给监控流量打 mark,再利用 ChaosMesh 的 excludeMark 或 tc fw filter 让这部分包 bypass netem,即可在“只丢业务、不丢监控”的前提下完成网络丢包演练,满足国内生产环境对监控可用性的刚性要求。

拓展思考

  1. 如果公司统一用 Istio 进行 mTLS 监控,所有指标先发到 Sidecar(127.0.0.1:15090),再由 Sidecar 转发给 Prometheus,是否还需要排除?
    答:不需要。NetworkChaos 默认只影响 Pod 网络命名空间里的 eth0 出口,localhost 流量不走 veth pair,直接 bypass。但需确认 Istio 版本 ≥1.10,旧版本有 bug 会把部分流量重定向到 eth0。

  2. 想对“入站”流量做丢包,又怕把 Kubelet 探针(liveness/readiness)也干掉,怎么办?
    答:把探针端口写到 excludePort 字段;或者给探针配置 httpHeaders 加自定义头 X-Probe: kubelet,再用 tc u32 匹配该 header 的十六进制特征,实现七层排除。

  3. 国产 OS 内核裁剪后不支持 tc fw,如何兼容?
    答:改用 ipset + iptables DSCP 方案:

    • 把监控对端 IP 加入 ipset monitor_set
    • iptables -t mangle -A OUTPUT -m set --match-set monitor_set dst -j DSCP --set-dscp 0x20
    • tc 里 match dscp 0x20 的流直接 action ok,达到同样 bypass 效果,无需 fw 模块。
  4. 未来 ChaosMesh 计划支持 FlowSchema 语义,直接引用 K8s NetworkPolicy 的 podSelector/namespaceSelector 做排除,届时可进一步简化配置,实现“声明式白名单”,值得持续关注社区 Roadmap。