云架构师学习------技术路线与总结
- 云架构师学习------技术路线与总结
- 一、什么是架构
- IT架构-数据架构-应用架构
- IT架构
- 应用架构
- 数据架构
- 架构的六个层面
- 基础设施层
- 数据层
- 中间层
- 基础服务层
- 业务服务层
- 用户接口层
- 二、云计算的历史演进与基本原理
- 云计算的本质:资源到架构的全面弹性
- 云计算如何管理应用
- 三、Linux基础知识
- 四、数据中心和网络基础知识
- 数据中心网络架构演进
- 传统三层网络
- 叶脊网络架构
- Spine-Leaf 的工作原理
- Spine-Leaf 的优势
- Spine-Leaf 的缺陷
- 叶脊网络架构如何设计?
- 五、基于OpenStack了解云平台
- OpenStack的云平台设计模式
- 第一:基于PKI Token的认证模式
- 第二:基于Role Based Access Control的鉴权模式
- 第三:基于Quota的配额管理
- 第四:基于预选和优选两阶段的Scheduler机制
- 第五:基于独立虚拟子网的网络模式
- 第六:基于Copy on Write的镜像机制
- 第七:基于namespace和cgroup的隔离和Qos机制
- 第八:基于iptables的安全机制
- 第九:基于Mesos和Kubernetes了解容器平台
- 第十:基于Hadoop和Spark了解大数据平台
- 第十一:基于Lucene和ElasticSearch了解搜索引擎
- 第十二:基于SpringCloud了解微服务
- 设计要点一:**负载均衡 + API 网关**
- 设计要点二:**无状态化与独立有状态集群**
- 设计要点三:**数据库的横向扩展**
- 设计要点四:**缓存**
- 设计要点五:**服务拆分与服务发现**
- 设计要点六:**服务编排与弹性伸缩**
- 设计要点七:**统一配置中心**
- 设计要点八:**统一日志中心**
- 设计要点九:熔断,限流,降级
- 设计要点十:全方位的监控
云架构师学习------技术路线与总结
云架构师的技术路线梳理总结
一、什么是架构
IT架构-数据架构-应用架构
IT架构
简单理解IT架构就是:计算,网络,存储。这是云架构师的基本功,也是最传统的云架构师应该首先掌握的部分,良好设计的IT架构,可以降低CAPEX和OPEX,减轻运维的负担。数据中心,虚拟化,云平台,容器平台都属于IT架构的范畴。
应用架构
随着应用从传统应用向互联网应用转型,仅仅搞定资源层面的弹性还不够,常常会出现创建了大批机器,仍然撑不住高并发流量。因而基于微服务的互联网架构,越来越成为云架构师所必需的技能。良好设计的应用架构,可以实现快速迭代和高并发。数据库,缓存,消息队列等PaaS,以及基于SpringCloud和Dubbo的微服务框架,都属于应用架构的范畴。
数据架构
数据成为人工智能时代的核心资产,在做互联网化转型的同时,往往进行的也是数字化转型,并有战略的进行数据收集,这就需要云架构师同时又大数据思维。有意识的建设统一的数据平台,并给予数据进行数字化运营。搜索引擎,Hadoop,Spark,人工智能都属于数据架构的范畴。
架构的六个层面
从系统的角度出发,架构分六个层次
持续集成和持续发布是保证微服务拆分过程中的快速迭代,以及变更后保证功能不变的,不引入新的Bug。
服务发现和服务治理是微服务之间互相的调用,以及调用过程中出现异常情况下的熔断,限流,降级策略。
大数据和人工智能是通过收集各个层面的数据,例如用户访问数据,用户下单数据,客服询问数据等,结合统一的中台,对数据进行分析,实现智能推荐。
监控与APM是基础设施的监控和应用的监控,发现资源层面的问题以及应用调用的问题。
基础设施层
在数据中心里面,会有大量的机架,大量的服务器,并通过交换机和路由器将服务器连接起来,有的应用例如Oracle是需要部署在物理机上的。为了管理的方便,在物理机之上会部署虚拟化,例如Vmware,可以将对于物理机复杂的运维简化为虚拟机灵活的运维。虚拟化采取的运维方式多是由运维部门统一管理,当一个公司里面部门非常多的时候,往往要引入良好的租户管理,基于Quota和QoS的资源控制,基于VPC的网络规划等,实现从运维集中管理到租户自助使用模式的转换,托生于公有云的OpenStack在这方面做的是比较好的。随着应用架构越来越重要,对于标准化交付和弹性伸缩的需求越来越大,容器最为软件交付的集装箱,可以实现基于镜像的跨环境迁移,Kubernetes是容器管理平台的事实标准。
数据层
第二个层次是数据层,也即一个应用的中军大营,如果是传统应用,可能会使用Oracle,并使用大量的存储过程,有大量的表联合查询,成本也往往比较高。但是对于高并发的互联网应用,需要进行微服务的拆分,数据库实例会比较多,使用开源的Mysql是常见的选择,大量的存储过程和联合查询往往会使得微服务无法拆分,性能会比较差,因而需要放到应用层去做复杂的业务逻辑,数据库表和索引的设计非常重要。当并发量比较大的时候,需要实现横向扩展,就需要基于分布式数据库,也是需要基于单库良好的表和索引设计。对于结构比较灵活的数据,可以使用MongoDB数据库,横向扩展能力比较好。对于大量的联合查询需求,可以使用ElasticSearch之类的搜索引擎来做,速度快,更加灵活。
中间层
第三个层次是中间件层,因为数据库层往往需要保证数据的不丢失以及一些事务,因而并发性能不可能非常大,所以我们经常说,数据库是中军大营,不能所有的请求都到这里来,因而需要一层缓存层,用来拦截大部分的热点请求。Memcached适合做简单的key-value存储,内存使用率比较高,而且由于是多核处理,对于比较大的数据,性能较好。但是缺点也比较明显,Memcached严格来讲没有集群机制,横向扩展完全靠客户端来实现。另外Memcached无法持久化,一旦挂了数据就都丢失了,如果想实现高可用,也是需要客户端进行双写才可以。Redis的数据结构比较丰富,提供持久化的功能,提供成熟的主备同步,故障切换的功能,从而保证了高可用性。另外微服务拆分以后,有时候处理一个订单要经过非常多的服务,处理过程会比较慢,这个时候需要使用消息队列,让服务之间的调用变成对于消息的订阅,实现异步处理。RabbitMQ和Kafka是常用的消息队列,当事件比较重要的时候,会结合数据库实现可靠消息队列。
基础服务层
第四个层次是基础服务层,有的时候成为中台层,将通用的能力抽象为服务对外提供原子化接口。这样上层可以根据业务需求,通过灵活的组合这些原子化接口,灵活的应对业务需求的变化,实现能力的复用,以及数据的统一管理,例如用户数据,支付数据,不会分散到各个应用中。另外基础服务层称为应用和数据库和缓存的一个分界线,不应该所有的应用都直接连数据库,一旦出现分库分表,数据库迁移,缓存选型改变等,影响面会非常大,几乎无法执行。如果将这些底层的变更拦截在基础服务层,上层仅仅使用基础服务层的接口,这样底层的变化会对上层透明,可以逐步演进。
业务服务层
第五个层次是业务服务层,或者组合服务层,大部分的业务逻辑都是在这个层面实现,业务逻辑比较面向用户,因而会经常改变,所以需要组合基础服务的接口进行实现。在这一层,会经常进行服务的拆分,实现开发独立,上线独立,扩容独立,容灾降级独立。微服务的拆分不应该是一个运动,而应该是一个遇到耦合痛点的时候,不断解决,不断演进的一个过程。微服务拆分之后,有时候需要通过分布式事务,保证多个操作的原子性,也是在组合服务层来实现的。
用户接口层
第六个层次是用户接口层,也即对终端客户呈现出来的界面和APP,但是却不仅仅是界面这么简单。这一层有时候称为接入层。在这一层,动态资源和静态资源应该分离,静态资源应该在接入层做缓存,使用CDN进行缓存。也应该UI和API分离,界面应该通过组合API进行数据拼装。API会通过统一的API网关进行统一的管理和治理,一方面后端组合服务层的拆分对APP是透明的,一方面当并发量比较大的时候,可以在这一层实现限流和降级。
二、云计算的历史演进与基本原理
云计算的本质:资源到架构的全面弹性
云计算的本质是实现从资源到架构的全面弹性。所谓的弹性就是时间灵活性和空间灵活性,也即想什么时候要就什么时候要,想要多少就要多少。
资源层面的弹性也即实现计算、网络、存储资源的弹性。这个过程经历了从物理机,到虚拟化,到云计算的一个演进过程。
架构层面的弹性也即实现通用应用和自有应用的弹性扩展。对于通用的应用,多集成为PaaS平台。对于自己的应用,通过基于脚本的Puppet, Chef, Ansible到基于容器镜像的容器平台CaaS。
云计算如何管理应用
大数据包含数据的收集,数据的传输,数据的存储,数据的处理和分析,数据的检索和挖掘等几个过程
三、Linux基础知识
四、数据中心和网络基础知识
数据中心网络架构演进
传统三层网络
接入层:接入交换机通常位于机架顶部,所以它们也被称为ToR(Top of Rack)交换机,它们物理连接服务器。
汇聚层:汇聚交换机连接同一个二层网络(VLAN)下的接入交换机,同时提供其他的服务,例如防火墙,SSL offload,入侵检测,网络分析等, 它可以是二层交换机也可以是三层交换机。
核心层: 核心交换机为进出数据中心的包提供高速的转发,为多个二层局域网(VLAN)提供连接性,核心交换机为通常为整个网络提供一个弹性的三层网络。
存在的问题
带宽的浪费:为了防止环路,汇聚层和接入层之间通常会运行STP协议,使得接入交换机的上联链路中实际承载流量的只有一条,而其他上行链路将被阻塞(如图中虚线所示),造成了带宽的浪费;
故障域较大:STP协议由于其本身的算法,在网络拓扑发生变更时需要重新收敛,容易发生故障,从而影响整个VLAN的网络;
难以适应超大规模网络:在云计算领域,网络规模扩大,数据中心也分布在不同的地理位置,虚拟机要求能在任意地点创建,迁移,而保持其网络属性(IP, 网关等)保持不变,需要支持大二层网络,在上图的拓扑中,无法在VLAN10和VLAN20之间作上述迁移;
-----传统架构下,当存在大量东西向流量时,汇聚交换机和核心交换机的压力会大大增加,网络规模和性能也就限制在了汇聚层和核心层。要支持大规模的网络,就必须有性能最好,端口密度最大的汇聚层核心层设备,这样的设备成本高,不是所有企业都买得起,且必须在建设网络时就预先规划好网络规模,在网络规模小时,会造成资源的浪费,在网络规模继续扩大时,扩容也比较困难,因而让企事业单位陷入了成本和可扩展性的两难选择之中。
-----数据中心的流量总的来说可以分为以下几种:
· 南北向流量:数据中心之外的客户端到数据中心服务器之间的流量,或者数据中心服务器访问互联网的流量。
· 东西向流量:数据中心内的服务器之间的流量。
· 跨数据中心流量:不同数据中心的流量,例如数据中心之间的灾备,私有云和公有云之间的通讯。
在传统数据中心中,业务通常采用专线方式部署。通常,服务部署在一个或多个物理服务器上,并与其他系统物理隔离。因此,传统数据中心东西向流量较低,南北向流量约占数据中心总流量的80%。
在云数据中心,服务架构逐渐从单体架构转变为Web-APP-DB,分布式技术成为企业应用的主流。服务的组件通常分布在多个虚拟机或容器中。该服务不再由一台或多台物理服务器运行,而是由多台服务器协同工作,导致东西向流量快速增长。
此外,大数据服务的出现使分布式计算成为云数据中心的标准配置。大数据服务可以分布在一个数据中心的数百台服务器上进行并行计算,这也大大增加了东西向流量。
传统的三层网络架构是为南北向流量占主导地位的传统数据中心设计的,不适合东西向流量较大的云数据中心。
一些东西向流量(如跨POD的二层和三层流量)必须经过汇聚层和核心层的设备转发,不必要地经过许多节点。传统网络通常设置1:10到1:3的带宽超额比,以提高设备利用率。随着超额订阅率,每次流量通过节点时性能都会显着下降。此外,第 3 层网络上的 xSTP 技术加剧了这种恶化。
因此,如果通过传统三层网络架构运行大量的东西向流量,连接到同一交换机端口的设备可能会争夺带宽,导致最终用户获得的响应时间很差。
叶脊网络架构
Clos 网络以其发明者Charles Clos命名,Charles Clos是一名电话网络工程师,他在 1950 年代需要解决如何应对电话网络的爆炸式增长这一问题. 提出了现在称之为 Clos 的网络架构。
上图一个简单的两层Clos网络
Spine-Leaf体系架构是由Spine和Leaf这两个交换层组成的数据中心网络拓扑结构。Leaf层由访问交换机组成,汇聚来自服务器的流量,并直接连接到Spine或网络核心。Spine交换机在全网格拓扑中互连所有Leaf交换机。上图中,绿色节点代表交换机,灰色节点代表服务器。在绿色节点中,最上面的是Spine节点,下面是Leaf节点。
Spine-Leaf 网络架构,也称为分布式核心网络,由于这种网络架构来源于交换机内部的 Switch Fabric,因此也被称为 Fabric 网络架构,同属于 CLOS 网络模型。事实已经证明,Spine-Leaf 网络架构可以提供高带宽、低延迟、非阻塞的服务器到服务器连接。
前面说过 CLOS 网络是三级交换架构,而 Leaf Spine 却只有两层,这是因为:网络架构中的设备基本都是双向流量,输入设备同时也是输出设备,因此三级 CLOS 沿着中间层对折,就得到了两层的网络架构。可以看出传统的三层网络架构是垂直的结构,而 Spine-Leaf 网络架构是扁平的结构,从结构上看,Spine-Leaf 架构更易于水平扩展。
从拓扑结构上看,Spine-Leaf 二层架构视乎要比传统三层网络架构简单得多,但为什么 Spine-Leaf 直到近些年才能得到普及呢?技术成熟度固然是因素之一,再一个就是数据中心网络发展过程中无法回避的成本问题。传统三层网络架构只有核心交换机是昂贵的 L3 交换机,但 Spine-Leaf 却要求所有节点都应该是 L3 交换机。因此,Spine-Leaf 也只能在设备价格下降了的这些年才得以被推广。
Spine-Leaf 的工作原理
Leaf Switch:相当于传统三层架构中的接入交换机,作为 TOR(Top Of Rack)直接连接物理服务器。与接入交换机的区别在于 L2/L3 网络的分界点现在在 Leaf 交换机上了。Leaf 交换机之上是三层网络,Leaf 交换机之下都是个独立的 L2 广播域,这就解决了大二层网络的 BUM 问题。如果说两个 Leaf 交换机下的服务器需要通讯,需要通过 L3 路由,经由 Spine 交换机进行转发。
Spine Switch:相当于核心交换机。Spine 和 Leaf 交换机之间通过 ECMP(Equal Cost Multi Path)动态选择多条路径。区别在于,Spine 交换机现在只是为 Leaf 交换机提供一个弹性的 L3 路由网络,数据中心的南北流量可以不用直接从 Spine 交换机发出,一般来说,南北流量可以从与 Leaf 交换机并行的交换机(edge switch)再接到 WAN router 出去。
Fabric 中的 Leaf 层由接入交换机组成,用于接入服务器,Spine 层是网络的骨干(Backbone),负责将所有的 Leaf 连接起来。每个低层级的 Leaf 交换机都会连接到每个高层级的 Spine 交换机上,即每个 Leaf 交换机的上行链路数等于 Spine 交换机数量,同样,每个 Spine 交换机的下行链路数等于 Leaf 交换机的数量,形成一个 Full-Mesh 拓扑。当 Leaf 层的接入端口和上行链路都没有瓶颈时,这个架构就实现了无阻塞(Nonblocking)。并且,因为任意跨 Leaf 的两台服务器的连接,都会经过相同数量的设备,所以保证了延迟是可预测的,因为一个包只需要经过一个 Spine 和另一个 Leaf 就可以到达目的端。
因为 Fabric 中的每个 Leaf 都会连接到每个 Spine,所以,如果一个 Spine 挂了,数据中心的吞吐性能只会有轻微的下降(Slightly Degrade)。如果某个链路的流量被打满了,Spline-Leaf 的扩容过程也很简单:添加一个 Spine 交换机就可以扩展每个 Leaf 的上行链路,增大了 Leaf 和 Spine 之间的带宽,缓解了链路被打爆的问题。如果接入层的端口数量成为了瓶颈,那就直接添加一个新的 Leaf,然后将其连接到每个 Spine 并做相应的配置即可。这种易于扩展(Ease of Expansion)的特性优化了 IT 部门扩展网络的过程。
传统的三层网络架构由核心层、汇聚层和接入层组成,由于该结构中存在多设备多路径冗余,会导致环路的形成。与此同时,传统的三层网络架构主要是为了南北向流量而设计,虽然也支持东西向流量,但其不足非常明显,如浪费核心交换机资源、多层转发增加了延时、最终用户响应时间过长等。因此,传统的三层网络架构并不适用计算机和存储服务器四处分布的大型虚拟化数据中心。
注:南北向流量指数据中心之外的客户端到数据中心服务器之间的流量,或数据中心服务器访问互联网的流量;东西向流量值数据中心内的服务器之间的流量。
Spine-Leaf 的优势
扁平化:扁平化设计缩短服务器之间的通信路径,从而降低延迟,可以显著提高应用程序和服务性能。
易扩展:如果 Spine 交换机的带宽不足,我们只需要增加 Spine 节点数,也可以提供路径上的负载均衡;如果接入连接不足,则只需增加 Leaf 节点数。
低收敛比:容易实现 1:X 甚至是无阻塞的 1:1 的收敛比,而且通过增加 Spine 和 Leaf 设备间的链路带宽也可以降低链路收敛比。
简化管理:叶脊结构可以在无环路环境中使用全网格中的每个链路并进行负载平衡,这种等价多路径设计,在使用 SDN 等集中式网络管理平台时处于最佳状态。SDN 允许在发生堵塞或链路故障时简化流量的配置,管理和重新分配路由,使得智能负载均衡的全网状拓扑成为一个相对简单的配置和管理方式。
边缘流量处理:随着物联网(IoT)等业务的兴起,接入层压力剧增,可能有数千个传感器和设备在网络边缘连接并产生大量流量。Leaf 可以在接入层处理连接,Spine 保证节点内的任意两个端口之间提供延迟非常低的无阻塞性能,从而实现从接入到云平台的敏捷服务。
多云管理:数据中心或云之间通过 Leaf Spine 架构仍可以实现高性能、高容错等优势,而多云管理策略也逐渐成为企业的必选项。
Spine-Leaf 的缺陷
Fabric 架构并非完美。叶子节点网络设备无论是性能要求还是功能要求,均高于传统架构下的接入设备,其作为各种类型的网关(二三层间、VLAN/VxLAN 间、VxLAN/NVGRE 间、FC/IP 间等等),芯片处理能力要求较高,目前尚无满足所有协议间互通的商用芯片;由于不存在相关的标准,为了实现各种类型网络的接入,其骨干节点与叶子节点间的转发各个厂商均采用了私有封装,这也为将来的互通设置了难题。除此之外,还有:
独立的 L2 Domain 限制了依赖 L2 Domain 应用程序的部署。要求部署在一个二层网络的应用程序,现在只能部署下一个机架下了。
独立的 L2 Domain 限制了服务器的迁移。迁移到不同机架之后,网关和 IP 地址都要变。
子网数量大大增加了。每个子网对应数据中心一条路由,现在相当于每个机架都有一个子网,对应于整个数据中心的路由条数大大增加,并且这些路由信息要怎么传递到每个 Leaf 上,也是一个复杂的问题。
叶脊网络架构如何设计?
在设计叶脊网络架构之前,您必须先确定一些重要的因素。如,收敛比(即超额预订比率)、叶交换机与脊交换机的比例、从叶层到脊层的上行链路、构建在第2层还是第3层等。
收敛比(即超额预订比率)——指所有设备在相同时间内发送流量的比值,也就是指南北向流量(下行链路带宽)和东西向流量(上行链路带宽)的比值。当前的网络设计应遵循3:1的超额预订比率,也就是说下行端口(叶交换机到服务器或存储设备)和上行端口(叶交换机到脊交换机)的比值应达到3:1。下图说明了如何测量叶子层和脊椎层的超额预订比率。
叶交换机和脊交换机的比例——由于叶脊网络架构中的网络端点仅与叶交换机连接,因此网络中叶交换机部署数量取决于网络端点所需连接的接口数。而又因为每台叶交换机都需要连接到脊交换机,因此脊交换机的端口密度取决于拓扑结构中叶交换机的最大数量,同时,网络中的脊交换机的数量取决于叶交换机之间的吞吐量、叶子层的冗余/等价多路径(ECMP)数以及脊交换机中的端口密度。
从叶层到脊层的上行链路——对于叶脊网络,从叶子层到脊椎层的上行链路通常为10G/40G,且可从10G迁移到40G。为了避免网络不会因主机的增加造成阻塞,最好是确保上行链路的传输速率比下行链路的传输速率快。
叶脊架构可构建在第二层或第三层——叶脊网络架构可构建在第2层(任何VLAN)或第3层(子网)中。在第2层中构建叶脊网络架构时,能提供较高的灵活性,允许VLAN跨越任何地方,以及MAC地址可迁移到任何地方。在第3层中构建叶脊网络架构时,可提供最快的收敛时间和较优越的扩展性(可扩展至最大规模),同时,其具备扇出(也就是扇形发散)等价多路径(ECMP)路由功能,可支持32个或更多脊交换机。
Spine-Leaf架构的主要好处之一就是它允许数据流从数据的源到数据的目标路径较短。无论源和目的地如何,Spine-Leaf结构中的数据流在网络上的跳数都相同,任意两个服务器之间都是Leaf—>Spine—>Leaf三跳可达的。
由于Spine-Leaf 架构不再需要 STP(生成树协议),容量也得到了提高。其依赖诸如 ECMP(等价多路径)路由等协议来平衡所有可用路径上的流量,同时仍然避免网络环路。
五、基于OpenStack了解云平台
云是基于计算,网络,存储虚拟化技术的,云和虚拟化的主要区别在于,管理员的管理模式不同,用户的使用模式也不同。
虚拟化平台没有多层次的丰富的租户管理,没有灵活quota配额的限制,没有灵活的QoS的限制,多采用虚拟网络和物理网络打平的桥接模式,虚拟机直接使用机房网络,没有虚拟子网VPC的概念,虚拟网络的管理和隔离不能和租户隔离完全映射起来。对于存储也是,公司采购了统一的存储,也不能和租户的隔离完全映射起来。
用虚拟化平台的特点是,对于这个平台的操作完全由运维部门统一管理,而不能将权限下放给业务部门自己进行操作。因为一旦允许不同的部门自己操作,大家都用机房网络,在没有统一管控的情况下,很容易网段冲突了。如果业务部门向申请虚拟机,需要通过工单向运维部门统一的申请。当然这个运维部门很适应这种方式,因为原来物理机就是这样管理的。
但是公有云,例如aws就没办法这样,租户千千万万,只能他们自己操作。在私有云里面,随着服务化甚至微服务化的进行,服务数目越来越多,迭代速度越来越快,业务部门需要更加频繁的创建和消耗虚拟机,如果还是由运维部统一审批,统一操作,会使得运维部门压力非常大,而且极大限制了迭代速度,因而要引入 租户管理,运维部灵活配置每个租户的配额quota和QoS,在这个配额里面,业务部门随时可以按照自己的需要,创建和删除虚拟机,无需知会运维部门。每个部门都可以创建自己的虚拟网络VPC,不同租户的VPC之前完全隔离,所以网段可以冲突,每个业务部门自己规划自己的网络架构,只有少数的机器需要被外网或者机房访问的时候,需要少数的机房IP,这个也是和租户映射起来的,可以分配给业务部门机房网IP的个数范围内,自由的使用。这样每个部门自主操作,迭代速度就能够加快了。
OpenStack的云平台设计模式
第一:基于PKI Token的认证模式
如果我们要实现一个Restful API,希望有个统一的认证中心的话,Keystone的三角形工作模式是常用的。
当我们要访问一个资源,通过用户名密码或者AK/SK登录之后,如果认证通过,接下来对于资源的访问,不应该总带着用户名密码,而是登录的时候形成一个Token,然后访问资源的时候带着Token,服务端通过Token去认证中心进行验证即可。
第二:基于Role Based Access Control的鉴权模式
对于权限控制,我们学会比较通用的Role Based Access Control的权限控制模式,形成“用户-角色-权限”的授权模型。在这种模型中,用户与角色之间,角色与权限之间,一般者是多对多的关系,可以非常灵活的控制权限。
第三:基于Quota的配额管理
可以通过设置计算,网络,存储的quota,设置某个租户自己可以自主操作的资源量。
第四:基于预选和优选两阶段的Scheduler机制
当需要从一个资源池里面,选择一个节点,使用这个节点上的资源的时候,一个通用的Scheduler机制是:
• 首先进行预选,也即通过Filter,将不满足条件的过滤掉。
• 然后进行优选,也即对于过滤后,满足条件的候选人,通过计算权重,选择其中最优的。
第五:基于独立虚拟子网的网络模式
为了每个租户可以独立操作,因而虚拟网络应该是独立于物理网络的,这样不同的租户可以进行独立的网络规划而互不影响,也不影响物理网络,当需要跨租户访问,或者要访问物理网络的时候,需要通过路由器。
第六:基于Copy on Write的镜像机制
有时候我们在虚拟机里面做了一些操作以后,希望能够把这个时候的镜像保存下来,好随时恢复到这个时间点,一个最最简单的方法就是完全复制一份,但是由于镜像太大了,这样效率很差。因而采取Copy on write的机制,当打镜像的时刻,并没有新的存储消耗,而是当写入新的东西的时候,将原来的数据找一个地方复制保存下来,这就是Copy on Write。
对于Openstack,有一种镜像qcow2就是采取的这样的机制。
第七:基于namespace和cgroup的隔离和Qos机制
在OpenStack里面,网络节点的路由器是由network namespace来隔离的。
KVM的占用的CPU和内存,使用Cgroup来隔离的。
网络的QoS使用TC来隔离的。
第八:基于iptables的安全机制
有时候,我们希望网络中的节点之间不能相互访问,作为最简单的防火墙,iptables起到了很重要的作用,以后实现ACL机制的,都可以考虑使用iptables。
第九:基于Mesos和Kubernetes了解容器平台
搭建完毕虚拟化层和云平台层,接下来就是容器层了
Docker有几个核心技术,一个是镜像,一个是运行时,运行时又分看起来隔离的namespace和用起来隔离的cgroup。
Docker的镜像也是一种Copy on Write的镜像格式,下面的层级是只读的,所有的写入都在最上层。
对于运行时,Docker使用的namespace除了network namespace外,还有很多,如下表格所示。
Docker对于cgroup的使用是在运行Docker的时候,在路径/sys/fs/cgroup/cpu/docker/下面控制容器运行使用的资源。
可见容器并没有使用更新的技术,而是一种新型的交付方式,也即应用的交付应该是一容器镜像的方式交付,容器一旦启动起来,就不应该进入容器做各种修改,这就是不可改变基础设施。
由于容器的镜像不包含操作系统内核,因而小的多,可以进行跨环境的迁移和弹性伸缩。
容器的正确使用场景
根据以上的分析,我们发现容器推荐使用在下面的场景下。
-
部署无状态服务,同虚拟机互补使用,实现隔离性
-
如果要部署有状态服务,需要对里面的应用十分的了解
-
作为持续集成的重要工具,可以顺利在开发,测试,生产之间迁移
-
适合部署跨云,跨Region,跨数据中心,混合云场景下的应用部署和弹性伸缩
-
以容器作为应用的交付物,保持环境一致性,树立不可变更基础设施的理念
-
运行进程基本的任务类型的程序
-
用于管理变更,变更频繁的应用使用容器镜像和版本号,轻量级方便的多
-
使用容器一定要管理好应用,进行health check和容错的设计
有了容器之后,接下来就是容器平台的选型,其实swarm, mesos, kubernetes各有优势,也可以在不同的阶段,选择使用不同的容器平台
容器平台选型的十大模式
模式一:公有云虚拟机
适合场景:初创公司,无信息安全担忧
一家初创公司,人员少,IT运维能力不足,要部署的系统很少,能够花在IT系统上的资金有限,当然应该选择公有云的虚拟机部署,它能够解决您的如下问题:
基层IT资源的管理交给公有云平台,公司自身运维人员仅需要基本的Linux能力
少量的部署系统,例如10台以下的虚拟机,往往替换一个war,重启Tomcat就能解决,如果稍微虚拟机多一点10到20台,Ansible脚本可以很好的解决这个问题
公有云按量按时收费,可以在花费很少的情况下启动,并且在业务飞速扩展的时候,迅速申请大量虚拟机
模式二:无IaaS,裸用容器
适用场景:初创公司无IaaS,有信息安全担忧
模式三:有IaaS,裸用容器
适用场景:创新项目,引入DevOps流程
有一些公司规模大一些,已经采购了IaaS,只不过有一些创新的项目需要部署,这种状态下,基本虚拟机已经能够满足需求,而且由于能够运维IaaS,IT能力比较强,一般也采用了Ansible等部署工具。
这种情况下,使用容器的动力相对比较少,然而容器也是能够带来一定好处的,就是DevOps。
创新项目迭代速度比较快,如果有比较多的创新项目,对运维的压力也是非常大的,这里的裸用容器和模式二的裸用容器不同的是,不是拿容器当做虚拟机来用,而是将容器当做交付物来用。虽然容器化对于运维的整个过程来讲改进有限,但是关键就是要开发写一个Dockerfile,这一点非常重要,意味着运行环境的配置提前到开发,而非直接交到运维,也即上面说的,开发5%的工作量增加减少大量运维工作,容器环境原子性升级回滚使得停服时间变短,可以保持开发、测试、运维环境的一致性。
模式四:使用Docker Swarm Mode
适用场景:发展中公司,中等规模集群
当集群规模超过50台时,裸用容器已经非常难受了,因为网络、存储、编排
服务发现等全部要靠自己的脚本或Ansible来搞定,是时候引入容器平台了。
当容器平台规模不是很大时,Docker Swarm Mode还是比较好用的:
集群的维护不需要Zookeeper,不需要Etcd,自己内置
命令行和Docker一样的,用起来顺手
服务发现和DNS是内置的
Docker Overlay网络是内置的
总之Docker帮你料理好了一切,你不用太关心细节,很容易就能够将集群运行起来。
模式五:使用Marathon和Mesos
使用场景:万节点集群,多定制
当集群规模大一些,几百个节点时,很多人就不愿意使用Docker Swarm Mode了,很多的选择是既没有用DC/OS,也没有用Kubernetes,而是仅仅用了Marathon和Mesos。
因为Mesos是一个非常优秀的调度器,它的双层调度机制可以使得集群规模大很多。
Mesos的调度过程如图所示:
Mesos有Framework、Master、Agent、Executor、Task几部分组成。这里面有两层的Scheduler,一层在Master里面,allocator会将资源公平的分给每一个Framework,二层在Framework里面,Framework的scheduler将资源按规则分配给Task。
模式六:使用开源Kubernetes
使用场景:千节点集群,少定制
Kubernetes模块划分得更细,模块比较多,比起裸Marathon和Mesos来讲功能丰富,而且模块之间完全的松耦合,可以非常方便地进行定制化。
而且Kubernetes的数据结构的设计层次比较细,非常符合微服务的设计思想。例如从容器->Pods->Deployment->Service,本来简单运行一个容器,被封装为这么多的层次,每次层有自己的作用,每一层都可以拆分和组合,这样带来一个很大的缺点,就是学习门槛高,为了简单运行一个容器,需要先学习一大堆的概念和编排规则。
但是当需要部署的业务越来越复杂时,场景越来越多时,你会发现Kubernetes这种细粒度设计的优雅,使得你能够根据自己的需要灵活的组合,而不会因为某个组件被封装好了,从而导致很难定制。例如对于Service来讲,除了提供内部服务之间的发现和相互访问外,还灵活设计了headless service,这使得很多游戏需要有状态的保持长连接有了很好的方式,另外访问外部服务时,例如数据库、缓存、headless service相当于一个DNS,使得配置外部服务简单很多。很多配置复杂的大型应用,更复杂的不在于服务之间的相互配置,可以有Spring Cloud或者Dubbo去解决,复杂的反而是外部服务的配置,不同的环境依赖不同的外部应用,External Name这个提供和很好的机制。
包括统一的监控cadvisor,统一的配置confgMap,都是构建一个微服务所必须的。
然而Kubernetes当前也有一个瓶颈——集群规模还不是多么大,官方说法是几千个节点,所以超大规模的集群,还是需要有很强的IT能力进行定制化,这个在模式七中会说一下我们在网易云上做的事情。但是对于中等规模的集群也足够了。
而且Kubernetes社区的热度,可以使得使用开源Kubernetes的公司能够很快地找到帮助,等待到新功能的开发和Bug的解决。
模式七:深入掌握使用Kubernetes
使用场景:万节点集群,IT能力强
模式八:深入掌握使用DC/OS
使用场景:万节点集群,IT能力强
模式九:部署大数据,Kubernetes vs. Mesos
模式十:容器和虚拟化混合部署
使用场景:大型公司,逐步容器化
对于很多大公司但是非互联网公司,使用容器还是需要小心对待的,因而需要逐步容器化,所以存在有IaaS平台,并且虚拟机和容器混合使用的状态,这种状态可能会持续相当长的时间。
在这种情况下,建议容器套在虚拟机里面使用。
使用Flannel和Calico都仅仅适用于裸机容器,而且仅仅用于容器之间的互通。
一旦有IaaS层,就会存在网络二次虚拟化的问题。
虚拟机之间的互联是需要通过一个虚拟网络的,例如vxlan的实现,而使用Flannel或者Calico相当于在虚拟机网络虚拟化的上面再做一次虚拟化,使得网络性能大幅度降低。
而且如果使用Flannel或者Calico,那容器内的应用和虚拟机上的应用相互通信时,则需要出容器平台,多使用node port,通过NAT的方式访问,或者通过外部负载均衡器的方式进行访问。在现实应用中,不可能一下子将所有的应用全部容器化,只是部分应用容器化,部分应用部署在虚拟机里面是常有的现象。然而通过NAT或者外部负载均衡器的方式,对应用的相互调用有侵入,使得应用不能像原来一样相互调用,尤其是当应用之间使用Dubbo或者SpringCloud这种服务发现机制时,尤其如此。
第十:基于Hadoop和Spark了解大数据平台
对于数据架构的部分,其实经历了三个过程,分别是Hadoop Map-Reduce 1.0,基于Yarn的Map-Reduce 2.0, 还有Spark。
Map-Reduce 1.0
Map-Reduce的过程将一个大任务,split称为多个Map Task,分散到多台机器并行处理,将处理的结果保存到本地,第二个阶段,Reduce Task将中间结果拷贝过来,将结果集中处理,取得最终结果。
在Map-Reduce 1.0的时候,跑任务的方式只有这一种,为了应对复杂的场景,将任务的调度和资源的调度分成两层。其中资源的调用由Yarn进行,Yarn不管是Map还是Reduce,只要向他请求,他就找到空闲的资源分配给他。
每个任务启动的时候,专门启动一个Application Master,管理任务的调度,他是知道Map和Reduce的。这就是Map-Reduce 2.0如下图。
这里Yarn相当于外包公司的老板,所有的员工都是worker,都是他的资源,外包公司的老板是不清楚接的每一个项目的。
Application Master相当于接的每个项目的项目经理,他是知道项目的具体情况的,他在执行项目的时候,如果需要员工干活,需要向外包公司老板申请。
Yarn是个通用的调度平台,能够跑Map-Reduce 2,就能跑Spark
Spark也是创建Spark自己的Application Master,用于调度任务。
Spark之所以比较快,是因为前期规划做的好,不是像Map-Reduce一样,每一次分配任务和聚合任务都要写一次硬盘,而是将任务分成多个阶段,将所有在一个Map都做了的合成一个阶段,这样中间不用落盘,但是到了需要合并的地方,还是需要落盘的。
第十一:基于Lucene和ElasticSearch了解搜索引擎
当大数据将收集好的数据处理完毕之后,一般会保存在两个地方,一个是正向索引,可以用Hbase,Cassandra等文档存储,一个是反向索引,方便搜索,就会保存在基于Lucene的ElasticSearch里面。
第十二:基于SpringCloud了解微服务
设计要点一:负载均衡 + API 网关
在实施微服务的过程中,不免要面临服务的聚合与拆分。
当后端服务的拆分相对比较频繁的时候,作为手机 App 来讲,往往需要一个统一的入口,将不同的请求路由到不同的服务,无论后面如何拆分与聚合,对于手机端来讲都是透明的。
有了 API 网关以后,简单的数据聚合可以在网关层完成,这样就不用在手机 App 端完成,从而手机 App 耗电量较小,用户体验较好。
有了统一的 API 网关,还可以进行统一的认证和鉴权,尽管服务之间的相互调用比较复杂,接口也会比较多。
API 网关往往只暴露必须的对外接口,并且对接口进行统一的认证和鉴权,使得内部的服务相互访问的时候,不用再进行认证和鉴权,效率会比较高。
有了统一的 API 网关,可以在这一层设定一定的策略,进行 A/B 测试,蓝绿发布,预发环境导流等等。
API 网关往往是无状态的,可以横向扩展,从而不会成为性能瓶颈。
设计要点二:无状态化与独立有状态集群
影响应用迁移和横向扩展的重要因素就是应用的状态。无状态服务,是要把这个状态往外移,将 Session 数据,文件数据,结构化数据保存在后端统一的存储中,从而应用仅仅包含商务逻辑。
状态是不可避免的,例如 ZooKeeper,DB,Cache 等,把这些所有有状态的东西收敛在一个非常集中的集群里面。
整个业务就分两部分,一个是无状态的部分,一个是有状态的部分。
无状态的部分能实现两点:
• 跨机房随意地部署,也即迁移性。
• 弹性伸缩,很容易地进行扩容。
有状态的部分,如 ZooKeeper,DB,Cache 有自己的高可用机制,要利用到它们自己高可用的机制来实现这个状态的集群。
虽说无状态化,但是当前处理的数据,还是会在内存里面的,当前的进程挂掉数据,肯定也是有一部分丢失的。
为了实现这一点,服务要有重试的机制,接口要有幂等的机制,通过服务发现机制,重新调用一次后端服务的另一个实例就可以了。
设计要点三:数据库的横向扩展
数据库是保存状态,是最重要的也是最容易出现瓶颈的。有了分布式数据库可以使数据库的性能随着节点增加线性地增加。
分布式数据库最最下面是 RDS,是主备的,通过 MySQL 的内核开发能力,我们能够实现主备切换数据零丢失。
所以数据落在这个 RDS 里面,是非常放心的,哪怕是挂了一个节点,切换完了以后,你的数据也是不会丢的。
再往上就是横向怎么承载大的吞吐量的问题,上面有一个负载均衡 NLB,用 LVS,HAProxy,Keepalived,下面接了一层 Query Server。
Query Server 是可以根据监控数据进行横向扩展的,如果出现了故障,可以随时进行替换的修复,对于业务层是没有任何感知的。
另外一个就是双机房的部署,DDB 开发了一个数据运河 NDC 的组件,可以使得不同的 DDB 之间在不同的机房里面进行同步。
这时候不但在一个数据中心里面是分布式的,在多个数据中心里面也会有一个类似双活的一个备份,高可用性有非常好的保证。
设计要点四:缓存
在高并发场景下缓存是非常重要的。要有层次的缓存,使得数据尽量靠近用户。数据越靠近用户能承载的并发量也越大,响应时间越短。
在手机客户端 App 上就应该有一层缓存,不是所有的数据都每时每刻从后端拿,而是只拿重要的,关键的,时常变化的数据。
尤其对于静态数据,可以过一段时间去取一次,而且也没必要到数据中心去取,可以通过 CDN,将数据缓存在距离客户端最近的节点上,进行就近下载。
有时候 CDN 里面没有,还是要回到数据中心去下载,称为回源,在数据中心的最外层,我们称为接入层,可以设置一层缓存,将大部分的请求拦截,从而不会对后台的数据库造成压力。
如果是动态数据,还是需要访问应用,通过应用中的商务逻辑生成,或者去数据库读取,为了减轻数据库的压力,应用可以使用本地的缓存,也可以使用分布式缓存。
如 Memcached 或者 Redis,使得大部分请求读取缓存即可,不必访问数据库。
当然动态数据还可以做一定的静态化,也即降级成静态数据,从而减少后端的压力。
设计要点五:服务拆分与服务发现
当系统扛不住,应用变化快的时候,往往要考虑将比较大的服务拆分为一系列小的服务。
这样第一个好处就是开发比较独立,当非常多的人在维护同一个代码仓库的时候,往往对代码的修改就会相互影响。
常常会出现我没改什么测试就不通过了,而且代码提交的时候,经常会出现冲突,需要进行代码合并,大大降低了开发的效率。
另一个好处就是上线独立,物流模块对接了一家新的快递公司,需要连同下单一起上线,这是非常不合理的行为。
我没改还要我重启,我没改还让我发布,我没改还要我开会,都是应该拆分的时机。
再就是高并发时段的扩容,往往只有最关键的下单和支付流程是核心,只要将关键的交易链路进行扩容即可,如果这时候附带很多其他的服务,扩容既是不经济的,也是很有风险的。
另外的容灾和降级,在大促的时候,可能需要牺牲一部分的边角功能,但是如果所有的代码耦合在一起,很难将边角的部分功能进行降级。
当然拆分完毕以后,应用之间的关系就更加复杂了,因而需要服务发现的机制,来管理应用相互的关系,实现自动的修复,自动的关联,自动的负载均衡,自动的容错切换。
设计要点六:服务编排与弹性伸缩
当服务拆分了,进程就会非常的多,因而需要服务编排来管理服务之间的依赖关系,以及将服务的部署代码化,也就是我们常说的基础设施即代码。
这样对于服务的发布,更新,回滚,扩容,缩容,都可以通过修改编排文件来实现,从而增加了可追溯性,易管理性,和自动化的能力。
既然编排文件也可以用代码仓库进行管理,就可以实现一百个服务中,更新其中五个服务,只要修改编排文件中的五个服务的配置就可以。
当编排文件提交的时候,代码仓库自动触发自动部署升级脚本,从而更新线上的环境。
当发现新的环境有问题时,当然希望将这五个服务原子性地回滚,如果没有编排文件,需要人工记录这次升级了哪五个服务。
有了编排文件,只要在代码仓库里面 Revert,就回滚到上一个版本了。所有的操作在代码仓库里都是可以看到的。
设计要点七:统一配置中心
服务拆分以后,服务的数量非常多,如果所有的配置都以配置文件的方式放在应用本地的话,非常难以管理。
可以想象当有几百上千个进程中有一个配置出现了问题,是很难将它找出来的,因而需要有统一的配置中心,来管理所有的配置,进行统一的配置下发。
在微服务中,配置往往分为以下几类:
• 一类是几乎不变的配置,这种配置可以直接打在容器镜像里面。
• 第二类是启动时就会确定的配置,这种配置往往通过环境变量,在容器启动的时候传进去。
• 第三类就是统一的配置,需要通过配置中心进行下发。例如在大促的情况下,有些功能需要降级,哪些功能可以降级,哪些功能不能降级,都可以在配置文件中统一配置。
设计要点八:统一日志中心
同样是进程数目非常多的时候,很难对成千上百个容器,一个一个登录进去查看日志,所以需要统一的日志中心来收集日志。
为了使收集到的日志容易分析,对于日志的规范,需要有一定的要求,当所有的服务都遵守统一的日志规范的时候,在日志中心就可以对一个交易流程进行统一的追溯。
例如在最后的日志搜索引擎中,搜索交易号,就能够看到在哪个过程出现了错误或者异常。
设计要点九:熔断,限流,降级
服务要有熔断,限流,降级的能力,当一个服务调用另一个服务,出现超时的时候,应及时返回,而非阻塞在那个地方,从而影响其他用户的交易,可以返回默认的托底数据。
当一个服务发现被调用的服务,因为过于繁忙,线程池满,连接池满,或者总是出错,则应该及时熔断,防止因为下一个服务的错误或繁忙,导致本服务的不正常,从而逐渐往前传导,导致整个应用的雪崩。
当发现整个系统的确负载过高的时候,可以选择降级某些功能或某些调用,保证最重要的交易流程的通过,以及最重要的资源全部用于保证最核心的流程。
还有一种手段就是限流,当既设置了熔断策略,又设置了降级策略,通过全链路的压力测试,应该能够知道整个系统的支撑能力。
因而就需要制定限流策略,保证系统在测试过的支撑能力范围内进行服务,超出支撑能力范围的,可拒绝服务。
当你下单的时候,系统弹出对话框说 “系统忙,请重试”,并不代表系统挂了,而是说明系统是正常工作的,只不过限流策略起到了作用。
设计要点十:全方位的监控
当系统非常复杂的时候,要有统一的监控,主要有两个方面,一个是是否健康,一个是性能瓶颈在哪里。
当系统出现异常的时候,监控系统可以配合告警系统,及时地发现,通知,干预,从而保障系统的顺利运行。
当压力测试的时候,往往会遭遇瓶颈,也需要有全方位的监控来找出瓶颈点,同时能够保留现场,从而可以追溯和分析,进行全方位的优化。