云计算定义

一种能够跨网络、按需提供基础架构、服务、平台和应用的交付方式,正在快速取代原本通过硬布线连接进行资源共享的方式。 – redhat

  • 云计算解决的问题主要是物理资源上云,通过虚拟化技术来将底层资源池化,达到弹性、可控等目的。然而大多数传统应用并不是面向云环境来构建的,这里面包含了大量开发需求(开发框架、类库、后段服务等),就导致了云端的强大能力没有被完全发挥出来。因此,摒弃传统的应用技术架构,基于云的特点重新构建云原生应用,成为企业上云的下一个阶段。

特点

云计算是指在云中运行工作负载,而云是一种能够抽象、汇集和共享整个网络中的可扩展资源的 IT 环境。云计算和云本身都不属于技术的范畴。

  • 云计算是指在云中运行工作负载的功能。
  • 而云是一种环境,是运行应用的地方。
  • 技术则是指用于构建和使用云的软件和硬件

云计算为云原生提供了物理基础,做个不太精确的比喻:“云计算是电脑硬件,云原生是应用”.

云原生

概念

云原生(Cloud Native)是一种软件开发和部署的方法论,旨在充分利用云计算的优势,提供高度可扩展、可伸缩、可观测、可维护、自动化、高稳定性的应用程序。

云原生计算基金会(CNCF):云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。

  • 容器:Kubernetes 的底层计算引擎,提供容器化的计算资源。

  • 微服务:一种软件架构思想,用来构建云原生应用。服务网格:建立在 Kubernetes 之上,作为服务间通信的底座,提供强大的服务治理功能。

  • 声明式 API :一种新的软件开发模式,通过描述期望的应用状态,来使系统更加健壮。

  • 声明式 API 是指我们通过工具描述期望的应用状态,并由工具保障应用一直处在我们期望的状态。Kubernetes 的 API 设计,就是一种典型的声明式 API。例如,我们在创建 Deployment 时,在 Kubernetes YAML 文件中声明应用的副本数为2,即设置replicas: 2,Deployment Controller 就会确保应用的副本数一直为2。也就是说,如果当前副本数大于2,Deployment Controller 会删除多余的副本;如果当前副本数小于2,会创建新的副本。

  • 声明式设计是一种设计理念,同时也是一种工作模式,它使得你的系统更加健壮。分布式系统环境可能会出现各种不确定的故障,面对这些组件故障,如果使用声明式 API ,你只需要查看对应组件的 API 服务器状态,再确定需要执行的操作即可。

不可变基础设施:一种新的软件部署模式,应用实例一旦被创建,便只能重建不能更新,是现代运维的基础。

  • 不可变基础设施(Immutable Infrastructure)的构想,是由 Chad Fowler 于 2013 年提出的。具体来说就是:一个应用程序的实例,一旦被创建,就会进入只读的状态,后面如果想变更这个应用程序的实例,只能重新创建一个新的实例。通过这种模式,可以确保应用程序实例的一致性,这使得落地 DevOps 更加容易,并可以有效减少运维人员管理配置的负担。

云原生是一种构建和运行应用程序的方法

1
2
3
Cloud表示应用程序位于云中,而不是传统的数据中心;
Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,
充分利用和发挥云平台的弹性+分布式优势。

DevOps+持续交付+微服务+容器

image-20211101212245096

  • 符合云原生架构的应用程序应该是:采用开源堆栈(K8S+Docker)进行容器化,基于微服务架构提高灵活性和可维护性,借助敏捷方法、DevOps支持持续迭代和运维自动化,利用云平台设施实现弹性伸缩、动态调度、优化资源利用率。

公有云,私有云和混和云

  • 根据服务模式对云计算的分类包括:基础设施作为服务(iaas),平台作为服务(paas),软件作为服务(saas)。

