Beautifulcode Sidecar 模式介绍

Beautifulcode 设计分布式系统之 Sidecar 模式

前言

https://www.beautifulcode.co/blog/55-what-is-sidecar-pattern

以下是内容翻译。

场景

让我们假设我们已经建立了以下基于微服务的电子商务应用程序。所有的服务都是用同一种语言编写的,比如说Ruby。

我们想把所有的日志推送给 LogParser 服务。我们可以做的是,我们可以写 log_exporter.rb 脚本,它定期运行并将日志文件的内容推送给 LogParser 服务。我们可以把这个脚本放在每个单独的服务中。

随着时间的推移,我们意识到我们需要为产品服务提供更大的吞吐量,因为它被多次调用以获得产品列表。我们将产品服务的实现从 Ruby 切换到 GoLang。现在我们有另一个 GoLang 版本的脚本 log_exporter.rb 。问题是,当我们在基于微服务的应用程序中使用更多的语言时,我们必须在该语言中维护另一个版本的导出器脚本。在未来,如果我们想对我们的脚本做任何改变,我们必须对所有语言的脚本进行修改。另一个问题是,我们在应用程序中编写导出日志的逻辑,尽管它与应用程序的逻辑无关。

我们解决这个问题的一个方法是借助于sidecar模式。

什么是 sidecar 模式?

在这种模式中,有两个容器。其中一个是应用容器,包含主要的应用逻辑。没有这个容器,应用程序就不存在。第二个容器被称为 sidecar 容器,通常情况下,应用容器不知道有这样一个容器的存在。Sidecar 容器被用来为应用层提供额外的功能。

应用容器和sidecar容器都被部署在同一个 pod 上。由于这种编排,两个容器都共享一些资源,如本地文件系统和网络。这个 sidecar 容器的生命周期是与应用容器相联系的。

使用 sidecar 模式

我们架构中的日志都在本地文件系统上。我们可以部署脚本,将这些日志导出到一个单独的容器中。这个容器可以和每个应用容器一起部署在同一个pod中,而不管应用逻辑是用哪种语言编写的。由于sidecar容器被部署在同一个pod中,它可以访问本地存储中的日志文件。

使用sidecar模式的优势

  • 应用容器的功能可以在没有紧耦合的情况下得到增强。

  • 每个容器都有单一的责任。

  • 即使 sidecar 容器出现任何故障,应用容器也不会受到影响。

  • 我们可以重复使用容器,而不管应用逻辑是用什么语言写的。

  • 因为与应用容器的距离很近,所以应该有较少的延迟。

何时使用sidecar模式

  • 当功能或服务必须在同一主机上共处时

  • 如果你希望一个服务与主应用程序共享相同的生命周期,但可以独立更新。

什么时候不使用sidecar模式

  • 如果应用容器很小,会导致不必要的复杂情况和成本。

  • 当 sidecar 和应用容器的通信之间不应该有任何延迟时。例如:当输出日志时,不应该有任何延迟。

  • 当延迟的容忍范围非常小的时候

  • 当你想独立于应用容器来扩展 sidecar 时。

实施过程中需要注意的事项

容器的参数化

让 sidecar 容器模块化和可重复使用是很重要的。例如,在我们导出日志的方案中,容器可以接受两个参数作为输入,一个是日志文件的位置,另一个是频率。这将有助于在不同的服务中重复使用该容器。

docker run -e=FREQUENCY=60 -e=LOG_PATH=/path/to/log/file

创建和维护容器的API

API接口是用来配置 sidecar 容器的,因此它们的定义很重要。

对API的任何改变都可能导致破坏性的改变或非破坏性的改变。破坏性变化的例子是将API的参数名称从 “FREQUENCY” 改为 “TIME_PERIOD”。 非破坏性变化的例子是,如果我们将接受的频率值从秒改为分钟。这种变化不会破坏任何东西,但不会导致 sidecar 像预期那样工作。

将容器的运维文档化

文档将有助于其他人理解如何使用这个 sidecar。写文档的最好地方是docker文件。

# FREQUENCY值决定了sidecar读取和上传日志的间隔时间,单位是秒
env frequency="60"
# LOG_PATH决定了sidecar读取日志文件的位置。
ENV LOG_PATH="/path/to/log/file"

示例

给传统服务添加HTTPS

在 sidecar 模式的帮助下,我们可以为一个遗留服务添加 HTTPS,由于某些原因,我们无法在新的构建过程中构建该服务。我们可以只在 localhost 上运行遗留的软件,并添加一个NGINX sidecar。这个sidecar容器可以作为一个代理来处理所有对传统服务的https请求。由于主容器和sidecar容器在同一个pod上,sidecar容器可以将请求转发给运行在localhost上的遗留服务。因此,未加密的流量只存在于内部网络中。

Git同步

我们可以实现一个 sidecar,它总是定期从主分支拉取最新的代码,我们可以配置主应用服务器来自动加载最新的变化。

连接到谷歌云SQL

我们可以通过添加Cloud SQL Proxy Docker镜像作为sidecar,从运行在Google Kubernetes Engine上的应用程序连接到Google Cloud SQL。通过这种方法,代理容器与应用程序在同一个pod中,这使得应用程序可以使用本地主机连接到代理,从而提高安全性。