赞
踩
在上一篇《Kubernetes网络三部曲~Pod网络》中,波波讲解了K8s的4层网络中的第1层Pod网络。有了Pod网络,K8s集群内的所有Pods在逻辑上都可以看作在一个平面网络内,可以正常IP寻址和互通。但是Pod仅仅是K8s云平台中的虚拟机抽象,最终,我们需要在K8s集群中运行的是应用或者说服务(Service),而一个Service背后一般由多个Pods组成集群,这时候就引入了服务发现(Service Discovery)和负载均衡(Load Balancing)等问题,这就是第2层Service网络要解决的问题,也是本文我要展开分析的问题。
我们假定第1层Pod网络已经存在,下图是K8s的第2层Service网络的简化概念模型:
我们假定在K8s集群中部署了一个Account-App应用,这个应用由4个Pod(虚拟机)组成集群一起提供服务,每一个Pod都有自己的PodIP和端口。我们再假定集群内还部署了其它应用,这些应用中有些是Account-App的消费方,也就说有Client Pod要访问Account-App的Pod集群。这个时候自然引入了两个问题:
实际上,K8s通过在Client和Account-App的Pod集群之间引入一层Account-Serivce抽象,来解决上述问题:
K8s中为何要引入Service抽象?背后的原理是什么?后面我将以技术演进视角来解释这些问题。
DNS域名服务是一种较老且成熟的标准技术,实际上DNS可以认为是最早的一种服务发现技术。
在K8s中引入DNS实现服务发现其实并不复杂,实际K8s本身就支持Kube-DNS组件。假设K8s引入DNS做服务发现(如上图所示),运行时,K8s可以把Account-App的Pod集群信息(IP+Port等)自动注册到DNS,Client应用则通过域名查询DNS发现目标Pod,然后发起调用。这个方案不仅简单,而且对Client也无侵入(目前几乎所有的操作系统都自带DNS客户端)。但是基于DNS的服务发现也有如下问题:
考虑到上述不同DNS客户端实现的差异,不在K8s控制范围内,所以K8s没有直接采用DNS技术做服务发现。注意,实际K8s是引入Kube-DNS支持通过域名访问服务的,不过这是建立在CusterIP/Service网络之上,这个我后面会展开。
另外一种较新的服务发现技术,是引入Service Registry+Client配合实现,在当下微服务时代,这是一个比较流行的做法。目前主流的产品,如Netflix开源的Eureka + Ribbon,HashiCorp开源的Consul,还有阿里新开源Nacos等,都是这个方案的典型代表。
在K8s中引入Service Registry实现服务发现也不复杂,K8s自身带分布式存储etcd就可以实现Service Registry。假设K8s引入Service Registry做服务发现(如上图所示),运行时K8s可以把Account-App和Pod集群信息(IP + Port等)自动注册到Service Registry,Client应用则通过Service Registry查询发现目标Pod,然后发起调用。这个方案也不复杂,而且客户端可以实现灵活的负载均衡策略,但是需要引入客户端配合,对客户应用有侵入性,所以K8s也没有直接采用这种方案。
K8s虽然没有直接采用上述方案,但是它的Service网络实现是在上面两种技术的基础上扩展演进出来的。它融合了上述方案的优点,同时解决了上述方案的不足,下节我会详细剖析K8s的Service网络的实现原理。
前面提到,K8s的服务发现机制是在上节讲的Service Registry + DNS基础上发展演进出来的,下图展示K8s服务发现的简化原理:
在K8s平台的每个Worker节点上,都部署有两个组件,一个叫Kubelet,另外一个叫Kube-Proxy,这两个组件+Master是K8s实现服务注册和发现的关键。下面我们看下简化的服务注册发现流程。
实际消费者Pod也并不直接调服务的ClusterIP,而是先调用服务名,因为ClusterIP也会变(例如针对TEST/UAT/PROD等不同环境的发布,ClusterIP会不同),只有服务名一般不变。为了屏蔽ClusterIP的变化,K8s在每个Worker节点上还引入了一个KubeDNS组件,它也监听Master并发现服务名和ClusterIP之间映射关系,这样, 消费者Pod通过KubeDNS可以间接发现服务的ClusterIP。
注意,K8s的服务发现机制和目前微服务主流的服务发现机制(如Eureka + Ribbon)总体原理类似,但是也有显著区别(这些区别主要体现在客户端):
个人认为,对比目前微服务主流的服务发现机制,K8s的服务发现机制抽象得更好,它通过ClusterIP统一屏蔽服务发现和负载均衡,一个服务一个ClusterIP,这个模型和传统的IP网络模型更贴近和易于理解。ClusterIP也是一个IP,但这个IP后面跟的不是一个服务实例,而是一个服务集群,所以叫集群ClusterIP。同时,它对客户应用无侵入,且不穿透没有额外性能损耗。
总结
有了Service抽象,K8s中部署的应用都可以通过一个抽象的ClusterIP进行寻址访问,并且消费方不需要关心这个ClusterIP后面究竟有多少个Pod实例,它们的PodIP是什么,会不会变化,如何以负载均衡方式去访问等问题。但是,K8s的Service网络只是一个集群内可见的内部网络,集群外部是看不到Service网络的,也无法直接访问。而我们发布应用,有些是需要暴露出去,要让外网甚至公网能够访问的,这样才能对外提供服务。K8s如何将内部服务暴露出去?这个是波波在下一篇《Kubernetes网络三部曲~外部接入网络》要展开的问题,敬请期待。
————————————————
版权声明:本文为CSDN博主「架构师波波」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yang75108/article/details/101267444
相关阅读:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。