什么是Service Discovery
Service Discovery指自动发现设备或在网络中的服务,例如蓝牙设备搜索,DNS服务发现,微服务注册发现等
Service Discovery的作用
- 减少用户或管理员的配置工作
- 支持服务动态扩展
- 提升系统可用性,快速屏蔽出错的服务实现方式Server-side Discovery Pattern
实现方式
Server-side Discovery Pattern
在服务资源前添加loadbalancer(或反向代理),这个lb的外部地址通常是固定的,由这个lb在分发请求,实例通过向Service Register新增或删除信息来更新当前的资源状况。Service Register向其他服务资源提供当前的资源信息,用以更新路由规则。
优点:对客户端隐藏了实现细节
缺点:引入了loadbalancer组建,增加了系统故障风险,lb组件可能成为系统的性能瓶颈,该lb需要支持client与server之间的所有网络协议,增加了一次网络路由节点
Client-side Dicovery Pattern
相对于server-side的方式,一处了loadbalancer组件,转而由client从service-register获取实例清单,并自行选择本次请求的目标实例地址。
优点:无需引入多余的组件
缺点:将client和service register耦合在一起,增加了client的负复杂度
client需要实现负载均衡相关的算法,对client具有侵入性,尤其是考虑client可能是由多种语言实现时,则需要每种语言都实现一次
DNS-SD(DNS-Based Service Discovery)
通过标准DNS也可以实现服务发现,使用DNS服务器为同一个服务域名配置多个ip地址,通过Round-Robin或其他规则选取服务ip。但这种方式有明显的缺点。
- 有很多DNS实现并没有遵循标准对TTL缓存的记录进行过期淘汰策略,这导致service信息可能无法及时更新
- 一些应用对DNS进行了缓存,在首次查询后,之后就不会进行更新了
- 即使应用完全遵循了DNS的标准,而由于服务发现需要的低延迟特性,DNS的需要接近0 TTL,这可能会给DNS服务器带来很高的负载
Service Discovery In Kubernetes
前提: 已经对kubernetes中的POD,SERVICE,NODE等基本概念有所了解
kubernets service discovery
Control-plane:就服务发现来说,控制节点的作用类似于注册中心,负责借口新建的pod网络信息并存储到etcd中。同时通知其他已存在的节点当前新建或更新的节点网络信息
Node:从网络路由的角度来说,Node可以视为虚拟机,我们的服务就运行在Node上,而kube-proxy是运行在node上的一个网络代理组件,由它监听Control-plane状态和信息更新
Service:同一类POD运行的服务的集合,是一个抽象的概念,每一个service都会被分配一个clusterip
DNS add-on:DNS插件,打开的情况下,可以为每一个service分配一个有效的DNS记录
大致可以把kubernetes中的一次数据请求分为以下几个步骤:
- 服务新增:Service2新增了一个运行在Node02上的POD
- 服务注册:Node02上的kube-proxy将该新增node的网络信息同步到Control-plane
- 服务更新:Node01上的kube-poxy监听Control-plane有更新消息后,获取并增加Service2的路由规则
- 服务请求:Service1通过Service2的DNS记录发送数据请求
- 网络路由:Node01上的路由规则生效,将数据请求发送到目标Service所在的机器上
kube-proxy 网络路由
kube-proxy负责将Control-plane中关于Service pod的网络信息编织成路由规则到node上,而随后pod中针对目标service的请求,就会被路由规则所代理转发到目标位置。也就是说,kubeproxy充当了client-side模式中的路由插件,只是不需要由服务自行实现,而是采用了流量代理的模式在外部实现,这样可以避免对服务的侵入性,同时增加了独立性与通用性。kube-proxy不仅实现了路由,还支持负载均衡。目前主要有以下几种实现方式。
- User space proxy mode 用户态的代理模式,这种模式kube-proxy将为每一个service在本地打开一个端口,kubeproxy将对iptables增加一条规则以监听该端口的流量,kubeproxy将把任何对该端口的请求流量都将被代理转发到目标目标sevice的一个pod(默认使用Round-Robin)。
- Iptables 顾名思义,基于Linux内核提供的网络功能实现,将路由规则写入iptables,相比于user space模式,流量转发由Linux netfliter处理,而kubeproxy只负责更新iptables即可,因此有更低的系统延迟。
- IPVS 与iptables类似,但是通过netlink创建规则,IPVS基于netfliter hook实现,与iptables相比工作在系统更底层,因此有更高的效率。同时IPVS支持更多的负载均衡算法
总结
kubernetes中,通过service cluster ip,DNS add-on,kube-proxy整合的方案,同时兼具了传统client-side和server-side的优势,同时规避了相应的缺点。
- 对client屏蔽了实现细节
- 基于操作系统底层网络架构实现的路由转发,因此对于效率的影响很小
- 没有在调用链中引入新的网络节点 总的来讲,kubernetes的设计方案,将负载均衡,服务发现等服务治理相关的细节与服务应用解耦,使应用程序可以更专注于业务逻辑,转而由平台来提供系统服务治理功能。
参阅
What is Service Discovery, wiki
What is Service Load balancing, wiki
Kubernetes Service
Ribbon discovery in Kubernetes, Spring