PCon全球产品创新大会最新日程上线,查看更多 了解详情
写点什么

Rethink:为什么微服务没有 sidecar 不行?

  • 2021 年 11 月 26 日
  • 本文字数:4126 字

    阅读完需:约 14 分钟

Rethink:为什么微服务没有sidecar不行?

作者 | 蔡芳芳

采访嘉宾 | 蔡书

 

几乎是随着 Service Mesh 概念的普及,“sidecar”这个词被容器从业者提到的频率也越来越高。甚至可以说,sidecar proxy 已经是 Service Mesh 的第一技术特征。今天我们就和Flomesh团队负责人蔡书一起来聊聊为什么会出现 sidecar proxy,以及除了 proxy 还有哪些 sidecar,最后展望一下“理想化”的 sidecar 应该是什么样子。

 

Rethink 系列回顾:《Istio 之外,我们需要什么样的服务网格?》

 

InfoQ:能否先简单解释下什么叫 sidecar?

 

蔡书:Sidecar 本意是指三轮摩托旁边的那个挎斗。Kubernetes 在形成初期,就把“容器”这个模型演化成了“pod”模型。Pod 就是多个容器“编组使用”,或者简单地说,如果把一个“pod”类比成一个“虚拟机”,那么多个容器就是这个虚拟机里边的多个进程。这些进程里边,那些配合业务进程的其他进程我们一般就称为 sidecar。比如 pod 运行的是一个 Spring Boot 的进程,在这个 pod 里边我们部署了采集日志的 Filebeat 进程,部署了代理流量的 proxy 进程,那么这个采集日志和代理进程都叫做“sidecar”。

 

在 sidecar 这个说法被广泛使用之前,其实 sidecar 这种用法就已经被普遍使用了,比如上边例子说的有些容器玩家会在容器内部署采集日志的进程。但是 sidecar 这个叫法是随着 Service Mesh 出现而流行起来的。在几乎所有讨论 Serivce Mesh 的材料和文章中都会出现 sidecar 这个词,如果从自然语言分析角度看,“Service Mesh”和“sidecar”是关联度极高的两个词汇。事实上,和 Service Mesh 一起说的 sidecar,是“sidecar proxy”的一个简化说法。所以当讨论的上下文是“Service Mesh”的时候,说到“sidecar”,一般就是指“sidecar proxy”。

 

InfoQ:这么说 sidecar 其实不算是个新事物了~

 

蔡书:虽然这个词汇是最近几年随着服务网格开始在容器圈流行,但是 sidecar 模式其实早就存在,甚至可以说从操作系统进入了“多任务”以后就出现了。

 

InfoQ:能详细说说 sidecar 的历史渊源吗?

 

蔡书:这个话题非常有趣,我试着从三个方面聊下,一个是操作系统,一个是应用服务器,一个是容器时代的 pod,他们之间内在有时间上的先后顺序,逻辑上他们的模型也有共性之处。

 

这里先做一个假设,就是我的目标是运行一个“业务程序”,比如一个 SpringBoot 的 Java 程序,当启动这个 SpringBoot 程序的时候,我需要用 Java springboot.jar 之类的命令来启动这个进程。在典型的 Linux 上,通常我们会把这个命令包装到一个脚本里边,用类似 start-springboot.sh 之类的脚本来启动。事实上,在我们启动这个 Java 进程之前,就有很多进程在运行了,典型的比如说监控进程,比如 zabbix agent;还有比如日志收集的进程,比如 filebeat,等等。

 

