K8s网络连接拒绝监控与排查实战指南
1. 为什么需要关注K8s中被拒绝的网络连接在Kubernetes集群中网络连接被拒绝的情况每天都在发生。这些被拦截的流量可能包含重要安全事件的前兆信号——比如未授权的服务发现尝试、横向移动攻击或异常的API调用。去年我们生产环境就遇到过这类情况某个微服务突然开始频繁连接其他命名空间的数据库正是防火墙日志帮我们及时发现了被入侵的Pod。网络策略NetworkPolicy作为K8s原生的防火墙机制默认采用白名单模式。任何不符合规则的连接都会被静默丢弃这种静默拒绝特性使得排查问题变得困难。想象一下开发人员报告服务A无法访问服务B时如果你连基本的拒绝记录都拿不出来故障排查就会变成一场噩梦。2. 关键日志来源全景分析2.1 网络插件层面的日志宝藏不同CNI插件的日志位置和格式差异很大。以Calico为例其Felix组件会在各个节点生成包含详细拦截记录的日志# 查看Calico的拒绝连接日志 journalctl -u calico-felix --no-pager | grep Dropped packet典型日志条目如下2023-08-20 09:15:23.123 [WARNING][1234] felix/int_dataplane.go 1024: Dropped packet, src_ip10.244.1.5, dst_ip10.244.2.8, protoTCP, src_port54321, dst_port6379, policy_namespacedefault, policy_nameredis-access关键字段解析src_ip/dst_ip显示通信双方的Pod IPproto/ports协议和端口信息policy_namespace/name触发拒绝的网络策略名称注意Calico默认日志级别可能不记录所有丢弃事件需要通过FelixConfiguration调整日志级别apiVersion: operator.tigera.io/v1 kind: LogSeverity metadata: name: cluster-wide spec: severity: Info2.2 内核防火墙的原始视角当使用iptables模式时可以直接查询Linux内核的防火墙日志。首先确保启用日志记录# 在每台节点上执行 sudo iptables -I INPUT -j LOG --log-prefix [IPTABLES-DENY] sudo iptables -I FORWARD -j LOG --log-prefix [IPTABLES-DENY] 日志会出现在系统日志中通过以下命令查看dmesg | grep IPTABLES-DENY典型输出示例[IPTABLES-DENY] INcali1234 OUT MAC... SRC10.244.1.5 DST10.244.2.8 LEN60 TOS0x00 PREC0x00 TTL63 ID54321 PROTOTCP SPT41892 DPT6379 WINDOW64860 RES0x00 SYN URGP02.3 K8s审计日志的补充价值虽然审计日志(Audit Log)主要记录API Server活动但它能捕获NetworkPolicy的变更事件。当突然出现大量拒绝连接时可以交叉检查是否有策略被意外修改kubectl logs -n kube-system kube-apiserver-node1 | grep networkpolicies.networking.k8s.io3. 实战构建拒绝连接监控体系3.1 日志收集架构设计推荐采用以下架构实现全集群覆盖Pod - CNI日志 - Fluentd - Elasticsearch - Kibana - iptables日志 -配置示例Fluentd部分source type tail path /var/log/calico/felix.log tag calico.deny format /(?logtime[^ ]* [^ ]*) \[(?loglevel[^\]]*)\]\[(?thread[^\]]*)\] (?file[^ ]*) (?line\d): Dropped packet, src_ip(?src_ip[^,]*), dst_ip(?dst_ip[^,]*), proto(?proto[^,]*), src_port(?src_port[^,]*), dst_port(?dst_port[^,]*), policy_namespace(?policy_ns[^,]*), policy_name(?policy_name[^ ]*)/ /source3.2 关键监控指标定义建议监控这些核心指标拒绝连接速率单位时间内被拒连接数高频拒绝来源统计源IP排名热点目标端口被拒连接的目标端口分布策略拦截排行触发拒绝最多的网络策略对应的PromQL示例# 按命名空间统计拒绝次数 sum by (policy_ns) (rate(calico_denied_packets[5m])) # 检测突发性拒绝激增 deriv(calico_denied_packets[1h]) 1003.3 告警规则最佳实践根据严重程度分级告警紧急关键业务服务被持续拒绝如数据库端口重要来自非信任命名空间的连接尝试警告新部署服务首次出现拒绝Alertmanager配置片段- name: network-denial-alerts rules: - alert: CriticalServiceDenied expr: sum by (dst_port) (rate(calico_denied_packets{dst_port~6379|5432|3306}[5m])) 10 for: 10m labels: severity: critical annotations: summary: Critical database port {{ $labels.dst_port }} denied4. 高级排查技巧与案例分析4.1 真实问题诊断流程案例现象订单服务突然无法访问支付服务确认基础连通性kubectl exec -it order-service-pod -- curl -v http://payment-service:8080检查网络策略kubectl get networkpolicy -n payment kubectl describe networkpolicy payment-access -n payment查询实时拒绝日志# 在支付服务所在节点执行 sudo tcpdump -i cali host 10.244.3.5 and port 8080策略模拟测试 使用calicoctl的模拟工具calicoctl policy-tracer -n payment --src order-service --dst payment-service --port 80804.2 性能优化注意事项当日志量过大时需要注意在Felix配置中启用日志采样apiVersion: projectcalico.org/v3 kind: FelixConfiguration metadata: name: default spec: logSeverityScreen: Info logDropAction: Log logDropInterval: 5s对iptables日志添加速率限制sudo iptables -A INPUT -m limit --limit 10/min -j LOG4.3 安全事件关联分析将拒绝日志与安全工具集成在Falco中创建规则检测可疑拒绝模式- rule: Unexpected Database Connection Attempt desc: Pod trying to connect to database port without label condition: k8s.pod.name ! and jevt.value[/proto] TCP and jevt.value[/dst_port] in (3306, 5432, 6379) and not k8s.pod.label.dbclient true output: Unauthorized DB access attempt from %k8s.pod.name to port %jevt.value[/dst_port] priority: WARNING与SIEM系统集成将拒绝事件与登录日志关联分析5. 工具链推荐与配置模板5.1 可视化看板配置Grafana看板JSON模板核心部分{ panels: [ { title: Top Denied Sources, type: table, targets: [{ expr: topk(10, sum by (src_ip) (rate(calico_denied_packets[1h]))), legendFormat: {{src_ip}} }] }, { title: Denial Trend, type: graph, targets: [{ expr: sum by (policy_name) (rate(calico_denied_packets[5m])), legendFormat: {{policy_name}} }] } ] }5.2 命令行诊断工具包常用命令速查表场景命令实时监控拒绝watch -n 1 kubectl logs -n kube-system -l k8s-appcalico-node策略影响评估calicoctl policy-tracer --namespace demo --src frontend --dst backend --port 8080历史日志分析journalctl -u calico-felix --since 1 hour ago网络拓扑检查calicoctl get hep -o wide5.3 策略调试工作流创建临时放行策略apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: temp-allow-debug namespace: problematic-ns spec: podSelector: {} ingress: - from: - podSelector: {} ports: - protocol: TCP port: 8080逐步收紧策略时检查连通性while kubectl apply -f stricter-policy.yaml; do kubectl exec test-pod -- curl -I http://target-service:8080 sleep 2 done最终策略确认后删除临时策略kubectl delete networkpolicy temp-allow-debug -n problematic-ns在实施网络策略时我习惯先设置deny-all作为安全基线然后像剥洋葱一样逐层添加允许规则。每次变更后通过自动化测试验证关键业务流不受影响。记住好的防火墙策略应该像瑞士奶酪——有严格控制的孔洞而不是完全封闭或完全开放。