Kubernetes: 内核参数rp_filter设置为Strict RPF,导致Service不通

Tags: kubernetes_problem 

目录

现象

网络方案是flannel, 从node上直接用telnet访问Service的服务地址(IP 端口),不通。

[node-70-155 ~]$ telnet 10.12.164.251 5432
Trying 10.12.164.251...
^C

同一台node上,直接访问Service对应的Pod的地址,可以通:

[node-70-155 ~]$ telnet 17.0.51.13  5432
Trying 17.0.51.13...
Connected to 17.0.51.13.
Escape character is '^]'.

在Pod所在的node上,用telnet访问Service的服务地址,也可以通。很奇怪。

调查

在nodeA(10.10.70.155)上发起请求,Pod在nodeB(10.10.67.156)上运行。

从nodeA上访问Service(10.12.164.251:5432)时 :

[node-70-155 ~]$ telnet 10.12.164.251 5432
Trying 10.12.164.251...

在nodeB上对flannel0抓包,发现没有回应包:

[root@k8s-node-67-156 flannel0]# tcpdump -i flannel0 host 10.10.70.155
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on flannel0, link-type RAW (Raw IP), capture size 65535 bytes
17:48:05.470698 IP 10.10.70.155.56192 > 17.0.51.13.postgres: Flags [S], seq 2778311576, win 28280, options [mss 1414,sackOK,TS val 844872206 ecr 0,nop,wscale 7], length 0
17:48:06.471586 IP 10.10.70.155.56192 > 17.0.51.13.postgres: Flags [S], seq 2778311576, win 28280, options [mss 1414,sackOK,TS val 844873208 ecr 0,nop,wscale 7], length 0
17:48:07.855606 IP 10.10.70.155.55820 > 17.0.51.13.postgres: Flags [P.], seq 2472621440:2472621762, ack 1631278827, win 314, options [nop,nop,TS val 844874592 ecr 2559804523], length 322
17:48:08.475632 IP 10.10.70.155.56192 > 17.0.51.13.postgres: Flags [S], seq 2778311576, win 28280, options [mss 1414,sackOK,TS val 844875212 ecr 0,nop,wscale 7], length 0
^C

在容器(17.0.51.13)内抓包,发现容器没有收到报文,并且可以看到目的地址已经被转换成了Pod的地址,iptables规则经核实也没有问题。

问题在nodeA上,flannel0收到了报文,但是没有转发给容器,查看nodeA上的路由,

[root@k8s-node-67-156 flannel0]# ip route
default via 10.10.0.1 dev eth0
10.10.0.0/16 dev eth0  proto kernel  scope link  src 10.10.67.156
17.0.0.0/16 dev flannel0
17.0.51.0/24 dev docker0  proto kernel  scope link  src 17.0.51.1

根据最后一条路由,目标IP是17.0.51.13的报文,要经过docker0送到容器中,在docker0上抓包,也没有收到包。

核对nodeA上的arp和容器内的网卡mac相同,也没有问题:

[root@k8s-node-67-156 flannel0]# arp -n |grep 51.13
17.0.51.13               ether   02:42:11:00:33:0d   C                     docker0

陷入困境。

继续调查

将问题反馈其他同事,发现可以通过修改内核参数rp_filter解决问题,操作如下:

echo 0 > /proc/sys/net/ipv4/conf/flannel0/rp_filter

然后就立马通了,很神奇。

/etc/sysctl.conf中添加:

net.ipv4.conf.all.rp_filter = 0

然后更新:

sysctl -p

查阅rp_filter参数的说明,原来这是linux kernel中实现的一种抗DOS攻击的方法。rp_filter为1时,将严格检查接受报文的网卡,和访问报文的源IP的网卡是否是同一个网卡,如果不是,就丢弃。

在nodeA上直接访问Service时,报文的源IP是nodeA的eth0的IP,在nodeB上,flannel0收到报文后,检查发现,回应时要使用的网卡是eth0,接收网卡和回应网卡不一致,报文被丢弃,因此docker0压根接没有看到包,也不会送给容器。

rp_filter参数的详细见:Linux内核参数用途记录: rp_filter

参考

  1. rp_filter

kubernetes_problem

  1. kubernetes ingress-nginx 启用 upstream 长连接,需要注意,否则容易 502
  2. kubernetes ingress-nginx 的 canary 影响指向同一个 service 的所有 ingress
  3. ingress-nginx 启用 tls 加密,配置了不存在的证书,导致 unable to get local issuer certificate
  4. https 协议访问,误用 http 端口,CONNECT_CR_SRVR_HELLO: wrong version number
  5. Kubernetes ingress-nginx 4 层 tcp 代理,无限重试不存在的地址,高达百万次
  6. Kubernetes 集群中个别 Pod 的 CPU 使用率异常高的问题调查
  7. Kubernetes 集群 Node 间歇性变为 NotReady 状态: IO 负载高,延迟严重
  8. Kubernetes的nginx-ingress-controller刷新nginx的配置滞后十分钟导致504
  9. Kubernetes的Nginx Ingress 0.20之前的版本,upstream的keep-alive不生效
  10. Kubernetes node 的 xfs文件系统损坏,kubelet主动退出且重启失败,恢复后无法创建pod
  11. Kubernetes的Pod无法删除,glusterfs导致docker无响应,集群雪崩
  12. Kubernetes集群node无法访问service: kube-proxy没有正确设置cluster-cidr
  13. Kubernetes集群node上的容器无法ping通外网: iptables snat规则缺失导致
  14. Kubernetes问题调查: failed to get cgroup stats for /systemd/system.slice
  15. Kubelet1.7.16使用kubeconfig时,没有设置--require-kubeconfig,导致node不能注册
  16. Kubelet从1.7.16升级到1.9.11,Sandbox以外的容器都被重建的问题调查
  17. Kubernetes: 内核参数rp_filter设置为Strict RPF,导致Service不通
  18. Kubernetes使用过程中遇到的一些问题与解决方法
  19. Kubernetes集群节点被入侵挖矿,CPU被占满
  20. kubernetes的node上的重启linux网络服务后,pod无法联通
  21. kubernetes的pod因为同名Sandbox的存在,一直无法删除
  22. kubelet升级,导致calico中存在多余的workloadendpoint,node上存在多余的veth设备
  23. 使用petset创建的etcd集群在kubernetes中运行失败
  24. Kubernetes 容器启动失败: unable to create nf_conn slab cache
  25. 未在calico中创建hostendpoint,导致开启隔离后,在kubernetes的node上无法访问pod
  26. calico分配的ip冲突,pod内部arp记录丢失,pod无法访问外部服务
  27. kubernetes的dnsmasq缓存查询结果,导致pod偶尔无法访问域名
  28. k8s: rbd image is locked by other nodes
  29. kuberntes的node无法通过物理机网卡访问Service

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  李佶澳的博客  系统软件  程序语言  运营经验  关注方向  水库文集  网文收藏  网络课程  发现知识星球  百度搜索 谷歌搜索