vlambda博客
学习文章列表

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:443kubernetes clusterIP和端口


在折腾过程中,尝试手动增加环境变量让flannel通过6443连接apiserver临时解决问题,但是只能走内部clusterIP调用APIserver的pod就没那么幸运可以跳过这个问题。==


2.在node节点上ping 10.0.4.1发现是可以通信;


3.在node节点上telnet 10.0.4.1 443无法通信;

k8s集群node节点无法访问k8s svc 443服务


4.查看kubernetes ep正常的;

k8s集群node节点无法访问k8s svc 443服务


5.从node上在使用了host网络模式的pod中,无法访问kubernetes中的service,在非host网络模式的pod中可以访问service。


排查过程


没有什么技巧只能抓包看看发生了什么,在node01 telnet,并进行抓包:

k8s集群node节点无法访问k8s svc 443服务


又在apiserver部署机器进行抓包:

k8s集群node节点无法访问k8s svc 443服务



上面说到在node节点上,k8s svc clusterIP是可以ping通,telnet ip 443是连接拒绝的。尝试看下node 的本地网卡,发现有一个kube-ipvs0,绑定IP正是10.0.4.1,也就是发送到10.0.4.1的数据都由这里转发,这个网卡正是kube-proxy创建的:

k8s集群node节点无法访问k8s svc 443服务


再看下这个node ipvs规则:

k8s集群node节点无法访问k8s svc 443服务


这就是k8s svc clusterIp可以ping 的原因吧!现在ipvs规则也是正常的,还是回到数据包被ipvs转发出去时,源IP怎么处理的问题上!


尝试自定义源IP发起请求,指定源IP node01的IP来telnet:

k8s集群node节点无法访问k8s svc 443服务

这就有意思了!!


继续这里折腾,在node01上将源IP强制转换,在进行telnet测试:

k8s集群node节点无法访问k8s svc 443服务

是可以直接访问了!


现在问题来到为什么加加了这个规则就正常了,或者说node节点为什么缺少这条规则?


峰回路转:

想到ipvs对应的是kube-proxy组件,去看了下kube-proxy启动日志:

k8s集群node节点无法访问k8s svc 443服务


留意到这个关键字【ClusterCIDR】,目前配置如下:


去官网看KubeProxyConfiguration :


ClusterCIDR配置错,配置成serviceCIDR!关键日志还没有明显的报错信息!!


Kube-proxy中的ClusterCIDR指定的是集群中pod使用的网段,pod使用的网段和apiserver中指定的service的cluster ip网段不是同一个网段。


修改clusterCIDR: 10.244.32.0/20 ,重启kube-proxy。问题解决。


问题总结


问题表面是配置错误pod CIDR,根源是自己照着文档操作没有多想每个配置的含义,出问题导致走了很多弯路。解决问题的能力和思路才是真正的技能啊!