云原生技术基于容器、服务网格、微服务、不可变基础设施以及声明式 API 等构建容错性好、易于管理、便于观察的应用系统,并可轻松应对频繁变更。那如何才能构建这种云原生的应用系统呢?本文通过图示的方式带你拆解云原生应用的那些最佳设计模式。
多副本模式
多副本模式是微服务中最常用的确保服务高可用的设计模式,它为业务容器创建多个副本,并把这些副本分布到不同可用区的不同机器中,这些副本再通过负载均衡的方式提供给外部消费。通常,多副本的业务容器都是无状态的,这样外部来的请求只需分配到任意一个空闲的容器处理即可。在 Kubernetes 中,你可以利用 Deployment 和 Service 实现这个模式。当然,还可以利用 HPA 特性,根据业务容器的负载情况,自动扩展或收缩副本数量。
比如下图就是利用多副本模式为业务容器提供高可用以确保服务可以实现预期的 SLA。
注意,为了确保 SLA,仅有负载均衡是不够的,还需要负载均衡器能够及时识别并摘除故障容器,即需要健康探针动态监测每个容器的健康状态。
Sidecar 模式
Sidecar 模式是最常用的无侵入修改应用行为的设计模式,它在应用容器所属的 Pod 中增加另一个代理容器,并由代理容器接管 Pod 网络,从而进一步在网络请求中增加额外的功能特性。比如在 Service Mesh 中,Sidecar 容器就被用来实现流控、熔断、TLS 认证、网络监控和跟踪等丰富的流量管理特性。
比如,下图所示就是利用 sidecar 模式给应用容器增加了 TLS 认证功能。由于所有 TLS 认证的功能逻辑都在代理容器中控制,应用容器不需要做任何改动。
大使模式
大使模式(Ambassador)通过容器的方式为业务服务访问外部服务提供一个统一的接口,从而隐藏外部服务的复杂性。大使容器通常为外部服务提供一个简化的视图,并以 Sidecar 的方式跟业务容器部署在相同的 Pod 中。
比如,下图所示就是利用大使模式给业务容器提供访问数据库的功能。对于数据库访问的服务发现、异常处理、缓存加速等都都在代理容器中实现,而不同的业务容器都可以复用代理容器简化后的接口,而无需修改业务容器的代码。
大使模式与 Sidecar 模式的区别在于大使容器是为业务容器服务的,为业务容器简化了外部依赖的访问;而 Sidecar 模式是为业务容器提供附加的功能。它们的共同优势都是无需修改业务代码。
适配器模式
适配器模式(Adapter)为异构的应用程序提供一个标准化的接口,从而可以被外部服务统一处理。适配器通常也是以一个 Sidecar 容器的方式跟业务容器部署在一起,并为外部服务隐藏了业务容器的复杂性。
比如,很多应用在容器化以前都可能基于不同的库构建了非标准的监控接口,而在采纳了微服务之后,需要统一所有的监控到 Prometheus。下图所示就是利用适配器模式,将异构系统的监控接口统一转换为 Prometheus 度量接口,这样就可以通过统一的 Prometheus 来监控所有的业务系统。
除了监控系统之外,另一个常用的适配器模式是日志。很多业务系统在容器化之前都是把日志直接记录到文件中,摒弃通常不同级别的日志记录到不同的文件中。在容器化后,利用适配器模式,无需修改这些业务系统,就可以把这些日志文件的内容重定向到适配器容器的 stdout 和 stderr 中,进而也就可以通过统一的方式处理所有容器的日志(比如 kubectl logs 也可以用到这些系统上)。
有状态服务
有状态服务需要每个实例都一个持久化的唯一身份,并且通常每个实例会被排列到不同的位置(有序)。故而这类应用在部署时需要为每个容器分配唯一的 DNS 名字,并为每个容器设置一个序号。数据库和分布式存储通常都需要以状态服务的方式运行,以确保每个实例状态的一致性。
如下就是利用有状态服务部署 Zookeeper 的示例,每个 Zookeepr 都分配了一个唯一名字和序号,并分配不同的持久化存储。在 Kubernetes 中,这可以通过 StatefulSet + PVC 实现。
在管理有状态服务时,需要特别注意为每个实例使用持久化存储(如 Kubernetes 中的 PVC),并且实例删除时持久化存储应该保留。这样,在进行例常维护重建实例时,所有的数据都不会丢失。
Operator 模式
Operator 模式是利用 Kubernetes 定制资源(CRD)管理复杂应用及组件的设计模式。Operator 遵循 Kubernetes 设计理念,代表运维人员捕获应用组件的关键指标,并根据这些指标维护应用的运行、部署、异常处理以及故障迁移等,实现应用软件整个生命周期的自动化管理。你可以在 https://operatorhub.io/ 找到 Kubernetes 社区常用的 Operator 列表。
如下图是一个 Etcd Operator 的示例,Etcd Operator 利用 Kubernetes API 扩展 EtcdCluster
资源,并为每个 EtcdCluster
资源创建多个 Etcd Pod 组成一个集群。Etcd Operator 通常也以普通 Pod 的形式运行在同一个 Kubernetes 集群中,并动态监测 Etcd Pod 的状态。当 Etcd Pod 发生异常时,Etcd Operator 会根据异常原因进行动态修复。
服务网格
服务网格(Service Mesh)以轻量级网络代理 Sidecar 的方法保障业务服务间的安全、可靠通信,为业务应用提供了统一的网络观测和流量控制特性。服务网格将服务治理与实际业务服务解耦,避免了微服务化过程中对应用的侵入,可用来加速传统应用向微服务和云原生转型。
FaaS 模式
FaaS (Function-as-a-Service)是一种在无状态容器中运行的事件驱动型计算执行模型,它以事件驱动的 Funtion 来构建和执行业务应用,而无需维护自己的基础架构。FaaS 无需服务器进程长期在后台执行,而是通过事件驱动动态部署新的容器执行任务,任务执行成功后容器回收。FaaS 模式通常用于数据处理、Web 应用、批处理任务、IoT 服务等。
“在很多地方你可能看到有人把 FaaS 等同于 Serverless,但实际上 FaaS 只是实现 Serverless 的一种方法,Serverless 通常还涵盖更广的体系架构模式和设计实践。
”