回顾
前面文章 (Spring Cloud Kubernetes 之实战服务注册与发现) 中,讲述了 spring-cloud-k8s
在微服务实践中,带来了多大的优势。介绍了 k8s 中资源 Service,其如何来实现服务的注册与发现。
其实在 k8s 中,Service 资源的类型比较多,有四种:
ExternalName:创建一个 DNS 别名指向 service name,这样可以防止 service name 发生变化,但需要配合 DNS 插件使用。
ClusterIP:默认的类型,用于为集群内 Pod 访问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定 IP。
NodePort:基于 ClusterIp,用于为集群外部访问 Service 后面 Pod 提供访问接入端口。
LoadBalancer:它是基于 NodePort。
我们一般会默认使用的类型:ClusterIP,但此时会出现一种问题,那就是此类型的 Service 被用来访问非同一 NS 下的 pods,即<servicename>.<namespace>.svc.cluster.local
形式访问 pod,只能通过 servicename 直接访问同一 namespace 下的 pod。
案例
下面,我们来看案例:假设我这里有三个服务:cas-server、rest-service、diff-ns-service 等,我通过 deployment 来部署这些服务的 pod。
可以看到这些 pod 处于 不同的 namespace 下,同样的对应的 service 也是处于对应的 namespace 下:
ns-app diff-ns-service-service ClusterIP 10.16.178.187 <none> 2008/TCP 6h39m app=diff-ns-service
system-server cas-server-service ClusterIP 10.16.134.168 <none> 2000/TCP 16d app=cas-server
system-server rest-service-service ClusterIP 10.16.128.58 <none> 2001/TCP 16d app=rest-service
这里的 Service 类型都是 ClusterIp
,在前面,我们验证过基于这样的服务,我们可以利用 springcloud-k8s 来实现同一 namespace 下服务之间的注册与发现,实现负载均衡。但如果不在同一 namespace 下呢?比如这里的diff-ns-service
,它与另外两个服务不在同一 namespace。此时我们通过基于 Ribbon 的负载均衡策略。这是因为我们默认了 KubernetesRibbonMode
的模式:POD,就是获取服务提供者的 pod 的 ip 和 port,该 ip 是 kubernetes 集群的内部 ip,只要服务消费者是部署在同一个 kubernetes 集群内就能通过 pod 的 ip 和服务提供者暴露的端口访问。当我们使用当mode
为SERVICE
时,就是获取服务提供者在 k8s 中的 service 的名称和端口,使用这种模式会导致 Ribbon 的负载均衡失效,转而使用 k8s 的负载均衡。
所以,如果不使用默认的 Ribbon 来