目前公司想做服务的注册与发现,但是在推进过程中,存在一个问题,目前我们的服务是混合部署的,即一部分部署在虚机,一部分部署在容器,所以就会面临这样一个问题,当容器里的服务和虚机里的服务都去注册中心进行注册时,虚机是无法访问容器的地址的,不过令人欣慰的是,虚机和容器是同属一局域网,所以要实现服务的注册与发现,首先需要解决这一问题。
首先就是一顿分析了,下面是我的分析过程
知道了这些,我大概就想到了是不是可以通过添加一条静态路由呢?但是在添加静态路由之前,得需要了解从pod里访问集群外虚机时的出口IP地址是什么?这个可以通过使用tcpdump来解决
1)现在一个Pod中去telnet虚机的地址,然后在虚机上进行抓包
#进入Pod中
kubectl exec -it user-api-764d68b678-54kt2 bash
#执行telnet,这里随意指定一个端口,只要没有被占用就好,目的是防止抓包时被其他信息干扰
telnet 192.168.0.130 12345
虚机上抓包
#虚机上抓包,指定12345端口即可
tcpdump -nni any port 12345
Telnet的结果
# telnet 192.168.0.130 12345
Trying 192.168.0.130...
telnet: connect to address 192.168.0.130: Connection refused
tcpdump抓包结果
# tcpdump -nni any port 12345
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10:52:28.644112 IP 192.168.0.198.35066 > 192.168.0.130.12345: Flags [S], seq 3592146803, win 28000, options [mss 1400,sackOK,TS val 780676435 ecr 0,nop,wscale 7], length 0
10:52:28.644169 IP 192.168.0.130.12345 > 192.168.0.198.35066: Flags [R.], seq 0, ack 3592146804, win 0, length 0
可以看到在Pod里进行Telnet时,访问虚机的源地址为node节点的IP地址,到这里基本上问题就解决了。
2)虚机上添加静态路由
#查看Pod的IP是什么?
kubectl get pod -o wide | grep user-api
user-api-764d68b678-54kt2 1/1 Running 0 3d17h 10.200.0.90 alpha-node-01 <none> <none>
可以看到IP地址为10.200.0.90
拿到Pod的IP地址后,就可以去虚机上添加路由了
route add -host 10.200.0.90 gw 192.168.0.198
验证下
#ping下是否能通
# ping 10.200.0.90
PING 10.200.0.90 (10.200.0.90) 56(84) bytes of data.
64 bytes from 10.200.0.90: icmp_seq=1 ttl=63 time=0.296 ms
64 bytes from 10.200.0.90: icmp_seq=2 ttl=63 time=0.258 ms
#再访问下服务是否可以通
# curl 10.200.0.90:8088/api/healthy/check
{"code":0,"message":"success"}
可以的,所以通过添加一条静态路由就可以解决同一局域网的虚机和pod的通信问题,但是这只是一个Pod的IP,实际上每一个node上都会起几十上百个这样的pod,那该如何添加呢?
我们的集群使用的网络插件是calico,而每一台节点分配的子网都是不同的,比如node1的IP段为10.200.0.0/24 , node2的IP段为10.200.38.0/24 所以我们可以添加整个IP段到虚机的路由表中
route add -net 10.200.0.0/24 gw 192.168.0.198
route add -net 10.200.38.0/24 gw 192.168.0.168
在每一台需要访问pod的虚机上,把集群内的IP段都添加上,就能实现了。