【社区精选】在Docker环境下,TDengine的客户端为什么连不上集群?

作者|陈玉

最近,在TDengine Database的一个社区群中突发了一场严重的灌水事件。几位群友不眠不休地聊天,可以说是废寝忘食。那么到底是什么话题能让他们凌晨四点还在忘我地讨论?

这个话题就是——如何完善Docker环境下TDengine Database的集群搭建。“什么?除了你们官方自己人之外,怎么会有用户加班加点地讨论如何完善Docker环境的集群搭建,这也太假了。”

聊天截图1

好吧,我们承认:其实是有一个叫Oliver(群昵称)的用户遇到了这样的问题——辛辛苦苦搭起来Docker环境下的TDengine集群在客户端连不上了。接下来,就引发了群里的二位热心大佬的讨论不休,直到想出最后的解决方案。

事情的经过是这样的:

该用户的数据库集群装在这台Linux服务器上(ip:10.0.31.2),容器ip所在的网络是由Docker在宿主机创建的虚拟网络172.19.0.0/16。三个容器的hostname和节点ip分别:taosnode1(172.19.0.41)、taosnode2(172.19.0.42)、taosnode3(172.19.0.43)。

各个节点配置如下:

taosnode1: firstEp=taosnode1:6030,secondEp=taosnode2:6030,fqdn=taosnode1;端口映射:16030-16042:6030-6042(tcp/udp)
taosnode2: firstEp=taosnode1:6030,secondEp=taosnode2:6030,fqdn=taosnode2;端口映射:26030-26042:6030-6042(tcp/udp)
taosnode3: firstEp=taosnode1:6030,secondEp=taosnode2:6030,fqdn=taosnode3;端口映射:36030-36042:6030-6042(tcp/udp)

按照官方文档的指示努力折腾一番后,Oliver终于搭起了这个集群。添加完节点之后,他忐忑地敲下了“show dnodes”,随着三个READY映入眼帘后———舒坦了。

服务端没有问题,接下来该客户端了。他打开了自己的一台ip为10.0.31.5(与集群宿主机同一网段)的Windows主机,迅速地在上面安装了个TDengine客户端,添加hosts信息,做好路由,2.8MB,傻瓜式安装,轻松便捷,连接集群一气呵成。“show dnodes”随着三个READY再次映入眼帘后———又舒坦了。

Oliver十分满意,然而,他马上发现事情可能并不像想象中的那么简单。

由于业务需要,他还需要完成客户端(10.0.2.61)跨网段连接服务端集群(基于ip:10.0.31.2的Docker环境下的集群)。ping得通宿主机,telnet得通集群映射出来的端口,使用taos连接集群,一样的操作也和此前一样顺利。于是他再次敲下“show dnodes”——万万没想到,这时令所有TDengine用户都深恶痛绝的“DB error:Unable to establish connection”出现了。于是,他便在群中抛出了自己的问题。

DB error:Unable to establish connection

上文说到的两位热心的同学就是在这个时候出现的。一位是TDengine的外部Contributor——Freemine。另一位是路见问题拔刀相助的热心大佬pigwing。

由于集群本身没有任何使用问题,唯一的区别就是客户端连接服务器的方式变成了跨网段。所以,一开始大家的思路就是——既然走宿主机的端口不行,那就试试直接连到Docker环境下的ip吧。遗憾的是,跨网段连接Docker环境下内部ip的想法没能实现。

接着大家推测:TDengine靠的是EndPoint(EP)来识别数据节点,而EP=FQDN+端口。可客户端连接已经成功,只是无法对数据操作,在FQDN无误的情况下,大家猜测是集群内的端口出现了问题,从而没拿到集群的拓扑信息。接下来,从最初的了解环境,到一步一步的排查问题,三个锲而不舍的工程师在群里从4月22日讨论到4月25,最晚的时候凌晨4点多都有人在线。

聊天截图2

终于,在三人的通力合作多次试错下,4月24日凌晨1点——freemine提出了一个行之有效的最终解决方案(文字过多只截图关键部分)

聊天截图3
聊天截图4

大功告成,经过测试后,一切顺利!

那么,freemine的集群搭建方案和最初的集群搭建有什么区别呢?

虽然过程曲折,但是最后我们仔细对比一下两者的方案就会发现,它们的区别就只有在端口配置这一块不一样。freemine的方案是在每一个单机的serverport都修改了不一样的值。taosnode1节点的serverport为6030—映射主机的6030端口;taosnode2节点的serverport为7030–映射主机的7030端口;taosnode3节点的serverport为8030–映射主机的8030端口。

而提问者Oliver最初的各个节点的serverport都是没做修改的默认6030,映射到宿主机的时候是16030,26030,36030。就是这样的配置在客户端与集群宿主机的同网段连接时并没有发生问题,而是在跨网段连接时出现问题。

看起来一丝小小的改动居然有这么大的区别?Why?

其实是这样,当客户端与服务端同属一个网段的时候,在添加路由后,客户端是可以直接访问到Docker内部的。这样一来,IP地址就可以根据需要被正确地解析出来。如:taosnode1(172.19.0.41)、taosnode2(172.19.0.42)、taosnode3(172.19.0.43)。在不同的IP地址下,即便端口都是一样的6030,TDengine还是可以完成不同节点的区分。

但是,当跨网段之后就不一样了。对于不同网段的客户端和服务端而言,客户端要通过真实路由去连接服务端,但真实路由中并没有注册我们设置的Docker内部网络,所以客户端自然就访问不了Docker内部的网络。因此,当taosc需要得到集群提供的不同节点的信息时,FQDN已经无法正确解析IP地址了。这时候,就需要通过端口来实现不同节点的区分。

这就是不能再在Docker环境下的节点中同时使用6030端口的原因。

因此,当你使用了Docker主机内外一致的端口映射,且每个节点的serverPort参数不相同的设置时,集群就可以通过不同的端口来区分不同的节点。这样一来,客户端才可以拿到拓扑信息进行集群的顺利操作。

这就是整个“案件”的最终答案。

总结一下,对于用户使用而言,Docker环境下搭建TDengine Database集群的水还是颇深。由于环境的相对复杂,所以我们也并不是十分推荐大家使用这种方式搭建集群。所以,关于TDengine在Docker环境的使用,大家还是要小心谨慎。

最后我们想说的是,作为一个开源的产品,社区的活跃与专业是我们涛思数据最为关注的地方。虽然目前官网上并没有关于Docker环境下TDengine集群搭建的文档。但是这些社区用户们的活跃思考显然很大程度填补了这样的一个空白。

真心感谢Oliver,freemine,pigwing三位朋友。十分希望日后可以继续看到你们在物联网大数据技术前沿群中的活跃身影,同时我们也希望有更多的朋友们能够参与进来。

扫描二维码,添加小T为好友,即可与各位热衷开源的朋友一起在群内互动哦~

小T二维码

点击“这里”,查看Oliver整理的TDengine在Docker环境下的集群搭建笔记