根据云计算的资源归属对象,它可以分为公共云和私有云两大类。

  • 公共云(公共云)是一种向公众提供计算资源的服务。一般通过互联网使用,成本低,公共云的核心属性是共享资源服务。公共云的优点是低成本和良好的可扩展性。缺点是用户对云资源、数据安全、网络性能和匹配等问题缺乏控制。

  • 私有云是为拥有基础设施并控制如何在其上部署应用程序的单个客户而构建的。用户可以在企业数据中心防火墙或安全托管站点中部署私有云。私有云的核心属性是专有资源

  • 混合云不是一个独立的概念。它是一种混合云服务模式,通过标准化手段或专有技术将公共和私人云结合起来。简单地说,混合云是一种云服务模式,既有公共云,也有私人云。

云元生素的四要素

  • 微服务:几乎每个云原生的定义都包含微服务,跟微服务相对的是单体应用,微服务有理论基础,那就是康威定律,指导服务怎么切分,很玄乎,凡是能称为理论定律的都简单明白不了,不然就忒没b格,大概意思是组织架构决定产品形态,不知道跟马克思的生产关系影响生产力有无关系。

微服务架构的好处就是按 function 切了之后,服务解耦,内聚更强,变更更易;另一个划分服务的技巧据说是依据DDD来搞。

  • 容器化:Docker是应用最为广泛的容器引擎,在思科谷歌等公司的基础设施中大量使用,是基于LXC技术搞的,容器化为微服务提供实施保障,起到应用隔离作用,K8S是容器编排系统,用于容器管理,容器间的负载均衡,谷歌搞的,Docker和K8S都采用Go编写,都是好东西。

  • DevOps:这是个组合词,Dev+Ops,就是开发和运维合体,不像开发和产品,经常刀刃相见,实际上DevOps应该还包括测试,DevOps是一个敏捷思维,是一个沟通文化,也是组织形式,为云原生提供持续交付能力。

  • 持续交付:持续交付是不误时开发,不停机更新,小步快跑,反传统瀑布式开发模型,这要求开发版本和稳定版本并存,其实需要很多流程和工具支撑。

云原生的设计理念

云原生系统的设计理念如下:

  • 面向分布式设计(Distribution):容器、微服务、API 驱动的开发;
  • 面向配置设计(Configuration):一个镜像,多个环境配置;
  • 面向韧性设计(Resistancy):故障容忍和自愈;
  • 面向弹性设计(Elasticity):弹性扩展和对环境变化(负载)做出响应;
  • 面向交付设计(Delivery):自动拉起,缩短交付时间;
  • 面向性能设计(Performance):响应式,并发和资源高效利用;
  • 面向自动化设计(Automation):自动化的 DevOps;
  • 面向诊断性设计(Diagnosability):集群级别的日志、metric 和追踪;
  • 面向安全性设计(Security):安全端点、API Gateway、端到端加密;

以上的设计理念很多都是继承自分布式应用的设计理念。虽然有如此多的理念但是我们仍然无法辨认什么样的设施才是云原生基础设施,不过可以先用排除法,我将解释什么不是云原生基础设施。

云原生应用

整体来看,云原生应用是指生而为云的应用,应用程序从设计之初就考虑到了云的环境,可以在云上以最佳姿势运行,充分利用和发挥云平台提供的各种能力。具体来看,云原生应用具有以下三大特点:

  • 从应用生命周期管理维度来看,使用 DevOps 和 CI/CD 的方式,进行开发和交付。
  • 从应用维度来看,以微服务原则进行划分设计。
  • 从系统资源维度来看,采用 Docker + Kubernetes 的方式来部署。

