TKE集群pod内无法访问集群外cvm自建容器

2021-09-18 14:29:52 浏览数 (1)

1. 问题描述

使用tke产品的客户,经常会遇到GlobalRouter网络模式下tke集群内的pod无法访问集群外cvm自建docker容器服务,cvm节点也无法集群内pod服务,vpc-cni网络模式下集群是没有这个问题的。

2. 问题现象

模拟问题现象,集群外cvm上部署了一个nginx容器,并映射端口到节点8082,tke集群内pod内ping或者telnet集群外cvm上的自建容器服务不通,集群内节点访问可以通,集群外cvm访问集群内的pod也不通。

具体测试结果如下:

  • tke集群节点访问cvm上nginx服务
  • 集群内pod访问cvm上nginx服务
  • 集群外cvm访问集群内pod

3. 分析过程

为什么会出现集群外cvm的自建容器和集群pod不通的现象呢?下面我们简单的抓包看下

pod内访问cvm上的nginx服务,同时在cvm的节点和pod内抓包,从上面的抓包结果可以看,cvm上收到了pod发的数据包,但是cvm没有回包,说明问题是出在cvm上,为什么没有回包给pod呢?

之前我们测试了在cvm上是ping不通集群的pod,这里可以用traceroute来测试下路由的走向,看下是哪里有问题

经过traceroute可以发现,访问pod的路由到了节点172.18.0.1这个ip,172.18.0.1这个ip是docker0网桥的ip,查看路由表发现目的端为172.18.0.0网段的ip都走了docker0这个网卡了。排查到这里,问题原因差不多就清晰了。

原因就是cvm自建的docker网段和tke集群网段冲突了,回给172.18.0.0网段包都路由到的docker0网卡上,没走eth0出去,目的端收不到包,导致访问不通。

4. 解决方案

问题既然知道原因了,那么有什么解决方案没有呢?难道后续就不能在集群内pod访问集群外部的容器服务了吗?

当然有解决方案。这个问题的解决方案有2种:

4.1 修改集群ip-masq-agent配置

细心的同学从抓包可以发现,在cvm上收到的包源ip是pod的真实ip,从而导致路由到了docker0上,正常k8s上访问外部服务,pod ip都会snat成节点ip,这里没有snat成节点ip是因为在集群内部署了一个ip-masq-agent组件导致的,ip-masq-agent的具体说明介绍可以参考文档https://cloud.tencent.com/developer/article/1688838

GlobalRouter模式下tke集群,ip-masq-agent会默认配置访问目的为vpc网段和容器网段的地址不做snat,因此pod访问cvm是真实的pod ip。

如果想要pod访问cvm不用真实pod的ip,用节点ip,修改ip-masq-agent的配置文件,去掉vpc网段配置。

代码语言:javascript复制
kubectl edit cm ip-masq-agent-config -n kube-system

修改configmap,去掉vpc网段10.0.0.0/16,然后等1分钟后,ip-masq-agent的pod重新加载配置,我们再抓包测试下。

修改了配置后,pod内就可以访问通cvm的nginx容器服务了,从抓包结果看,cvm上抓包的源ip变成了pod所在的node节点ip 10.0.17.16,当目的端ip是节点ip,cvm上会走第二条路由规则,从eth0将包会给pod,因此访问正常。

4.2 修改cvm上docker容器网段

除了上述修改集群ip-masq-agent组件配置外,还有一种方案就是修改cvm上的docker容器网段,来避免和tke集群网段冲突的问题,这个方案需要重启cvm上的所有容器,需要慎重使用。

修改节点的/etc/docker/daemon.json配置文件,没有新建一个,添加如下内容,这里将网段改成192.168了,保存后重启docker。

代码语言:javascript复制
"bip": "192.168.0.1/24"

下面我们测试下,将ip-masq-agent的配置加上vpc网段,然后在pod内访问下cvm上的nginx服务看看。

可以发现,改了cvm的容器网段后,在pod内是可以成功访问到cvm的nginx服务的。

5. 思考扩展

还记得开始我们说过,在vpc-cni的模式下,不会出现这个问题,经过上面的分析和排查,大家应该知道为什么vpc-cni不会出现这个问题了,原因很简单。

vpc-cni模式下容器网段都是vpc下的子网ip,容器网络和vpc是同一个网络层面,vpc-cni模式下的pod访问cvm上的docker会走local路由策略,走主网卡eth0出去,因此不会有这个问题。

0 人点赞