k8s集群node节点无法访问k8s svc 443服务
问题背景
二进制搭建k8s 1.18集群,kube-proxy采用ipvs模式,集群内部无法通过clusterIP访问k8s 443服务,准确来讲是node节点与k8s clusterip的443端口通信。
podCIDR:10.244.32.0/20
serviceCIDR:10.0.4.0/22
故障现象
1.在部署kube-flannel时一直处于CrashLoopBackOff状态,log报错如下,10.0.4.1:443是kubernetes clusterIP和端口。
在折腾过程中,尝试手动增加环境变量让flannel通过6443连接apiserver临时解决问题,但是只能走内部clusterIP调用APIserver的pod就没那么幸运可以跳过这个问题。==
2.在node节点上ping 10.0.4.1发现是可以通信;
3.在node节点上telnet 10.0.4.1 443无法通信;
4.查看kubernetes ep正常的;
5.从node上在使用了host网络模式的pod中,无法访问kubernetes中的service,在非host网络模式的pod中可以访问service。
排查过程
没有什么技巧只能抓包看看发生了什么,在node01 telnet,并进行抓包:
又在apiserver部署机器进行抓包:
上面说到在node节点上,k8s svc clusterIP是可以ping通,telnet ip 443是连接拒绝的。尝试看下node 的本地网卡,发现有一个kube-ipvs0,绑定IP正是10.0.4.1,也就是发送到10.0.4.1的数据都由这里转发,这个网卡正是kube-proxy创建的:
再看下这个node ipvs规则:
这就是k8s svc clusterIp可以ping 的原因吧!现在ipvs规则也是正常的,还是回到数据包被ipvs转发出去时,源IP怎么处理的问题上!
尝试自定义源IP发起请求,指定源IP node01的IP来telnet:
这就有意思了!!
继续这里折腾,在node01上将源IP强制转换,在进行telnet测试:
是可以直接访问了!
现在问题来到为什么加加了这个规则就正常了,或者说node节点为什么缺少这条规则?
峰回路转:
想到ipvs对应的是kube-proxy组件,去看了下kube-proxy启动日志:
留意到这个关键字【ClusterCIDR】,目前配置如下:
去官网看KubeProxyConfiguration
:
ClusterCIDR配置错,配置成serviceCIDR!关键日志还没有明显的报错信息!!
Kube-proxy中的ClusterCIDR指定的是集群中pod使用的网段,pod使用的网段和apiserver中指定的service的cluster ip网段不是同一个网段。
修改clusterCIDR: 10.244.32.0/20 ,重启kube-proxy。问题解决。
问题总结
问题表面是配置错误pod CIDR,根源是自己照着文档操作,没有多想每个配置的含义,出问题导致走了很多弯路。解决问题的能力和思路才是真正的技能啊!