对于云原生架构的部署,通常我们需要关注以下两点:

  • 容灾能力:容灾能力是指应用程序遇到故障时的恢复能力。在互联网时代,对应用的容灾能力有比较高的要求。理想情况是系统在出现故障时,能够无缝切换到另外一个可用的实例上,继续提供服务,并做到用户无感知。但在实际开发中,无缝切换在技术上比较难以实现,所以也可以退而求其次,允许系统在一定时间内不可用。通常这个时间需要控制在秒级,例如 5s。容灾能力可以通过负载均衡、健康检查来实现。
  • 扩缩容能力:扩缩容能力指的是系统能够根据需要扩缩容,可以手动扩缩容,也可以自动扩缩容。互联网时代对扩缩容能力的要求也比较高,需要实现自动扩缩容。我们可以基于一些自定义指标,例如 CPU 使用率、内存使用率等来自动扩缩容。扩容也意味着能够承载更多的请求,提高系统的吞吐量;缩容,意味着能够节省成本。扩缩容能力的实现,需要借助于负载均衡和监控告警能力。

服务网格(Service mesh)

服务网格是用于处理服务间通信的专用基础设施层。它负责通过包含现代云原生应用程序的复杂服务拓扑来可靠地传递请求。实际上,服务网格通常通过一组轻量级网络代理来实现,这些代理与应用程序代码一起部署,而不需要感知应用程序本身。 —— Willian Morgan Buoyant CEO

服务网格有如下几个特点:

  • 应用程序间通讯的中间层
  • 轻量级网络代理
  • 应用程序无感知
  • 解耦应用程序的重试/超时、监控、追踪和服务发现

目前两款流行的服务网格开源软件 LinkerdIstio 都可以直接在 kubernetes`中集成,其中 Linkerd 已经成为 CNCF 成员,Istio 在 2018年7月31日宣布 1.0。

理解服务网格

如果用一句话来解释什么是服务网格,可以将它比作是应用程序或者说微服务间的 TCP/IP,负责服务之间的网络调用、限流、熔断和监控。

对于编写应用程序来说一般无须关心 TCP/IP 这一层(比如通过 HTTP 协议的 RESTful 应用),同样使用服务网格也就无须关系服务之间的那些原来是通过应用程序或者其他框架实现的事情,比如 Spring Cloud、OSS,现在只要交给服务网格就可以了。

Phil Calçado 在他的这篇博客 Pattern: Service Mesh 中详细解释了服务网格的来龙去脉:

  1. 从最原始的主机之间直接使用网线相连
  2. 网络层的出现
  3. 集成到应用程序内部的控制流
  4. 分解到应用程序外部的控制流
  5. 应用程序的中集成服务发现和断路器
  6. 出现了专门用于服务发现和断路器的软件包/库,如 Twitter 的 FinagleFacebook 的 Proxygen,这时候还是集成在应用程序内部
  7. 出现了专门用于服务发现和断路器的开源软件,如 Netflix OSS、Airbnb 的 synapsenerve
  8. 最后作为微服务的中间层服务网格出现

服务网格的架构如下图所示:

image-20211101212200081

下面以 Istio 为例讲解服务网格如何在 Kubernetes 中工作。

  • Istio 将服务请求路由到目的地址,根据中的参数判断是到生产环境、测试环境还是 staging 环境中的服务(服务可能同时部署在这三个环境中),是路由到本地环境还是公有云环境?所有的这些路由信息可以动态配置,可以是全局配置也可以为某些服务单独配置。
  • 当 Istio 确认了目的地址后,将流量发送到相应服务发现端点,在 Kubernetes 中是 service,然后 service 会将服务转发给后端的实例。
  • Istio 根据它观测到最近请求的延迟时间,选择出所有应用程序的实例中响应最快的实例。
  • Istio 将请求发送给该实例,同时记录响应类型和延迟数据。
  • 如果该实例挂了、不响应了或者进程不工作了,Istio 将把请求发送到其他实例上重试。
  • 如果该实例持续返回 error,Istio 会将该实例从负载均衡池中移除,稍后再周期性得重试。
  • 如果请求的截止时间已过,Istio 主动失败该请求,而不是再次尝试添加负载。
  • Istio 以 metric 和分布式追踪的形式捕获上述行为的各个方面,这些追踪信息将发送到集中 metric 系统。