其实除了这些大家常见的进程,还有一些大家可能未必留意的进程,也在运行了。典型的比如 crond,大家都用 crontab 做一些定时任务,crond 进程就是管理这个的。记得以前常常有用户问我们“能不能给我一个最小最干净的操作系统”,其实他指的就是在运行业务进程的时候,只有最少的其他进程在运行。这些“其他进程”,从逻辑模型看,都可以认为是业务进程的 sidecar。从功能的角度来说,我们会发现,这些 sidecar 进程可以分为几类,一类是辅助业务的,比如定时任务;一类是管理员需要的,比如日志采集、监控;一类是系统本身需要的,操作系统在启动内核后,会启动一个“超级进程”,称为 initd 进程,后来的 systemd 进程是 initd 的替代品,这个超级进程会启动一些进程用来辅助操作系统的功能,最典型的比如 kdump,用来在程序崩溃时候收集信息。概括地说,早期使用单机操作系统运行业务进程的时候,我们有三类“sidecar”,#1 是业务自身需要的,#2 是管理员需要的,#3 是操作系统需要的。

 

说完操作系统,我们再说应用服务器。千禧年之后,随着 Java 进入企业领域,也就是当时的 J2EE,应用服务器开始普及。以 Java 应用服务器来说(事实上几乎各种语言都有自己的“应用服务器”),应用服务器有自己的启动过程,在这个过程中,应用服务器会启动很多“线程”,这些线程也是辅助完成业务逻辑或者实现管理功能的,他们的本质也是 sidecar。

 

进入容器时代以后,尤其是 K8s 提出 pod 的概念,围绕业务进程的辅助进程模式更加清晰和明确,这些辅助进程就是 sidecar。同样,这些 sidecar 也还是完成着传统的三方面功能,一方面是辅助业务的;一方面是面向管理员的;一方面是面向系统的。容器环境是典型的云环境,所以这里的“面向管理员”和“面向系统”又有了新的含义和进一步的需求。

 

InfoQ:感觉当前对于 Service Mesh、微服务,甚至可以扩大到云原生,似乎都是没有 sidecar 不行?为什么 sidecar 这么重要?

 

蔡书:说“没有 sidecar 不行”不如说“sidecar 的普遍使用是客观现实,是刚需”。这种刚需的产生我觉得有这么几个因素,一个是不同角色需要不同能力的进程协助完成工作,比如业务进程、应用运维、系统运维,彼此工作的和角色的差异,导致了每个角色用自己的 sidecar 辅助进程是一种分工,也是一种清晰的工作边界。

 

另一方面,有些需求是在业务上线后出现的,那么这个时候,用一个附加的 sidecar 进程完成管理工作就很顺理成章。还有一点,进程是现代 Unix 和类 Unix 系统的基本管理单位,进程级的管理是非常成熟的技术。作为一个对比,其实上一代应用服务器,比如 JEE 应用服务器,尝试把很多辅助管理能力放到线程级,但是后来又都逐渐分离到外部进程了。所谓“一个快速、简洁的 Java 进程”。这些客观的需求,使得 sidecar 辅助进程成为一种刚需。

 

InfoQ:使用 sidecar 模式的优势是什么?

 

蔡书:就像上一个问题里说到的,sidecar 辅助进程的出现很多时候是顺理成章、水到渠成的,是一种最佳选择。简单来说,sidecar 本质就是分而治之,并且天然具有“分工”的属性,还可以用来解决很多“上线时候还没有的管理需求”,扮演了管理上的补丁角色。从 sidecar proxy 的角度看,proxy 提供一种“切片管理”的能力,这个是非常经典的设计模式。

 

InfoQ:前面回顾 sidecar 历史渊源的时候,您最后提到容器环境带来的“新的含义和进一步需求”,这个怎么理解?能不能具体说说?

 

蔡书:容器和 K8s 的普及,使得“云”距离用户更近了一步,这里,我总结了一些和 sidecar 相关的技术变化,以及“云”本身带来的一些变化。很多时候,我认为这些变化和特征也是“云原生”的特征和驱动力的一部分。

 

