NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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:005134
用户头像
蔡芳芳 InfoQ主编

发布了 781 篇内容, 共 495.9 次阅读, 收获喜欢 2748 次。

关注

评论 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
回复
没有更多了
发现更多内容

【函数式编程实战】(六) Stream高并发实战

小明Java问道之路

Java stream 高并发 7月月更 签约计划第三季

vue2升级vue3:Vue Demij打通vue2与vue3壁垒,构建通用组件

zhoulujun

Vue3 vue2 demij vue2有vue3兼容

算法题每日一练---第10天:时间显示

知心宝贝

算法 前端 后端 7月月更

STM32+MFRC522完成IC卡号读取、密码修改、数据读写

DS小龙哥

7月月更

语音聊天app源码——钠斯直播系统源码

开源直播系统源码

直播系统源码 语音聊天系统 语音聊天软件 一对一语音聊天系统

vue2升级vue3:单文件组件概述 及 defineExpos/expose

zhoulujun

Vue3 expose

模块二作业

薛敏

java零基础入门-异常、线程(上)

喵手

Java 7月月更

2B和2C

白粥

面试突击68:为什么 TCP 需要 3 次握手?

王磊

Java 面试题 网络

入门前端 -- CSS

bo

CSS 前端 7月月更

vue2升级vue3: h、createVNode、render、createApp使用

zhoulujun

Vue3

vue2升级vue3:provide与inject 使用注意事项

zhoulujun

Vue3 provide inject

第二届中国Rust开发者大会来啦,完整议程大曝光!

Mike Tang

rust rust conf

LeetCode-67. 二进制求和(java)

bug菌

Leet Code 7月月更

C#入门系列(三十一) -- 运算符重载

陈言必行

7月月更

服务器内存故障预测居然可以这样做!

vivo互联网技术

运维 内存监控 EDAC 内存预测

vue2升级vue3:composition api中监听路由参数改变

zhoulujun

Vue3 路由参数 参数监听 路由跳转

vue2升级vue3:Vue Router报错,directly inside <transition> or <keep-a

zhoulujun

Vue3 router JSX tsx

C# Serialport的发送和接收

IC00

C# 7月月更

一种分布式深度学习编程新范式:Global Tensor

OneFlow

深度学习 编程 分布式

万字详解“用知识图谱驱动企业业绩增长”

博文视点Broadview

vue2升级vue3:vue3 hooks库选用

zhoulujun

Vue3 Hooks vueuse ahooks

如何使用Docker内的kafka服务

程序员欣宸

Java kafka 7月月更

为啥谷歌的内部工具不适合你?

laofo

DevOps cicd 研发效能 工具链 谷歌

如何写一篇百万阅读量的文章

六月的雨在InfoQ

内容 个人提升 写作技巧

Prometheus 运维工具 Promtool (二)Query 功能

耳东@Erdong

Prometheus 7月月更 Promtool

vue2升级vue3:vue3创建全局属性和方法

zhoulujun

Vue3 全局变量 全局方法

前端食堂技术周刊第 45 期:Vite3.0、第91次TC39会议、Figma背后的CSS、B 站事故复盘、图片优化工具

童欧巴

前端 deno vite TC39 figma

Qt | 关于如何使用事件过滤器 eventFilter

YOLO.

qt 7月月更

Kubernetes网络插件详解 - Calico篇 - 概述

巨子嘉

Rethink:为什么微服务没有sidecar不行?_开源_蔡芳芳_InfoQ精选文章