TKE集群内pod无法访问云上数据库

2021-04-13 13:34:48 浏览数 (1)

现在很多人会将服务部署到tke集群中,数据库也是用的云上数据库,一些后端服务就需要连接redis、mysql等数据库,大家都知道我们的服务是打成镜像通过pod部署的,所以我们需要在pod里面能访问到云上的数据库。

但是这个过程很多人遇到一个问题,就是发现后端需要连接数据库的pod一直无法正常运行,查看业务日志发现是连接数据库失败,然后就赶紧到节点看看和数据库的网络是否通,节点telnet测试发现是可以连接,说明节点到数据库的网路没问题,然后就怀疑是容器网络有问题,起了一个测试pod,直接telnet数据库无法连接。也就是说tke集群内的容器到数据库的网络不通,很多人到这里就没有思路了,然后只能提工单向腾讯云求助。

其实这个问题就是pod到数据库网络不通的问题,今天我们来说下这个问题是什么原因导致,又该如何解决。

很多人使用过k8s的都知道,pod的出口ip一般就是所在节点的ip,所以在数据库得安全组就只放通了节点所在的网段,但是在tke集群会部署一个ip-masq-agent的插件,这个插件具体的介绍说明可以参考https://cloud.tencent.com/developer/article/1688838 ,这里简单说下这个插件就是集群内那些网段的ip不做snat,保留源ip,tke集群默认会配置节点网段和容器网段不做snat,也就说如果pod作为客户端ip去访问数据库,在数据库接收的ip是pod ip,并不是节点ip,通常节点所在的网段和容器网段不是同一个,但是你数据库的安全组又只放通了节点所在网段,所以会导致pod访问不通数据库。

既然找到问题的原因了,那么解决方案就好说了,我们在数据库的安全组放通下容器网段的访问就行。下面我们可以简单测试下是不是这样一回事,我们这里测试下访问mysql数据,其他数据库也是相同的解决方案,只不过数据库端口不一样。

这里我们还要说明下:一般这个问题都是tke的GR网络模式,GR网络模式才会出现容器网络和节点网络不在一个vpc内,如果是vpc-cni模式则容器网络和节点网络在同一个vpc内,所以数据库安全组只需要放通vpc网段,也就是节点网段就行。

1. 首先获取集群不做snat的网段

我们可以通过获取ip-masq-agent组件的configmap来获取不做snat的网段信息

代码语言:javascript复制
[root@baron-cvm ~]# kubectl get cm ip-masq-agent-config -n kube-system -o yaml | grep NonMasqueradeCIDRs
  config: '{"NonMasqueradeCIDRs":["172.23.0.0/16","10.0.0.0/16"],"MasqLinkLocal":true,"ResyncInterval":"1m0s"}'

2. mysql只放通vpc网段

这里我么测试下mysql只放通vpc的网段,看看pod内能否访问mysql

我们在节点测试下访问mysql,节点上是可以访问通的。

我们起了一个busybox pod进行测试下,在pod里面是访问mysql不通。这里是因为我们的安全组还没放通我们的容器网段导致的。

注意:即使网络通了,在busybox的pod里面如果直接telnet redis数据库会有问题,具体原因未知,这里不建议busybox测试

3. mysql放通容器网段

这里我们在mysql的安全组加了一条规则,放通了集群的容器网段3306端口的访问。下面我们再在之前的pod测试下

这里我们测试了在容器里面是可以telnet通mysql,说明容器到数据库的网络是通的,这里pod内无法访问云上数据库的问题就解决了。

如果是访问其他数据库有问题,这里的解决方案也一样的,其实这个问题的解决方案总结起来就是在数据库的安全组放通tke集群内的ip-masq-agent组件配置的不做snat的网段。

0 人点赞