最近在学习k8s与serviceMesh技术时,由于发现网上内容概念太多,太乱,太细,很多文章就是COPY很多基本知识,与我期望的认知过程不符合,所以写这样一个学习笔记。不讲安装,不讲demo,只是整合一些知识点,并理清相关的概念与关联,形成一个知识框架方便记忆与使用。
正好看到这么一篇文章–“关于整体性学习”https://www.jianshu.com/p/1019549f256b,与我想法不谋而合,我的目的就是建立这么一个基础的知识框架。
因为水平有限,有些知识点还是自己猜测的,有不对的请各位看官指正。
k8s有master与node,看多了分布式系统的设计,总会感觉套路都差不多。比如:
一般都有管理中心(协调中心,配置中心)与业务中心,无论k8s,hadoop,rocketmq。由于配置ssh,免密登陆,机器间通过相关TCP等协议,可以远程操作很多事件,传数据,传脚本,传代码,可以安排哪个业务节点,用什么代码,处理什么数据 。有新节点加入了,控制中心可以知道,可以合理分配任务,所以就很好扩容增能了。
再比如大数据处理中间件,除了移动数据,还可以把jar包发给业务中心,classLoader动态加载到自己的jvm中,处理分给自己的数据。
业务中心一般要向控制中心心跳,要报告数据处理情况,报告性能情况。hadoop的节点还分两类,map业务节点要知道有哪些reduce业务节点,要把自己的数据给过去继续处理,自己的数据要不要持久化本地。
管理中心一般要实现高可用,有相关的一致性协议。
甚至再推广一下,看到蚂蚁的三城五中心10单元部署,为了尽可能在一个机房调用,还有备份,这样的用户与应用分区安排与kafka的分区也是非常像的。包括数据库分片也同样按用户按机房分片,一个单元的从应用到数据都紧密耦合一起,还有跨机房备份,更像kafka跨节点分区了。
那么k8s的master当然可以行程控制Node节点上启动一个容器,加载一个远程导入的镜像,映射一个端口,容器知道主masterip,上报心跳,自己的IP地址等信息。那自然就可以组成一个集群。也很容易想到可以分类,可以扩容。
所以,从直觉上会大概知道这些系统是怎么工作的,但是如何把这些套路与真正的k8s实现结合起来,到底Pod, Deployment, ReplicaSet,Service这些都是什么?都存在于哪里呢?
开始用docker还是比较方便的,但如何从docker的组合角度进一步理解,如何实现部署可伸缩应用,应用编组提供服务,进一步提供对外的服务?K8s会怎么做出选择呢?
先上图,左边是我理解的k8s中的东西,右边是一般使用Docker。
先不讲伸缩(假设有脚本可以帮你完成),你在装有Linux的物理机或者虚拟机上,如何用docker组织出一个微服务呢?首先是相同的应用应分散在不同的机器上,另外不同的应用之间如何调用?至于分散在哪,哪些相同,假设有静态配置供查找。
如果不同的应用在同一个机器上,而在不同的容器内,可以通过4种方式调用。如果在不同的机器上,只能通过机器ip与内外映射进入容器内。如果要无差别对待两种情况,都映射机器端口来调用可以。
如果容器内被调用应用的容器要自由漂移,从同机移动到其它机器,调用方需要知道这个变化造成的ip变化,这个可以办到。但同主机的多容器使用的宿主机volumn,共享一些主机东西,密切相关可能就破坏了。
另外,如果想调度容器,容器有可能Docker容器,但它也可能是一个rkt的容器,所以不如让宿主机(当然物理机不行)漂移起来。这可以理解为k8s的基本操作单元pod。
看到这些,共享IP,端口空间,分配CPU,共享volumn,这pod与虚拟机是多么的相似,可以认为就是一个虚拟机吧。虚拟机的启停,迁移,远程安装docker,都可以实现的。
但Deployment, ReplicaSet,Service又是什么呢?是存在于mater还是node呢?不少文章介绍了配置文件,用简图表示了包含关系,比如Deployment调用ReplicaSet控制pod复制的。所以猜测Deployment与ReplicaSet都是mater上的组件,pod在哪个node产生,是由mater控制的。那service又是什么,又在哪呢?
既然类似虚拟机的pod飘移起来,从一个主机到另一个主机。应用也要分组来组成同一种service。service应该是一个比较固定的概念,它包含的同类应用pod是变化的,需要一个映射关系。主机是固定的,service是数量不定比较稳定的,pod是变化的,所以每个主机上有相关的关系表。我从一个pod发起调用,从当前所在的主机上找到这个服务service的pod都在哪,按策略找到一个,连接过去。
主机、服务、pod是分属三个层次的内容,两层映射关系表。主机的Ip当然在主机物理网络内了。可飘移pod之间类似虚拟机之间,自己有完善的ip来组网,毕竟真正的调用就在这层ip上,就是plannel虚拟网络。服务ip处理两者之间,只做数据包转发功能,是一层特殊性质的ip。前面docker提到容器通讯,也可能有一层桥接网络,这个如果有的话,层次最低,这里提一下。
这三个层次关系,由kuber-proxy处理。当service给外部提供服务,要有主机与端口与service的映射关系,否则内部不用配置。
所以,service应该是在每个Node上存在的组件,应该与kuber-proxy一起工作吧。
再总结一下:k8s由mater与node组成,这种结构与很多软件产品的结构相似,比如hadoop,yarn,rocketmq。一个负责总的管理,一个负责具体业务。比如总控通过deploy与ReplicaSet组件来处理Pod漂移与增减,同时更新每个节点node上的service信息,这样就更新映射关系表。
istio主要功能是为每个服务,分离出公共的调用,发现,流量控制等通用功能,服务专注于业务功能,其它交给istio。istio肯定有一个附着在应用一起的sideCar(贴身待者)。
istio的sideCar就叫Envoy,在上图中红色背景标识出来了。它注入到每个pod创建过程中,拉起一个容器运行Envoy,与应用在同一个pod中。一开始我受springCloud的sideCar影响,以为Envoy与你的服务之间有调用关系。springCloud中是为了包装异构服务的发现,其实就是一个网关应用代理了异构服务, 7层协议调用。
后来发现了一个图,看到了Linxu/netFilter,一查此概念,恍然大悟。
Netfilter/IPTables是Linux2.4.x之后新一代的Linux防火墙机制,是linux内核的一个子系统。Netfilter采用模块化设计,具有良好的可扩充性。其重要工具模块IPTables从用户态的iptables连接到内核态的Netfilter的架构中,Netfilter与IP协议栈是无缝契合的,并允许使用者对数据报进行过滤、地址转换、处理等操作。
这正好是4层通讯拦截,路由的地方,Envoy并不与你的应用有半毛钱的直接关系,它是给Netfilter用的。
Envoy具体特点:
猜测一下,比如之前K8s中一个pod调用另一个服务,要走上一层找到服务,返回对应的随机pod,没办法控制流量。现在sideCar可能从k8s拿到了映射关系,并附加了自己的策略,就按配置的比例,在pannle虚拟网络上路由数据包。
当然sideCar要接受一些控制管理监控,这些就是建一群专门的pod服务了,没啥特别要讲的。
这篇文章写的比较清楚:https://www.cnblogs.com/assion/p/11249519.html
更详细的可以看这个:https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/78919669
准确点说SpringCloud是适合实现微服务的一套基础开发框架,SpringCloud有助于讯速的落地微服务架构。SpringCloud是以Java库的形式工作所以它的工作层面是在应用层(研发层)。
k8s并不是因为微服务而生,而是因为docker而生,只是天时地利人和正好赶上了微服务流行的时代,docker的特性正好特别适用于微服务,而k8s进一步对docker方便的编排。它的工作层面是在容器层(运维层)
Istio开始就是与k8s结合设计的,加入了特色功能,Istio结合k8s可以牛逼的落地微服务架构。
话说还看到一个把springcloud部署到k8s的例子,感觉怪怪的,一种发现套另一种发现上,一种路由套另一种路由。不知道把springcloud套在istio会怎么样?一种限流,熔断套另一种限流熔断吗?
https://blog.csdn.net/weixin_44388301/article/details/99575907
网上只看到些蚂蚁金服在搞istio的进一步扩展,他们的 SOFAMesh 项目,是蚂蚁金服推出的 Service Mesh 开源产品,简单的理解为是 Istio 的落地增强版本。
http://www.uml.org.cn/wfw/201910213.asp?artid=22547
在这个架构中,和 Istio 原版最大的不同在于没有选择 Istio 默认集成的 Envoy,而是用 Golang 开发了一个名为 SOFAMosn 的 Sidecar 来替代 Envoy。为什么我们选择了用 Golang 语言来实现?
我们需要考虑在 SOFAMesh 和 SOFAMosn 中增加这些通讯协议的支持,需要支持 REST 和 gRPC 之外的众多协议,尤其是要可以让客户非常方便的扩展支持各种私有TCP协议。
快速的扩展支持一个新的通讯协议。
解决问题:注册模型不匹配,原有用接口调用的代码调不通。一般情况下 Dubbo 程序是按照 Interface 来注册和发现,调用时也是通过 Interface 来调用。
设计了一个名为 DNS通用选址方案 的解决方案,用来支持 Dubbo 等SOA框架,容许通过接口名来调用服务。不做 SOA 程序的微服务改造,就直接搬迁到 SOFAMesh,提前受益。
我猜测接口名是相对service的,要靠拢istio就要是ip定位,具体的实现不知道在哪,就要有一个接口与DNS对应关系。
然后我们将探索一下服务间通讯的范围,看看 Service Mesh 可以在哪些领域得到应用
Service Mesh 起初关注的是东西向通讯,即系统内部各个服务之间的通讯,而这通常都是同步的,走REST或者RPC协议。
通过将 Sidecar 用于南北向通讯,重用 Sidecar 的请求转发和服务治理功能。如服务发现,负载均衡,路由,灰度,安全,认证,加密,限流,熔断……