在我开发的项目notr内网穿透当中引入DNS来解决一个问题:
每次客户端连接都会修改其A记录,解析到连接的服务器节点上。目前DNS版本还非常简单,已经开源成notrns项目。但是这个项目还有几个问题:
通过github了解到CoreDNS和etcd两个项目,就想着用CoreDNS代替notrns来做动态域名解析,使用etcd来做存储,使用etcd是基于以下考量:
1.启动etcd
2.启动coredns
CoreFile:
notr.tech {
etcd {
path /skydns
endpoint http://localhost:2379
upstream
}
log
}
3.使用etctrl设置域名解析
➜ bin git:(master) ./etcdctl put /skydns/tech/notr/yingjiu/ '{"host":"192.168.1.2"}'
OK
➜ bin git:(master) nslookup yingjiu.notr.tech 127.0.0.1
Server: 127.0.0.1
Address: 127.0.0.1#53
Name: yingjiu.notr.tech
Address: 192.168.1.2
➜ bin git:(master) ./etcdctl put /skydns/tech/notr/yingjiu/ '{"host":"192.168.1.3"}'
OK
➜ bin git:(master) nslookup yingjiu.notr.tech 127.0.0.1
Server: 127.0.0.1
Address: 127.0.0.1#53
Name: yingjiu.notr.tech
Address: 192.168.1.3
➜ bin git:(master)
接下来只需要在registry将etcd client集成进去即可,改造完之后整个软件变成了下图所示的流程。
1.每次启动一个服务端节点之后,会往registry发送当前节点的信息,目的是让registry做负载均衡以及根据地理位置进行调度,同时服务端节点也可以随时插拔,随时都可以添加和删除节点。
2.把节点信息写入数据库,当前使用mongodb
3.步骤一和步骤二初始化完成之后,用户使用客户端,先和registry节点连接,获取接入的服务节点的信息
4.registry从数据库中取出在步骤二中存储的节点信息,并根据节点当前连接的客户端数量和地理位置进行一轮选择,首选地理位置最近的,目前只划两个区,中国区和海外区,然后再根据客户端连接数量排序选择连接数最少的。
5.客户端拿到节点信息之后和server建立tcp长连接
6.server节点需要从registry请求用户,限速等信息
7.从数据库取出数据
8.生成域名解析记录,将当前用户等域名映射到它当前连接到server的公网IP
9.每次需要域名解析时,由于配置了ns记录,用户的域名解析请求最终会到coredns,coredns再从etcd中取出