具体包括这么几个部分:

 

  1. 容器启动的时候,有一个 PID=1 的进程。通常而言,这个进程就是“业务进程”(实际上 pod 启动还有个 init 进程,叫做 pause)。当我们想启动 sidecar 进程的时候,目前的做法是通过 hook,在启动过程中启动 sidecar。实际上,这个时候 K8s(或者具体的说 Kubelet)其实是一个超级进程,它负责启动业务进程和 sidecar。很多时候,sidecar 和业务进程,甚至是 sidecar 之间,是有启动顺序的。但是目前在 K8s 的体系内,缺少对这种依赖的管理。如果大家熟悉 Linux 的 initd 和 systemd,会知道系统的启动过程是由一堆脚本控制的,也包含了一些优先关系。在操作系统时代,这些 sidecar 的启动是个“准标准”,也是可以通过 Shell 脚本“定制化”的。总结来说:pod 的 init 过程在标准化、定制化、扩展方面比较简单,在一个 pod 内容器多且有依赖和关联的时候,当前的机制不够灵活。所以第一个“新”需求就是 pod 内多进程的启动依赖及顺序,目前容器平台没有提供相应的机制。

  2. 容器快速被认可,背后最主要的原因是容器“轻量化”,而轻量化是“敏捷”的前提。当我们需要通过 sidecar 进程来完成某一种辅助功能的时候,我们需要这个辅助进程尽可能轻量化,否则就会有一种头重脚轻的感觉。前几天有个技术分享,提到他们业务容器的资源配置是 4C8G,然后 sidecar 资源配置是 4C4G。对这种配置,我只能感慨“有钱真好”。大多数用户还是希望 sidecar 是很轻量化的。概括地说,第二个“进阶”需求是,pod 内的 sidecar 辅助进程需要比传统主机上更轻量化。

  3. 权限。当我们在虚拟机或者物理机上部署 sidecar 这些辅助进程的时候,有时候我们需要特权,因为读写一些系统信息需要高权限。在主机(虚拟机、物理机)时代,超级用户加上业务用户的两级权限很好地满足了不同用户运行不同进程权限管理的需求。但是在容器时代,这个事情变难了。容器环境里,除了宿主机的管理(通常是特权用户)和业务进程(通常是普通用户)之外,多了这些 sidecar 辅助进程。这些 sidecar 辅助进程,有些也需要特权、更多的最好是用普通用户。相当于在容器环境和 pod 里,其实出现了 3 个等级的权限需求:宿主机的 root、容器的“root”、容器的普通用户。这层权限的出现,本质上是云的多租户导致的。目前来看,这个中间层的权限比较难处理,因为业务进程和辅助 sidecar 进程是共享 namespace 的。概括起来,第三个“新”需求是 sidecar 辅助进程通常要求一种介于宿主机 root 和业务进程之间的权限能力。

  4. 扩展性。主机上传统的 sidecar 辅助进程,一般都有自己的配置方式(配置文件格式),以及一些扩展方式,比如 zabbix 可以运行脚本等。这些传统的辅助进程进入到容器后,管理其实更难了。之前积累的很多管理工具,可以通过配置工具如 ansible 之类下发,而容器一般提供的方式是 configMap,这种配置和扩展的变化导致了严重的碎片化,而且方式改变也带来了新的困难。Sidecar 辅助进程的功能,很多是需要这种客户化和现场定制化的,这部分需要通用、简单的扩展机制和方式。因此,第四个“进阶”需求是 sidecar 辅助进程通常需要比传统主机上更简单、易用、且强大的扩展能力。

 

大概总结这么几个,其实还有一些,以后想起来再讨论。

 

InfoQ:针对上面这些问题和需求,业内现在有什么可行的解决办法吗?

 

蔡书:这是个好问题,在我看来,整个行业都发现了这些新问题——就是说,pod 里正在被塞进越来越多的 sidecar。因此整个行业也都在探索可行的解决办法。这里介绍下我们开源项目pipy的探索:我们通过 infra container 的方式为每个容器提供了 PID=1 的 sidecar,这个 pipy 进程类似 Linux 中的 initd 或者 systemd,它的作用是根据需要引入和执行其他的功能;通过 pipy repo 和 pipy js 的能力,pipy 可以提供目前我们已经识别的各种 sidecar 所需要的功能,比如服务注册/注销、服务发现、日志采集、指标采集、主动健康检查、定时任务、提供网络代理(也就是 sidecar proxy 能力)等。这是一种尝试,也欢迎大家一起来探讨。

