最近在看Kubernetes pattern这本书,讲的是关于k8s的设计模式。书写的不错,学到了不少,感兴趣的同学可以问我要电子书哈。今天就给大家分享下关于k8s sidecar的两种设计模式。
本文内容大致如下:
sidecar的应用场景
k8s Adapter模式
k8s Ambassador模式
【注意】本文需要掌握 k8s pod 知识,如果对 k8s pod 还不了解,可以参考文章:Kubernetes 批调度
首先介绍下在k8s中sidecar指的是什么,具体有什么用。
sidecar的应用场景
在介绍sidecar之前,为了便于理解,我们先说下容器的单一性原则。
我们在写代码的时候,会去抽象一些function,本着代码的单一性原则,function最好只做一件事。单一性的好处是,可以对function进行复用。相反,如果一个function要做的事情太多,就很难复用到其他地方,这样代码写起来就会变得很臃肿。
同样的,在容器的世界里,也推荐遵守单一性原则,即一个容器只做一件事情。这样的好处,是便于容器镜像的复用与模块的拆分。在设计一个系统的时候,需要我们去做模块与功能拆解,按照拆解来对应生成容器镜像,保证容器的单一性。比如说日志采集、监控上报等功能就可以单独封到一个容器内,以便其他模块进行复用。
反过来想一想,遵守了单一性原则后,最终还是需要把模块组装成一个系统。这时候,我们就需要将不同的容器放到一个 k8s pod 内,来组成一个完整的服务模块。sidecar是一种用来在k8s pod中扩展服务能力的方式,它可以在不侵入主容器的前提下,扩展主容器的能力,是一种很好的服务能力扩展手段。
我们来看个简单例子,例子来源于Kubernetes pattern这本书。
图1 sidecar的简单示例
从图中可以看出,Pod 内有两个容器:
Main container:主容器内运行着一个http服务,它会读取磁盘上需要对外服务的内容。
Sidecar container:sidecar容器内运行着一个git定时同步服务,它会定期从远端同步最新的服务内容到磁盘上。
这么做有两个好处:
职责划分清晰:负责主容器的团队,只需要考虑如何提供服务即可,不需要关心服务内容怎么进行同步。
sidecar容器可复用:git同步容器只需要关系怎么将服务内容同步到磁盘上,不需要关心内容怎么对外提供。它做好后,可以共享给其他http服务进行复用,不需要重复造轮子。
sidecar的思想核心就是:不侵入主容器的前提下,可以进行服务功能扩展。一般都是一些共性的能力,比如说:
日志代理/转发,例如 fluentd;
Service Mesh,比如 Istio,Linkerd;
代理,比如 Docker Ambassador;
探活:检查某些组件是不是正常工作;
其他辅助性的工作,比如拷贝文件,下载文件等;
在了解sidecar的时候,看到个比较有意思的事情:sidecar管理。细节可以参考:https://www.kubernetes.org.cn/6405.html。
背景是k8s不会明显区分主容器与sidecar容器,如果主容器与sidecar容器有启动顺序要求,目前没有特别优雅的方式。所以,作者就考虑做个sidecar容器管理,还可以分为presidecar和postsidecar,这样就能定义容器的启动顺序,还能做sidecar容器编排。如下图所示:
图2 sidecar编排管理(图片来源于https://www.kubernetes.org.cn/6405.html)
对于sidecar就介绍到这里,感兴趣的同学可以去多了解了解。
接下来说说k8s关于sidecar的两种设计模式。
k8s Adapter模式
第一种模式是Adapter模式,该模式主要是为了解决异构容器系统下对外标准化的问题。
定义看起来有点抽象,直接来看个示例,如下图所示:
图3 Adapter模式示例
在集群内可能存在使用不同语言实现的服务,如图中Pod A运行着Java实现的服务,Pod B运行着Python实现的服务。为了系统可用性考虑,来了个新需求,需要给服务增加监控。需要采集监控数据,并存入 Prometheus。现在考虑两个方案:
方案一,不同服务基于各自的语言实现监控数据采集与上报。
方案二,实现一个可复用的Adapter,适配不同语言服务,采集数据并上报。
一眼就可以看出,方案二更优。好处如下:
无须侵入。在不侵入主容器的情况下,不仅能够进行监控数据采集与上报,还具备一定的复用性。
统一标准。Prometheus对于监控数据上报服务有一定的规范要求,通过实现Adapter可以统一这个规范。
分工明确。团队分工上,负责各自服务的团队无需关心数据采集与上报如何实现,可以继续专注在自己的工作中。
通过示例,我们就更好理解。异构容器系统指的是容器内的服务架构不同,包括语言、框架、输入输出等。标准化是指通过Adapter容器去屏蔽异构系统中的差异性,对外提供统一标准的内容。
所以,Adapter模式主要是针对主容器对外提供的功能。通过适配的方式,标准化要提供的内容。
我们再来看看Ambassador模式。
k8s Ambassador模式
与Adapter模式不同,Ambassador模式主要是针对主容器对外的访问需求。通过Ambassador容器可以屏蔽主容器对外访问的一些复杂性问题,给主容器带来更简单的访问方式。
Ambassador模式实际上就是给主容器加个代理,我们来看个具体示例,如下图所示:
图4 Ambassador模式示例
从图中可以看出,Ambassador容器是用来解决主容器对外访问问题的。一开始架构选型可能使用了Memcached作为缓存系统,但后来需求调整要换成Redis来作为缓存系统。
如果没有Ambassador容器,那主容器就需要去实现对接不同缓存系统的能力。假如之后还换其他的缓存系统,那对主容器的侵入性就太大了。相反,如果把对接的工作放到Ambassador容器中,那主容器就不需要关心到底对接什么缓存系统,只要对接Ambassador容器即可,剩下的就交给Ambassador容器了。
同样,把这部分工作拆分出来放到Ambassador容器,还便于复用。系统内要使用缓存的肯定不止一个服务,一旦Ambassador容器做好了,就可以直接被其他服务所复用。
所以,Ambassador模式是针对主容器对外访问的问题。
总结
本文主要给大家介绍了k8s sidecar的应用场景,以及两种关于sidecar的设计模式:Adapter模式与Ambassador模式。需要记住的是Adapter主内,管别人怎么访问自己。而Ambassador主外,管怎么访问别人。
分享内容大概这么多,写写技术文章感觉也挺好的。不仅可以加深自己对一些知识的理解,还能分享给大家,就是耗费的时间比较多。所以,分享技术文章频率估计没那么快。一起加油吧,各位。
相关文章:如何预防 k8s 容器内的僵尸进程
上一篇文章: