微服务与Kubernetes容器云的边界的考量,其实就是思考微服务要不要跨多个Kubernetes集群的问题。比较理想的情况是微服务和Kubernetes完全对齐,也就是一套微服务运行在一套Kubernetes集群上。在这种情况下,微服务、配置中心+注册中心都在相同的Kubernetes集群中。当微服务指向配置中心时,写配置中心的ServiceName即可,网络I/O路径较短。否则,需要通过Kubernetes Ingress访问注册中心(如果容器云的SDN采用overlay模式),网络延迟将会较大。这在微服务数量较多、变更较频繁的时候更为明显。
1)配置+注册中心在一个Kubernetes集群上:如果Kubernetes集群的SDN用的是underlay网络,那么其他Kubernetes集群注册的时候,由于其Pod IP和宿主机IP在同一个网络平面,使得注册中心能够准确识别到Pod的IP。这种方式的弊端体现在如下三个方面。
- 微服务去注册中心注册时,由于跨Kubernetes集群,网络I/O路径长。
- 数据中心网络需要打开BGP(用到了类似Caico的underlay SDN方案)。
- underlay网络方案比较耗费数据中心的IP。
2)配置+注册中心不在一个Kubernetes集群上:如果Kubernetes集群的SDN方案用的是overlay网络,那么其他Kubernetes集群注册的时候,由于Pod IP和宿主机IP不在同一个网络平面,导致注册中心不能准确识别Pod的IP,只能识别到Pod所在Kubernetes宿主机的IP(Pod以SNAT的方式访问集群外部)。
想要解决这个问题,可以考虑使用Pod的多网络平面,也就是给Pod增加第二个虚拟网卡,挂载数据中心到同一个网络平面的IP。这种方式类似macvlan、ipvlan,不用再单独配置DNS,但弊端是当宿主机上启动的macvlan数量较多时,网卡性能会下降。
如果Spring Cloud的边界远大于一个Kubernetes边界,想让一套Spring Cloud分布在很多个Kubernetes集群时,最好把微服务配置中心和注册中心从Kubernetes集群中独立出来,放在虚拟机或者物理机上。这样做的好处是让这个配置+注册中心离所有Kubernetes集群网络都比较近。而且,在虚拟机或者物理机上部署配置+注册中心,当需要注册微服务的时候,也不必再经过类似Ingress的环节,性能也会得到提升。此外,我们可以针对独立的配置+注册中心做高可用或者容灾方案。
注册中心的整体选择思路主要从三个维度考量:应用是否跨开发语言,微服务的边界是否大于Kubernetes集群,以及是否限定应用的Service名称。
1)应用跨语言,微服务边界不大于一个Kubernetes集群,不限定应用的Service名称:使用Kubernetes平台的etcd。
2)应用跨语言,微服务边界大于一个Kubernetes集群,不限定应用的Service名称:使用应用级注册中心,而且每种语言都需要设置自己的注册中心。
3)应用不跨开发语言,微服务不大于一个Kubernetes边界,不限定应用的Service名称:使用Kubernetes平台的etcd。
4)应用不跨开发语言,微服务大于一个Kubernetes边界,不限定应用的Service名称:使用一个应用级注册中心。
5)限定应用的Service名称:使用应用级注册中心。