背景
- kubernetes:1.16.3
- Proxy mode:ipvs
问题
在同一个节点上,两个Pod通过svc互相访问超时
排查思路
- coredns漂移到node节点后,发现其中同节点上,dns解析会超时
- 因为dns是udp协议,抓包效果不好,随即找到同节点内http协议的服务进行抓包验证
- 抓包后,请求到达service vip的源地址(当前pod ip)和目的地址(vip)
- 而在回报时,却发现通信变成了两个pod之间直接通信
解决方法
方法一:
使用affinity调度,保证两个存在相互调度关系的pod不会启动在同一个节点上
方法二:
开发流量伪装,修改kube-proxy配置文件
masqueradeAll: true
总结
kube-proxy
kube-proxy通过在每个节点上创建相同的ipvs规则(关闭rap),当pod访问集群内svc(vip)时,请求会被当前节点vip接受,此时,ipvs会进行DNAT操作,而在回报时,两个pod处于同一个veth-part的一面,此时流量并不会走网关,所以回报的时候源ip和目的ip都是两个pod的ip,但是在请求发送时,目的ip为vip,此时会丢弃掉请求。
ipvs
- 当用户请求到达 DS 时,请求报文会先经过内核空间中的 PREROUTING 链,此时源 IP 为CIP,目的 IP 为 VIP;
- 在 PREROUTING 规则链上进行检查目的IP是否为本机,如果是的话将数据包送至 INPUT 链;
- 数据包到达INPUT链后,IPVS 会比对数据包请求的服务是否为集群服务,若是,修改数据包的目标 IP 地址为后端服务器 IP(这里需要根据各种算法计算,哪台 RS 更合适),再将数据包发至 POSTROUTING 链,此时报文的源 IP 为 CIP,目标 IP 为 RIP;
- POSTROUTING 链的作用就是选路,根据 INPUT 链中目标 IP,将数据包发送给 RS;
- RS 发现数据包中的目标 IP 是自己的 IP,此时它会开始构建响应报文发并回给 DS, 此时报文的源IP为RIP,目标IP为 CIP;
- DS 收到 RS 响应后,但在响应客户端,会将源 IP 地址修改为自己的 VIP 地址,然后发送给客户端,此时报文的源 IP 为 VIP,目标 IP 为 CIP;
参考链接
https://mp.weixin.qq.com/s/qIfwXpoC5odpIsQIcNxi5A
https://www.cnblogs.com/longgor/p/13588191.html