2021 年 11 月 26 日 14:004384
用户头像
蔡芳芳 InfoQ高级编辑

发布了 660 篇内容, 共 333.5 次阅读, 收获喜欢 2250 次。

关注

评论 5 条评论

发布
用户头像
点进嘉宾团队链接,果不其然,卖产品的。也还请别用sidecar这种充满争议的概念碰瓷微服务,谢谢
2021 年 12 月 01 日 15:24
回复
这年头商业化都成原罪了?
2021 年 12 月 03 日 11:04
回复
用户头像
扯淡,混淆概念
2021 年 11 月 29 日 10:49
回复
用户头像
daemonset 可解否
2021 年 11 月 29 日 10:32
回复
用户头像
感謝芳芳分享
2021 年 11 月 26 日 16:40
回复
没有更多了
发现更多内容

Mac 常用远程连接 ubuntu 工具对比

悟空聊架构

28天写作 Mac 软件 悟空聊架构 12月日更 远程连接

创业研发团队的组织建设-软件工作流程

wood

创业 敏捷开发 28天写作

为什么不要急着告诉孩子答案?

Justin

心理学 教育 28天写作

关于元宇宙的一些认识

Lin

学习笔记 元宇宙

《我和我的家乡》观后感

圣迪

SAP 产品的 Field Extensibility

Jerry Wang

28天写作 扩展 ERP 12月日更 企业管理软件

JavaScript中的作用域和预解析

前端史塔克

JavaScript 大前端 ES6 HTML5, CSS3 12月日更

Golang Gin 框架之日志 DIY(七)

liuzhen007

28天写作 12月日更

搭建K8s容器化应用的开发调试环境

xiaoboey

Docker Kubernetes k3s Telepresence Skaffold

浅谈应用架构设计思路

陈俊

应用架构 设计指南

世界女性科技群落(二):种姓制度与数字微光下的生长录

脑极体

Android C++系列:Linux线程(一)概念

轻口味

c++ android 28天写作 12月日更

34 K8S之ServiceAccount及X509数字证书

穿过生命散发芬芳

k8s 28天写作 12月日更

JavaScript数据结构之 Array

devpoint

JavaScript ES6 array 内容合集 签约计划第二季

电子屏幕 or 风月宝鉴

mtfelix

元宇宙:虚实相生的网络世界

石云升

学习笔记 28天写作 元宇宙 12月日更

【Promise 源码学习】第十一篇 - Promise.all 的实现

Brave

源码 Promise 12月日更

3.《重学JAVA》—Hello World

杨鹏Geek

Java 25 周年 28天写作 12月日更

su 和 sudo,你用对了吗?

xcbeyond

Linux 28天写作 12月日更 sudo

渗透测试如何入门?

喀拉峻

网络安全 安全

amazing

Nydia

一个简单的例子教会您使用 javap

Jerry Wang

Java 性能调试 28天写作 12月日更 javap

实用机器学习笔记三:网页数据抓取

打工人!

机器学习 学习笔记 12月日更 实用机器学习

linux常用命令-历史命令和自动补全

青乡java

Linux

如何调用潜意识有效收集演讲素材-从右脑到左脑的切换

将军-技术演讲力教练

如何设计微服务架构

天天向上

架构实战营

手把手带你玩转 Spring

4ye

Java spring 程序员 内容合集 签约计划第二季

支付宝商户号稳定性解决方案

hackstoic

支付宝 解决方案 To B业务

Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架【值得收藏】

前端开发爱好者

typescript 大前端 Vue3 Vite2

数据一致性

卢卡多多

数据一致性 28天写作 12月日更

Python Qt GUI设计:QTableView、QListView、QListWidet、QTableWidget、QTreeWidget和QTreeWidgetltem表格和树类(提升篇—1)

不脱发的程序猿

Python qt GUI设计 Qt Company 表格和树类

Rethink:为什么微服务没有sidecar不行?-InfoQ