Sidecar 模式:无需修改代码即可扩展微服务

Sidecar 模式:无需修改代码即可扩展微服务

在现代云原生系统中,微服务的作用不仅仅是运行业务逻辑。他们必须处理日志记录、管理 SSL/TLS 证书、收集指标、实施重试机制以及协调与其他服务的安全通信。

如果我们将所有这些横切功能直接嵌入到每个应用程序的代码库中,最终会导致代码膨胀、紧密耦合和语言锁定。

这就是 Sidecar 模式 的用武之地。在本指南中,我们将使用简单的类比和 Kubernetes 配置示例来详细介绍 Sidecar 模式是什么、为什么它对于现代微服务架构至关重要,以及它是如何工作的。


现实世界的类比:摩托车边车

理解这种模式的最简单方法是想象一辆带边车的摩托车

Sidecar 模式架构图显示 Pod 内的应用程序和 Sidecar 容器

想象一下您有一辆高性能摩托车。它的设计初衷是为了出色地完成一件事:快速运送一名乘客。现在,假设您需要携带乘客行李或添加额外的座位。

您可以完全重新设计摩托车的车架、发动机和车轮,将其变成汽车。然而,这需要付出巨大的努力,破坏了自行车的简单性,并且使其难以维护。

相反,您附加一个 sidecar

边车是一个独立的、独立的单元,连接到摩托车。它共享摩托车的旅程,摩托车去往任何地方,并且紧密配合运行。然而,摩托车的核心发动机仍然没有受到影响。

在软件架构上:

  • 摩托车 是您的主要应用程序容器(运行核心业务逻辑,例如结账或用户身份验证)。
  • Sidecar 是一个单独的帮助容器(运行实用程序任务,例如 SSL 终止、监控或日志传送)。
  • 旅程是部署的生命周期(例如,Kubernetes Pod)。

问题:交叉关注点和代码膨胀

在 sidecar 出现之前,开发人员必须将辅助库直接包含在他们的应用程序代码中。例如,如果您想将日志发送到中央服务器,则可以导入日志库。如果您需要指标,则添加了指标 SDK。

这种基于库的方法带来了几个重大挑战:

  • 语言锁定:如果监控库仅用 Go 编写,则无法轻松在 Python 或 Java 微服务中使用它。您必须为堆栈中的每种语言找到或构建一个库。
  • 代码污染:业务逻辑因用于重试、服务发现、加密和日志记录的基础设施特定代码而变得混乱。
  • 复杂升级:如果在通信库中发现安全漏洞,每个微服务都必须更新其依赖项、重新编译和重新部署。
  • 资源争用:帮助程序代码与主应用程序在同一运行时进程中运行,这意味着记录器中的内存泄漏可能会导致整个核心应用程序崩溃。

解决方案:Sidecar 模式

Sidecar 模式通过将辅助任务移出主应用程序进程并将其放入紧邻应用程序运行的单独的独立进程中来解决这些问题。

在 Kubernetes 等容器化环境中,应用程序容器和 sidecar 容器在同一个 Pod 内运行。因为他们共享同一个 Pod:

  • 相同的网络命名空间:它们共享相同的 IP 地址和网络端口。他们可以通过 localhost 立即相互交谈,延迟几乎为零。
  • 共享存储卷:它们可以访问完全相同的磁盘存储,允许 sidecar 读取日志文件或加载主应用程序写入的配置文件。
  • 相同​​的生命周期:sidecar 与主应用程序一起部署、启动、停止和扩展。

Sidecar 模式的关键用例

Sidecar 的用途非常广泛。一些最常见的应用包括:

1. 服务网格代理(例如 Envoy、Linkerd)

您的应用程序不会直接向其他服务进行 HTTP 调用,而是将请求发送到其本地 sidecar 代理。 sidecar 代理处理路由、重试、负载平衡、断路和双向 TLS (mTLS) 加密,然后转发请求。应用程序仍然完全不知道这些网络的复杂性。

2.日志收集和转发(例如Fluent Bit)

您的应用程序只需将其日志语句写入标准输出或本地日志文件。 Sidecar 容器监视该文件,解析日志,并将其转发到中央分析引擎,例如 Elasticsearch 或 Datadog。

3.配置&秘密重载

sidecar 可以监视远程服务器(如 Consul 或 Vault)的配置更新或加密密钥轮换。当检测到更改时,它将新文件下载到共享卷并通知主应用程序重新加载它们,而无需重新启动。


Kubernetes 实现示例

在 Kubernetes 中设置 sidecar 非常简单。以下是一个简单的 YAML 配置,显示应用程序容器将日志写入共享卷,以及 Fluent Bit sidecar 容器读取和传送这些日志:

apiVersion: v1
kind: Pod
metadata:
  name: app-with-logging-sidecar
  labels:
    app: billing-service
spec:
  containers:
    # 1. Primary Application Container
    - name: web-app
      image: node:18-alpine
      command: ["/bin/sh", "-c"]
      args:
        - >
          while true; do
            echo "$(date) [INFO] Transaction processed successfully" >> /var/log/app/output.log;
            sleep 5;
          done
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app

    # 2. Sidecar Container (Log Shipper)
    - name: log-shipper
      image: fluent/fluent-bit:latest
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app
      # In a real setup, Fluent Bit config would read /var/log/app/output.log
      # and forward it to an external logging system.

  # Shared disk storage accessible by both containers
  volumes:
    - name: shared-logs
      emptyDir: {}

Sidecar 模式的优点和缺点

与任何设计模式一样,边车也需要权衡:

优势(专业版) 缺点(缺点)
与语言无关:sidecar 在自己的环境中运行。您可以在 Go、Java、Python 或 Ruby 应用程序旁边使用相同的 sidecar 助手。 资源开销:每个 Pod 运行多个容器会增加 CPU 和内存消耗。
解耦生命周期:基础设施团队可以更新 sidecar 的安全补丁,而无需触及应用程序代码。 复杂性增加:管理两倍数量的容器使部署配置、调试和调度变得复杂。
独立故障隔离:如果 sidecar 容器崩溃,Kubernetes 可以自动重新启动它,而无需关闭主应用程序。 轻微网络延迟:通过本地代理 sidecar 的流量路由会增加一个微小的跃点,尽管它通常可以忽略不计 (< 1ms)。

## 结论

Sidecar 模式是现代云原生架构的基本构建块。通过将横切关注点(例如网络代理、安全性、日志记录和配置管理)隔离到单独的配套流程中,它允许开发人员专注于构建业务价值。

虽然它引入了额外的资源开销,并且需要 Kubernetes 等容器编排平台进行有效管理,但更干净的代码库、语言灵活性和独立扩展的优势使其成为企业微服务不可或缺的模式。


在 Ghaznix 博客上探索更多软件开发和后端工程见解 →