云原生时代——后微服务时代¶
跨越软件与硬件之间的界限
最常见的分布式问题:
注册发现、跟踪治理、负载均衡、传输通讯
最常见的分布式问题传统的解决方法:
如果某个系统需要「伸缩扩容」,我们通常会购买新的服务器,多部署几套副本实例来分担压力;
如果某个系统需要解决「负载均衡」的问题,我们通常会布置负载均衡器,并选择恰当的均衡算法来分流;
如果需要解决「安全传输」的问题,我们通常会布置 TLS 传输链路,配置好 CA 证书,以保证通讯不被窃听篡改;
如果需要解决「服务发现」的问题,我们通常会设置 DNS 服务器,让服务访问依赖稳定的记录名而不是易变的 IP 地址。
备注
计算机科学经过了这么多年的发展,这些问题已经大多都有了专职化的基础设施来帮助解决了。在微服务时代,我们之所以不得不在应用服务层面,而不是基础设施层面去解决这些分布式问题,完全是因为**由硬件构成的基础设施,跟不上由软件构成的应用服务的灵活性**。这其实是一种无奈之举。
备注
注册发现、跟踪治理等等问题的解决,依靠的就是虚拟化技术和容器化技术
时间点:
2014 年,微服务真正崛起的时候,Docker Swarm(2013 年)和 Apache Mesos(2012 年)就已经存在了,
更早之前也出现过软件定义网络(Software-Defined Networking,SDN)、软件定义存储(Software-Defined Storage,SDS)等技术,
但是,被业界广泛认可、普遍采用的通过虚拟化的基础设施,去解决分布式架构问题的方案,
应该要从 2017 年 Kubernetes 赢得容器战争的胜利开始算起。
2017 年,
长期作为 Docker 竞争对手的 RKT 容器一派的领导者 CoreOS,宣布放弃了自己的容器管理系统 Fleet,
未来将会把所有容器管理功能,转移到 Kubernetes 之上去实现。
容器管理领域的独角兽 Rancher Labs,宣布放弃其内置了数年的容器管理系统 Cattle,提出了 “All-in-Kubernetes” 战略,
从 2.0 版本开始,把 1.x 版本能够支持多种容器管理工具的 Rancher,“升级” 为只支持 Kubernetes 一种的容器管理系统。
Kubernetes 的主要竞争者 Apache Mesos,在 9 月正式宣布了 “Kubernetes on Mesos” 集成计划,
开始由竞争关系,转为了对 Kubernetes 提供支持,
使其能够与 Mesos 的其他一级框架(如 HDFS、Spark 和 Chros 等)进行集群资源动态共享、分配与隔离。
Kubernetes 的最大竞争者,Docker Swarm 的母公司 Docker,
终于在 10 月被迫宣布 Docker 要同时支持 Swarm 与 Kubernetes 两套容器管理系统,
也就是承认了 Kubernetes 的统治地位。
备注
2017 年,可以说是容器生态发展历史中具有里程碑意义的一年。
备注
一旦硬件能够跟得上软件的灵活性,那么这些与业务无关的技术问题,便很可能从软件的层面剥离出来,在硬件的基础设施之内就被悄悄解决掉,让软件可以只专注于业务,真正 “围绕业务能力构建” 团队与产品。那么原来只能从软件层面解决的分布式架构问题,于是有了另外一种解法:应用代码与基础设施软硬一体,合力应对。
在 DCE 中未能实现的 “透明的分布式应用” 就成为了可能,
Martin Fowler 设想的 “凤凰服务器” 就成为了可能,
Chad Fowler 提出的 “不可变基础设施” <> 也会成为可能。
Kubernetes 其实并没有完美地解决全部的分布式问题:
有一些问题处于应用系统与基础设施的边缘,我们很难能完全在基础设施的层面中,去精细化地解决掉它们。
基础设施是针对整个容器来做整体管理的,它的粒度就相对粗犷。
例子:
微服务 A 调用了微服务 B 中发布的两个服务,我们称之为 B1 和 B2,
假设 B1 表现正常,但 B2 出现了持续的 500 错,
那在达到一定的阈值之后,我们就应该对 B2 进行熔断,以避免产生雪崩效应。
如果我们仅在基础设施的层面来做处理,这就会遇到一个两难问题,
也就是切断 A 到 B 的网络通路,会影响到 B1 的正常调用,
而不切断的话则会持续受到 B2 的错误影响。
类似的情况不仅仅会在断路器上出现,服务的监控、认证、授权、安全、负载均衡等功能,都有细化管理的需求。
比如:
服务调用时的负载均衡,往往需要根据流量特征,调整负载均衡的层次、算法等,
而 DNS 尽管能实现一定程度的负载均衡,但它通常并不能满足这些额外的需求。
为了解决这一类问题,微服务基础设施很快就进行了第二次进化,引入 “服务网格”(Service Mesh)的 “边车代理模式”(Sidecar Proxy)
“服务网格”的“边车代理模式”:
这个代理除了会实现正常的服务调用以外(称为数据平面通讯),
同时还接受来自控制器的指令(称为控制平面通讯),
根据控制平面中的配置,分析数据平面通讯的内容,以实现熔断、认证、度量、监控、负载均衡等各种附加功能。
很难从概念上,来判定一个与应用系统运行于同一资源容器之内的代理服务,到底应该算是软件,还是算作基础设施
但只要它对应用是透明的,不需要改动任何软件代码就可以实现服务治理,这就足够了。
备注
未来几年,Kubernetes 将会成为服务器端标准的运行环境,如同在此之前的 Linux 一样;服务网格将会成为微服务之间通讯交互的主流模式,它会把 “选择什么通讯协议”“如何做认证授权” 之类的技术问题隔离于应用软件之外,取代今天的 Spring Cloud 全家桶中的大部分组件的功能。这是最理想的 Smart Endpoints 解决方案,微服务只需要考虑业务本身的逻辑就行了。