第一章:云原生技术概论
云计算的演进变革
物理机时代
虚拟化技术成熟
从虚拟化技术的发展中,我们看到业务的工作负载由物理机转向虚拟机,资源有了初级的隔离,并且分配/利用更加合理。
云计算技术成熟
对于 XaaS 的一路演进,可以简单归纳为:
- 有了 IaaS(Infrastructure as a Service,基础设施即服务),客户不用关注物理机器,只需关注基础架构及应用程序。
- 有了 PaaS(Platform as a Service,平台即服务),客户不用关注基础架构,只需关注应用程序。
- 有了 FaaS(Function as a Service,功能即服务),客户只需关注功能和数据。
容器技术的兴起
Docker 创新性地提出了“镜像”(image)的概念,实现了一种新型的应用打包、分发和运行机制,开发人员能够在几秒钟内完成应用程序的部署、运行,无需再担心环境不一致的问题。
云原生出现的背景
部分软件已经变成水电煤一样的社会经济中的基础设施。
过去二十年间,云的底层基础设施和平台越来越强大,软件架构的发展也逐渐和云匹配:
- 通过不可变基础设施(镜像)解决本地和远程一致性问题;
- 通过服务网格(ServiceMesh)将非业务逻辑从应用程序中剥离;
- 通过声明式 API 描述应用程序的状态,而不用管中间的处理过程;
- 通过 DevOps 方法论以及一系列工具来提升研发/运维效率…
应用程序中的非业务逻辑不断被剥离,并下沉到云/基础设施层,代码越来越轻量。由此,工程师的开发工作回归本质(软件开发的本质是解决业务需求,各类“高深”、“复杂”的技术难题是业务需求的副产物,并不是软件开发的主题)。
云原生的定义
CNCF 云原生的定义 v1.0 版本
云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。
这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。
云原生的目标
云原生的几个关键目标:
- 可用(Available):通过各种机制来实现应用的高可用,以保证服务提供的连续性。
- 规模(Scale):要求云原生服务能够适应不同的规模(包括但不限于用户规模/部署规模/请求量),并能够在部署时动态分配资源,以便在不同的规模之间快速和平滑的伸缩。
- 敏捷(Agility):快速响应市场需求。
- 成本(Cost):充分有效的利用资源。
云原生代表技术
云原生的代表技术:容器技术、微服务、服务网格、不可变基础设施、声明式设计以及 DevOps。
容器技术
Google Cloud 对容器的定义: 容器是轻量级应用代码包,它还包含依赖项,例如编程语言运行时的特定版本和运行软件服务所需的库。
容器技术发展历程:
chroot 阶段:隔离文件系统
chroot 被认为是最早的容器技术之一,它能将进程的根目录重定向到某个新目录,复现某些特定环境,同时也将进程的文件读写权限限制在该目录内。
LXC 阶段:封装系统
至 2013 年,Linux 虚拟化技术已基本成型,通过 cgroups、namespace 以及安全防护机制,大体上解决了容器核心技术“运行环境隔离”,但此时仍需等待另一项关键技术的出现,才能迎来容器技术的全面繁荣。
Docker 阶段:封装应用
Docker 的核心创新“容器镜像(container image)”:
- 容器镜像打包了整个容器运行依赖的环境,以避免依赖运行容器的服务器的操作系统,从而实现“build once,run anywhere”。
- 容器镜像一但构建完成,就变成只读状态,成为不可变基础设施的一份子。
- 与操作系统发行版无关,核心解决的是容器进程对操作系统包含的库、工具、配置的依赖(注意,容器镜像无法解决容器进程对内核特性的特殊依赖)。
OCI 阶段:容器标准化
OCI 组织着力解决容器的构建、分发和运行标准问题,其宗旨是制定并维护 OCI Specifications(容器镜像格式和容器运行时的标准规范)。
OCI 有了三个主要的标准:
- OCI Runtime Spec(容器运行时标准):定义了运行一个容器,如何管理容器的状态和生命周期,如何使用操作系统的底层特性(namespace、cgroups、pivot_root 等)。
- OCI Image Spec(容器镜像标准):定义了镜像的格式,配置(包括应用程序的参数、依赖的元数据格式、环境信息等),简单来说就是对镜像文件格式的描述。
- OCI Distribution Spec(镜像分发标准):定义了镜像上传和下载的网络交互过程的规范。
容器编排阶段:封装集群
以 Kubernetes 为代表的容器编排框架,就是把大型软件系统运行所依赖的集群环境也进行了虚拟化,让集群得以实现跨数据中心的绿色部署,并能够根据实际情况自动扩缩。
就像用 docker run 可以启动单个程序一样,现在用 kubectl apply -f 就能部署和运行一个分布式集群应用,而无需关心是在私有云还是公有云或者具体哪家云厂商上。
云原生阶段:百花齐放
微服务
Netflix 云架构师 Adrian Cockcroft定义:微服务架构是一种面向服务的架构,由松耦合的具有有限上下文的元素组成。
Adrian Cockcroft 的观点中有两个核心概念:
- 松耦合(Loosely Coupled):意味着每个服务可以独立的更新,更新一个服务无需要求改变其他服务。
- 限界上下文(Bounded Contexts):意味着每个服务要有明确的边界性,你可以只关注自身软件的发布,而无需考虑谁在依赖你的发布版本。微服务和它的消费者严格通过 API 进行交互,不共享数据结构、数据库等。基于契约的微服务规范要求服务接口是稳定的,而且向下兼容。
微服务架构中,有一些必须解决的问题,如负载均衡、伸缩扩容、传输通讯等等,这些问题可以说只要是分布式架构的系统就无法完全避免。
Kubernetes 在基础设施层面,解决分布式系统问题的方案:
- Kubernetes 用 CoreDNS 替代 Spring Cloud 服务发现组件 Eureka。
- Kubernetes 用 Service/Load Balancer 替代 Spring Cloud 中的负载均衡组件 Ribbon。
- Kubernetes 用 ConfigMap 替代 Spring Cloud 的配置中心 Config。
- Kubernetes 用 Ingress 代替 Spring Cloud 的网关组件 Zuul。
当虚拟化的基础设施从单个服务的容器扩展至由多个容器构成的服务集群,并开始解决分布式的问题。
服务网格
服务网格(Service Mesh)的概念最早由 Buoyant 公司的创始人 William Morgan 于 2016 年提出。
服务网格的定义
服务网格(ServiceMesh)是一个基础设施层,用于处理服务间通信。云原生应用有着复杂的服务拓扑,服务网格保证请求在这些拓扑中可靠地穿梭。在实际应用当中,服务网格通常是由一系列轻量级的网络代理组成的,它们与应用程序部署在一起,但对应用程序透明。
—— by William Morgan
业内绝大部分服务网格产品通常由“数据平面”和“控制平面”两部分组成:
- 数据平面(Data plane):通常采用轻量级的网络代理(如 Envoy)作为 Sidecar,网络代理负责协调和控制服务之间的通信和流量处理,解决微服务之间服务熔断、负载均衡、安全通讯等问题。
- 控制平面(Control plane):包含多个控制组件,它们负责配置和管理 Sidecar ,并提供服务发现(Discovery)、配置管理(Configuration)、安全控制(Certificates)等功能。
不可变基础设施
可变的基础设施会导致以下问题:
- 重大故障时,难以快速重新构建服务:持续过多的手动操作并且缺乏记录,会导致很难由标准初始化的服务器来重新构建起等效的服务;
- 不一致风险:类似于程序变量因并发修改而带来的状态不一致风险。服务运行过程中,频繁的修改基础设施配置,同样会引入中间状态,导致出现无法预知的问题。
不可变基础设施思想的核心是,任何基础设施的运行实例一旦创建之后就变成只读状态。如需修改或升级,应该先修改基础设施的配置模版(例如 yaml、Dockerfile 配置),之后再使用新的运行实例替换。
声明式设计
声明式设计是指一种软件设计理念:“我们描述一个事物的目标状态,而非达成目标状态的流程”。至于目标状态如何达成,则由相应的工具在其内部实现。
和声明式设计相对的是命令式设计(又叫过程式设计),两者的区别是:
- 命令式设计:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现;
- 声明式设计:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。
DevOps
DevOps 是个很复杂的概念,几句话很难解释清楚。我们延用之前的惯例,如果要理解一个复杂的概念,就先去了解它出现的背景,以及发展的历史。
DevOps 核心本质是解决软件开发生命周期中的管理问题,我们先从一种名为“瀑布模型”的项目管理方法说起。
虽然敏捷开发提升了开发效率,但它的范围仅限于开发和测试环节,并没有覆盖到部署环节。显然,运维部门并没有收益。相反的,甚至可以说“敏捷”加重了运维的负担。运维追求的目标是稳定,频繁变更是破坏稳定的根源。
DevOps 运动始于 2007 年左右,当时技术社区对开发与运维之间分开工作的方式以及由此引发的冲突感到担忧。
DevOps 的定义
DevOps(Development 和 Operations 的合成词)是一种重视“软件开发人员(Dev)”和“IT 运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。
通过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
—— from 维基百科
DevOps 的成功实践离不开工具上的支持,这其中包括最重要的自动化 CI/CD 流水线,通过自动化的方式打通软件从构建、测试到部署发布的整个流程。还有实时监控、事件管理、配置管理、协作平台等一系列工具/系统的配合。
参考链接
- 深入高可用系统原理与设计,by thebyte.