云计算技术发展
云原生的定义
CNCF
全称Cloud Native Computing Foundation(云原生计算基金会)
2015年7月21日Google主导成立了云原生计算基金会,其最初的口号是坚持和整合开源技术来让编排容器作为微服务架构的一部分,致力于云原生应用推广和普及。
CNCF作为一个厂商中立的基金会,致力于Github上的快速成长的开源技术的推广,如Kubernetes、Prometheus、Envoy等,帮助开发人员更快更好的构建出色的产品。
CNCF对云原生的定义
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。
云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。
云原生应用的三大特征
- 容器化包装:软件应用的进程应该包装在容器中独立运行。
- 动态管理:通过集中式的编排调度系统来动态的管理和调度。
- 微服务化:明确服务间的依赖,互相解耦。
云原生概念思维导图
云原生的设计理念
- 面向分布式设计(Distribution):容器、微服务、API 驱动的开发。
- 面向配置设计(Configuration):一个镜像,多个环境配置。
- 面向韧性设计(Resistancy):故障容忍和自愈。
- 面向弹性设计(Elasticity):弹性扩展和对环境变化(负载)做出响应。
- 面向交付设计(Delivery):自动拉起,缩短交付时间。
- 面向性能设计(Performance):响应式,并发和资源高效利用。
- 面向自动化设计(Automation):自动化的 DevOps。
- 面向诊断性设计(Diagnosability):集群级别的日志、metric 和追踪。
- 面向安全性设计(Security):安全端点、API Gateway、端到端加密。
以上的设计理念很多都是继承自分布式应用的设计理念。
云原生生态体系
容器化
由于KVM( for Kernel-based Virtual Machine )hypervisor虚拟化技术仍然存在⼀些性能和资源使⽤效率⽅⾯的问题,因此出现了⼀种称为容器技术(Container)的新型虚拟化技术来帮助解决这些问题。
虚拟化技术可以在宿主机上安装多个不同的操作系统,运⾏多套不同的应⽤。但可能就是为了运⾏⼀个微应用,却还要在虚拟机⾥运⾏⼀个完整的操作系统,内核和其它⽆关程序,这种做法资源利⽤不⾼。
所以我们希望更多的关注应⽤程序本身,⽽不再分精⼒去关注操作系统与⽆关程序,操作系统内核直接与宿主机共享。
Docker 容器
Docker容器本质上是宿主机的进程. 可以把docker容器内部跑的进程看作是宿主机的线程。
Docker通过namespace实现了资源隔离,通过cgroups实现了资源限制。
Linux内核实现namespace的⼀个主要⽬的就是实现轻量级虚拟化(容器)服务。在同⼀个namespace下
的进程可以感知彼此的变化,⽽对外界的进程⼀⽆所知。
Linux容器技术是⼀种轻量级的虚拟化技术。主要特点有:
- 轻量:只打包了需要的bins/libs(也就是命令和库⽂件)。与宿主机共享操作系统,直接使⽤宿主机的内核。
- 部署快: 容器的镜像相对虚拟机的镜像⼩。部署速度⾮常快,秒级部署。
- 移植性好: Build once,Run anywhere (⼀次构建,随处部署运⾏)。
- 资源利⽤率更⾼: 相对于虚拟机,不需要安装操作系统,所以⼏乎没有额外的CPU,内存消耗。
虚拟化与容器化对比
虚拟化(VM)Docker容器操作系统宿主机OS上运行虚拟机OS与宿主机共享OS存储大小镜像庞大(vmdk、vdi等)镜像小,便于存储于传输运行性能操作系统额外的CPU、内存开销几乎无额外的性能损失移植性笨重,与虚拟化耦合度高轻便、灵活、适应于linux硬件亲和性面向硬件开发者面向软件开发者部署速度较慢、10秒级别快速、秒级
容器的编排与调度
Kubernetes(k8s)是Google基于Borg开源的容器编排调度引擎,作为CNCF(Cloud Native Computing Foundation)最重要的组件之一,它的目标不仅仅是一个编排系统,而是提供一个规范,可以让你来描述集群的架构,定义服务的最终状态,Kubernetes可以帮你将系统自动得达到和维持在这个状态。
Kubernetes用户可以通过编写一个yaml或者json格式的配置文件,也可以通过工具/代码生成或直接请求Kubernetes API创建应用,该配置文件中包含了用户想要应用程序保持的状态,不论整个Kubernetes集群中的个别主机发生什么问题,都不会影响应用程序的状态,你还可以通过改变该配置文件或请求Kubernetes API来改变应用程序的状态。
Kubernetes 架构图:
其他容器编排与调度技术方案:
Swarm、Mesos
微服务
微服务是一种分布式架构设计理念,为了推动细粒度服务的使用,这些服务要能协同工作,每个服务都有自己的生命周期。一个微服务就是一个独立的实体,可以独立的部署在PAAS平台上,也可以作为一个独立的进程在主机中运行。服务之间通过API访问,修改一个服务不会影响其它服务。
微服务带给我们很多开发和部署上的灵活性和技术多样性,但是也增加了服务调用的开销、分布式系统管理、调试与服务治理方面的难题。
Spring框架
当前最成熟最完整的微服务框架Spring,而Spring又仅限于Java语言开发,其架构本身又跟Kubernetes存在很多重合的部分,如何探索将Kubernetes作为微服务架构平台就成为一个热点话题。就拿微服务中最基础的服务注册发现功能来说,其方式分为客户端服务发现和服务端服务发现两种,Java应用中常用的方式是使用Eureka和Ribbon做服务注册发现和负载均衡,这属于客户端服务发现,而在Kubernetes中则可以使用DNS、Service和Ingress来实现,不需要修改应用代码,直接从网络层面来实现。
服务网格
Kubernetes中的应用将作为微服务运行,但是Kubernetes本身并没有给出微服务治理的解决方案,比如服务的限流、熔断、良好的灰度发布支持等。
Service Mesh可以用来做什么
- Traffic Management:API网关
- Observability:服务调用和性能分析
- Policy Enforcment:控制服务访问策略
- Service Identity and Security:安全保护
Service Mesh的特点
- 专用的基础设施层
- 轻量级高性能网络代理
- 提供安全的、快速的、可靠地服务间通讯
- 扩展kubernetes的应用负载均衡机制,实现灰度发布
- 完全解耦于应用,应用可以无感知,加速应用的微服务和云原生转型
当前开源的Service Mesh有哪些?
使用Service Mesh将可以有效的治理Kubernetes中运行的服务:
- Linkderd:https://linkerd.io,由最早提出Service Mesh的公司Buoyant开源,创始人来自Twitter
- Envoy:https://www.envoyproxy.io/,Lyft开源的,可以在Istio中使用Sidecar模式运行
- Istio:https://istio.io,由Google、IBM、Lyft联合开发并开源
- Conduit:https://conduit.io,同样由Buoyant开源的轻量级的基于Kubernetes的Service Mesh
此外还有很多其它的Service Mesh鱼贯而出,请参考awesome-cloud-native。
DEVOPS
持续集成
Continuous integration,简称CI
是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。
持续集成的目的不是减少build失败的次数,⽽是尽早发现问题,在最短的时间内解决问题,减少风险和浪费。从而让产品开发流程更加敏捷,缩短产品开发周期,在产品上线后,让用户用得更加顺畅。
在没有应用持续集成之前,传统的开发模式是项目一开始就划分模块,每个开发人员分别负责一个模块,等所有的代码都开发完成之后再集成到一起提交给测试⼈人员,随着软件技术团队的发展,软件已经不能简单地通过划分模块的方式来开发,需要项目内部相互协作,划分模块这种传统的模式的弊端也越来越明显。由于很多bug在项目早期的设计、编码阶段就引入,到最后集成测试时才发现问题,开发人员需要花费⼤量的时间来定位bug,加上软件的复杂性,bug的定位就更难了,甚⾄出现不得不调整底层架构的情况。这种情况的发生不仅对测试进度造成影响,⽽且会拖长整个项⽬周期。
而持续集成可以有效解决软件开发过程中的许多问题,在集成测试阶段之前就帮助开发人员发现问题,从而可以有效的确保软件质量,减小项目的风险,使软件开发团队从容的面对各种变化。持续集成报告中可以体现目前项目进度,哪部分需要已经实现,哪些代码已经通过自动化测试,代码质量如何,让开发团队和项目组了解项目的真实状况。
持续交付
Continuous Delivery,简称CD
持续交付是指软件开发过程,从原始需求到最终产品开发过程中,较短周期内以需求的小颗粒度(小批量)频繁提交的过程。
目的
- 开发过程的快速迭代,小步快跑,及时纠正偏离主线
- 小颗粒度实现,避免颗粒度大,出现问题解决麻烦
- 迅速反馈软件功能,避免⽅向性错误
- 团队角色(含客户)协作密切,减少时间浪费
持续部署
Continuous Deployment,简称CD
基于持续交付的基础上,把功能稳定,符合产品需求的版本有方法地部署至生产环境中。
持续发布
Continuous Release,简称CR
发布是周期性或不定期地对项目在部署后,进行整体软件版本的更新,例如,更新功能或展示页面框架等。
目的
- 产品快速迭代,小步快跑
- 适应市场变化
- 匹配市场策略
- 应对市场风险
持续测试
Continuous Testing,简称CT
持续测试是贯穿着整个软件开发过程,验证程序员提交代码,检验合规性及降低bug,减少最终错误,实现敏捷及精益开发。
目的
- 为了降低开发、部署、发布等可能出现的错误
- 防止代码出错
- 防止功能出错
- 防止业务逻辑出错等
Jenkins
Jenkins是一款由Java编写的开源的持续集成工具。
Jenkins提供了软件开发的持续集成服务。它运行在Servlet容器中。它支持软件配置管理(SCM)工具(包括AccuRev SCM、CVS、Subversion、Git、Perforce、Clearcase和RTC),可以执行基于Apache Ant和Apache Maven的项目,以及任意的Shell脚本和Windows批处理命令。
使用Jenkins进行持续集成与发布流程图:
应用构建和发布流程说明:
- 用户向Gitlab提交代码,代码中必须包含Dockerfile。
- 将代码提交到远程仓库。
- 用户在发布应用时需要填写git仓库地址和分支、服务类型、服务名称、资源数量、实例个数,确定后触发Jenkins自动构建。
- Jenkins的CI流水线自动编译代码并打包成Docker镜像推送到Harbor镜像仓库。
- Jenkins的CI流水线中包括了自定义脚本,根据我们已准备好的Kubernetes的YAML模板,将其中的变量替换成用户输入的选项。
- 生成应用的Kubernetes YAML配置文件。
- 更新Ingress的配置,根据新部署的应用的名称,在Ingress的配置文件中增加一条路由信息。
- 更新PowerDNS,向其中插入一条DNS记录,IP地址是边缘节点的IP地址。
- Jenkins调用Kubernetes的API,部署应用。