分布式系统设计1-单节点模式之sidecar
作者:互联网
本系列文章是大魏的读书笔记。但笔者在记笔记的时候,对原有内容进行了精简并加入了自己的一些认识,因此本系列文章与原文已经有不少不同之处。想阅读原文的朋友,直接在网上可以收到这本pdf书。
在本系列文章中,会经常出现一个词:design pattern。根据维基百科的定义:“在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是由埃里希·伽玛(Erich Gamma)等人在1990年代从建筑设计领域引入到计算机科学的。
设计模式并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案。面向对象设计模式通常以类别或对象来描述其中的关系和相互作用,但不涉及用来完成应用程序的特定类别或对象。设计模式能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免会引起麻烦的紧耦合,以增强软件设计面对并适应变化的能力。”
也就是说,设计模式(design pattern)是一种框架。那么,针对现在很火的分布式架构,它的设计模式都包含哪些呢?
以容器为主要实现技术的分布式系统,其设计模式(design pattern)主要有以下三大类:
Single-Node Patterns,其中包括的内容有(实现方式和相关技术点):Sidecar Pattern、Ambassadors、Adapters
Serving Patterns,其中包括的内容有(实现方式和相关技术点):Replicated Load-Balanced Services、Sharded Services、Scatter/Gather、Functions and Event-Driven Processing、Ownership Election、
Batch Computational Patterns,其中包括的内容有(实现方式和相关技术点):Work Queue Systems、Event-Driven Batch Processing、Coordinated Batch Processing。
本系列文章思维导图如下:
Single-Node Patterns
为啥分布式系统设计模式还有Single-Node Patterns?因为无论你的分布式业务系统多松耦合,都会有一个自小原子单元。容器化时代,就是一个容器。在K8S中,就是一个pod。因此Single-Node Patterns是研究以容器为基础的、分分布式设计模式最小源自单元的架构。
通常,容器的目标是围绕特定资源建立边界(例如,此应用程序需要两个内核和8 GB的内存)。同样,边界描述了团队的所有权(例如,该团队拥有此image)。最后,边界旨在提供关注点分离(例如,此image完成了某一件事)。
所有这些原因为将单个计算机上的应用程序拆分为一组容器提供了动力。
首先考虑资源隔离。您的应用程序可能由两个组件组成:一个是面向用户的应用程序服务器,另一个是后台配置文件加载器。显然,面向最终用户的请求延迟是最高优先级,因此面向用户的应用程序需要具有足够的资源以确保其具有高响应能力。
另一方面,后台配置加载程序主要是尽力而为服务。如果在高用户请求量期间稍有延迟,则系统可以正常运行。同样,后台配置加载程序不应影响最终用户获得的服务质量。
出于所有这些原因,您希望将面向用户的服务和后台分片加载器分离到不同的容器中。这使您可以将不同的资源要求和优先级附加到两个不同的容器。两个容器的单独资源要求确保如果存在由于内存泄漏或内存资源的其他过量使用引起的资源争用问题,则后台加载程序将在面向用户的服务之前终止。
Single-Node Patterns又包含三种具体实现:Sidecar Pattern、Ambassadors、Adapters。我们接下来先看Sidecar Pattern。
我们先看Sidecar Pattern。提到sidecar,我们可能最容易想到Istio。istio就是sidecar的一种实现,pod中的主容器旁边塞了一个istio的代理。
边车模式是由两个容器组成的单节点模式。第一个是应用程序容器,它包含应用程序的核心逻辑。没有这个容器,该应用程序将不存在。除了应用程序容器外,还有一个边车容器。辅助工具的作用通常是在应用容器不了解的情况下扩展和改进应用容器。
Sidecar容器通过原子容器组(例如Kubernetes中的pod API对象)被共同调度到同一台机器上。除了在同一台机器上进行调度之外,应用程序容器和sidecar容器还共享许多资源,包括文件系统,主机名和网络的一部分以及许多其他namespaces,如下图所示:
那么,除了Istio之外,其他的sidecar应用示例都有什么?
例子:将HTTPS添加到旧版服务Web服务
几年前,内部网络安全性在公司构建时并不那么重要,因此,该应用程序仅通过未加密的HTTP(而不是HTTPS)为请求提供服务。由于最近发生的安全事件,该公司已强制要求所有公司网站都使用HTTPS。为了使发送更新此特定Web服务的团队所承受的痛苦加重,此应用程序的源代码是使用公司内部版本的旧版本构建的系统,它不再起作用。对该HTTP应用程序进行容器化非常简单:二进制文件可以在具有旧版Linux发行版的容器中运行,而该版本具有由团队的容器协调器运行的更现代的内核。但是,向此应用程序添加HTTPS的任务更具挑战性。
当团队中的一位成员建议他们使用Sidecar模式来更轻松地解决这种情况时,团队试图在恢复旧的构建系统与将应用程序的源代码移植到新的构建系统之间做出决定。
边车模式在这种情况下的应用很简单。旧版Web服务被配置为仅在localhost(127.0.0.1)上提供服务,这意味着只有与服务器共享本地网络的服务才能访问该服务。然后,我们添加一个nginx sidecar容器。此nginx容器与旧版Web应用程序位于同一网络pod,因此它可以访问在localhost上运行的服务。同时,此Nginx服务可以终止Pod的外部IP地址上的HTTPS流量,并将该流量代理到旧版Web应用程序,如下图所示。由于未加密的流量仅通过容器组内的本地环回适配器发送,因此网络安全团队对数据的安全性感到满意。同样,通过使用sidecar模式,该团队无需考虑如何重建新的旧应用程序就可以对其进行现代化来服务HTTPS。
Sidecar的动态配置
在实际的应用中,引流并不是Sidecar的唯一用途。
另一个常见的示例是配置同步。许多应用程序都使用配置文件对应用程序进行参数设置。这可能是原始文本文件,也可能是诸如XML,JSON或YAML之类的更结构化的文件。编写了许多先前存在的应用程序,以假定该文件存在于文件系统中并从那里读取其配置。但是,在云原生环境中,通常使用API更新配置。这样,您就可以通过API来动态推送配置信息,而不必手动登录到每台服务器并使用命令式命令来更新配置文件。这使得配置(和重新配置)更加安全,容易。
旧版应用程序启动时,将按预期从文件系统加载其配置。当配置管理器启动时,它会检查配置API并查找本地文件系统与该API中存储的配置之间的差异。如果存在差异,则配置管理器会将新配置下载到本地文件系统,并向旧版应用程序发出信号,通知它应该使用此新配置重新配置自身。此通知的实际机制因应用程序而异。一些应用程序实际上会监视配置文件进行更改,而其他响应SIGHUP信号。在极端情况下,配置管理器可能会发送SIGKILL信号来中止旧版应用程序。一旦中止,容器编排系统将重新启动旧版应用程序,此时它将加载其新配置。与向现有应用程序添加HTTPS一样,该模式说明了sidecar模式如何帮助使现有应用程序适应更多云原生场景。
模块化应用容器 Modular Application Containers
Sidecar模式存在的的很重要一个原因是: 不再希望对原始源代码进行修改的旧版应用程序,但还有许多其他动机使用边车来设计事物。使用Sidecar模式的另一个主要优点之一是模块化和可重复使用。
在部署任何现实的,可靠的应用程序时,都需要调试或对应用程序进行其他管理所需的功能,例如使用容器中的资源来读取所有不同的进程,要求每个开发人员都实现一个HTTP / topz接口,该接口提供对资源使用情况的读取。我们可以将topz功能部署为sidecar容器。这个topz容器可以检查所有正在运行的进程并提供一致的用户界面。此外,您可以使用业务流程系统将该容器自动添加到通过业务流程系统部署的所有应用程序中,以确保有一套一致的工具
适用于基础架构中运行的所有应用程序。
[root@bastion ~]# docker run -d quay.ocp.ats.com/rhscl/redis-32-rhel7
d79dc5492f28e63d6c3acc50d00e715a2fc9a7a023d6fc448d34cec66559e155
[root@bastion ~]# docker run --pid=container:d79dc5492f28e63d6c3acc50d00e715a2fc9a7a023d6fc448d34cec66559e155 -p 9090:8080 brendanburns/topz:db0fa58 /server --addr=0.0.0.0:8080
Serving on 0.0.0.0:8080
[root@bastion ~]# curl http://localhost:9090/topz
1 0 0.0077974726 /opt/rh/rh-redis32/root/usr/bin/redis-server *:6379
19 0 0.008065931 /server --addr=0.0.0.0:8080
[root@bastion ~]# curl http://localhost:9090/
404 page not found
在上面的cli中,我们通过:curl http://localhost:8080/topz以获得容器中正在运行的进程,而不加topz,会有404报错。
使用Sidecar构建简单的PaaS
边车模式不仅可以用于自适应和监视。它也可以用作简化您的应用程序实现完整逻辑的一种方式,模块化的方式。例如,假设构建一个简单的平台即服务
(PaaS)围绕git工作流程构建。部署此PaaS后,只需推动直到Git存储库的新代码都会导致该代码被部署到正在运行的代码中服务器。我们将看到sidecar模式如何显着构建此PaaS直截了当。
如前所述,在sidecar模式中有两个容器:main应用程序和sidecar。在我们简单的PaaS应用程序中,主容器是实现Web服务器的Node.js服务器。已检测Node.js服务器,以便在更新新文件时自动重新加载服务器。完成了使用nodemon工具。
Sidecar容器与主应用程序容器共享一个文件系统,并且运行一个简单的循环,该循环将文件系统与现有的Git存储库同步:
#!/bin/bash
while true; do
git pull
sleep 10
done
显然,此脚本可能更复杂,而是从特定分支中提取仅来自HEAD。故意使它简单以提高其可读性例子。
Node.js应用程序和Git同步工具是共同安排的,一起部署以实现我们的简单PaaS,如下图。一旦部署,每个当新代码被推送到Git存储库时,代码会自动更新并由服务器重新加载。
实际上,上图所展示的功能,OpenShift的S2I已经实现的非常好了。并且S2I的功能范畴比上图所展现的大得多。
标签:容器,应用程序,sidecar,分布式系统,设计模式,节点,Sidecar,旧版 来源: https://blog.51cto.com/u_15127570/2708395