热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

“自主设计与实施的故障注入微服务Sidecar,欢迎大佬批评指正!”

“故障注入Sidecar“——为您的微服务注入故障以验证集群性能!由于导师和实验室师兄们的科研需要,本人专门以Sidecar的模式设计了一个用于错误注入的微服务模块。该模块可以与任

“故障注入 Sidecar“——为您的微服务注入故障以验证集群性能! 由于导师和实验室师兄们的科研需要,本人专门以 Sidecar

的模式设计了一个用于错误注入的微服务模块。该模块可以与任何微服务应用共同部署运行,为其模拟cpu、内存等错误。 本项目的 Github

地址:
https://github.com/iscas-micr…

我的联系方式: leontian1024@gmail.com || 或直接留言 欢迎您提出问题批评指点!

项目背景

目前,本人正在中科院软件所的微服务研究组从事部分研究工作。由于本人所在科研小组的研究内容( 微服务自动扩缩容相关 ),需要经常使微服务应用处于”高 CPU 利用率” 和 “高内存使用”的状态。因此,为了方便导师和实验室的各位师兄进行实验,本人特地开发了一个可以注入进 Pod 中的错误注入容器,来模拟上述的高负载状态。

导师和师兄们使用后对我的工作给予了肯定,因此我准备将开发过程和简单使用方法写成文章做个记录( 也就是本文 ),一来方便自己日后工作学习,二来也方便有类似实验需求的其他同仁们使用这个小项目,为大家的研究节省时间。更具体的安装和使用方法,可以移步本项目 Github 的代码仓库,其中有非常详细的说明。

知识储备

什么是微服务中的”Sidecar 运行模式?”

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 以 Sidecar 模式部署并运行的微服务单元

Sidecar 运行模式是最近两年比较火的一种微服务部署和运行方法,它由目前流行的 ServiceMesh(服务网格) 架构推广而来。

具体而言,Sidecar 运行模式是一种”将不属于业务应用的功能以独立的容器运行于业务容器旁边”,在 K8s 中表现出的样子就是将具有不同功能的模块封装成不同的镜像,并以不同的容器运行在同一个 Pod 中。这种说法非常形象,因为 Sidecar 这个单词的本意就是三轮摩托侧面的”跨斗”,这里形容独立于业务应用但又与业务应用部署在一起非常合适。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: Sidecar ,中文意思为摩托车的跨斗,不由赞叹命名的非常生动

主要设计思想

架构设计

本项目的错误注入模块也采用了 Sidecar 这种设计思想,将用于模拟 CPU、内存等故障的模块独立封装成一个镜像,并在 Pod 启动时以 Sidecar 的形式运行在主业务容器旁边。这样,不用它时他就会安安静静地当个美男子,完全不用担心它会影响到正常业务的运行;一旦需要它模拟错误产生,由于与业务容器同处于一个 Pod 之中(而 K8s 又以 Pod 为基本单元),因此他模拟出的错误亦被 K8s 集群视为业务应用所在 Pod 产生而被监测到。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: Pod 中的每个容器都有自己的端口映射到外部主机,因此不会相互影响

注入方式设计

本项目在设计之初是采用“在容器内修改环境变量”的方式对容器注入故障的,但事实证明这种方法太low,而且非常麻烦。因此在后续设计和实现中采用了目前较为流行的通过 REST API 传递 POST 请求的方式使容器模拟错误,这样就极大地方便了师兄们展开实验,而且也可以模拟出“微服务间调用而产生错误”的场景( 上游服务调用错误注入的 API 而模拟下游服务产生错误 )。

多进程模拟故障产生

此外,原本该项目的实现是单进程的,故每注入一个错误都要等待错误结束后才能获得应答并注入下一个错误,这十分不利于实验的进行。因此在后面我们改为了多进程运行,即每当一个错误产生时,程序都会建立一个子进程用于运行错误故障,而原来的进程则立刻产生注入是否成功的应答并继续监听相应的服务端口,从而满足应答实时汇报和多种错误同时注入的功能需求。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 该程序的主要运行流程-以 “A 进程监听服务端口”的状态为起点

使用说明( 故障注入的方法 )

启动服务

本应用以 Web 服务的方式运行,并封装为镜像保存于 DockerHub 上。因此使用之前需要先以容器的形式运行镜像。以 docker 命令运行本应用的参考命令如下所示:

# 使用 docker 命令简单测试该应用( 测试版本为 docker 18.03-ce )
docker run --rm -it -d --name fault-injection-server -p 5000:5000 xinyaotian/micro-fault-injection:1.0.0

待容器就绪后,访问您启动该容器的主机 IP 的 5000 号端口,如果出现了使用指引界面,就表明您的服务启动成功,可以参考使用说明进行错误注入了。

《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 为了方便师兄们和大家的使用, 特地在服务首页制作了简易的使用方法指引, 为大家节省查 Github 文档的时间

错误注入

本项目主要支持四种故障类型: cpu、内存、磁盘和网络,均通过 POST 请求向 /fault-inject 搭配相应参数进行注入。具体的注入方法如下所示( 注意更改 IP 和端口号 ):

1.注入 CPU 故障

# fault_type=cpu 指定错误故障类型(此处为 cpu 类型)
# thread_num=4 触发该错误的线程数(此处为 4 个线程)
# duration=15 故障持续时间,单位为秒(此处为 15 秒)
curl -X POST -d 'fault_type=cpu&thread_num=4&duration=15' http://localhost:5000/fault-inject

2. 注入内存故障

# fault_type=mem 指定错误故障类型(此处为 mem 类型)
# mem_size=120M 指定内存泄露的数值(此处为 120M ,注意 M 不能省略)
# thread_num=4 触发该错误的线程数(此处为 4 个线程)
# duration=15 故障持续时间,单位为秒(此处为 15 秒)
curl -X POST -d 'fault_type=mem&mem_size=120M&thread_num=4&duration=15' http://localhost:5000/fault-inject

3.注入磁盘故障

# fault_type=disk 指定错误故障类型(此处为 disk 类型)
# io_times=4
# duration=15 故障持续时间,单位为秒(此处为 15 秒)
curl -X POST -d 'fault_type=disk&io_times=4&duration=15' http://localhost:5000/fault-inject

4.注入网络故障

# fault_type=net 指定错误故障类型(此处为 net 类型)
# net_port=100
curl -X POST -d 'fault_type=net&net_port=100' http://localhost:5000/fault-inject
在 K8s 或 Istio 上运行( 基于 yaml )

本项目的镜像将作为原本微服务应用的 Sidecar 独立部署运行, 因此在 K8s 环境中其应该与业务应用部署于同一个 Pod 之中。

您可以利用 yaml 启动一个单独的 Pod 来初步体验一下这个应用。快读启动的 yaml 如下所示( Istio 同样可以这样写, K8s 版本为 1.13.1, Istio 版本为 1.0.6 ):

---
# 为 fault injection 创建 service 分配端口 #
---
apiVersion: v1
kind: Service
metadata:
name: single-fault-injection
namespace: default
spec:
selector:
# deployment identifier
# 这个标签要与 deployment 中相对应
app: fault-injection
ports:
- protocol: TCP
port: 5000 # 容器内端口为 5000
nodePort: 30050 # 映射至主机的 30050 端口
type: NodePort # 映射方式为 NodePort
---
# 将该模块作为一个独立的 Pod 在 K8s 上进行部署 #
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: single-fault-injection
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
# svc identifier
# 这个标签要与 service 中相对应
app: fault-injection
spec:
containers:
# 错误注入模块的 container
- name: fault-injection-container
image: xinyaotian/micro-fault-injection:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
# 该容器的资源限制, 错误注入可使其达到峰值 #
resources:
limits:
cpu: "0.4"
memory: 128Mi

如果您希望以 Sidecar 的形式将本应用部署在其他微服务的 Pod 之中同样可行,这也是本项目的设计初衷。在 K8s 环境下部署和启动的 yaml 如下所示意( Istio 同样可以这样写, K8s 版本为 1.13.1, Istio 版本为 1.0.6 ):

---
# 为 fault injection 创建 service 分配端口 #
---
apiVersion: v1
kind: Service
metadata:
name: your-microapp-with-faultinjection
namespace: default
spec:
selector:
# deployment identifier
# 这个标签要与 deployment 中相对应
app: sidecar-fault-injection
ports:
- protocol: TCP
port: 5000
nodePort: 30050
type: NodePort
---
# 相应的 deployment 配置( 与原应用配置在一起 )
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: your-microapp-with-faultinjection
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
# svc identifier
# 这个标签要与 service 中相对应
app: sidecar-fault-injection
spec:
containers:
# 你原来应用的 container 信息
- name: your-micro-app
image: your-docker-name/project:1.0
imagePullPolicy: IfNotPresent
env:
- name: PATH_VALUE
value: "example"
ports:
- containerPort: 80
# ------------------- #
# Sidecar 错误注入模块的 container
- name: fault-injection-sidecar
image: xinyaotian/micro-fault-injection:1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 5000
# ------------------- #
---

在我自己的实验集群上,利用 Istio 启动该服务,并对其注入内存故障后,可以在 Grafana 监控面板上清晰地看到微服务 Pod 的内存忽高忽低,非常有趣。 错误注入的结果如下图所示。
《“故障注入 Sidecar”——自己设计并实现的“故障注入微服务”,非常欢迎各位大佬批评指正!》

上图: 注入内存故障后, 我自己的 Istio 集群监测微服务资源面板的可视化展现

后续版本开发展望

项目到这里已经满足了实验室内师兄们绝大部分的科研需求。在之后的迭代中预计还会加入故障的产生速率( 例如 CPU 使用率会呈线性或指数上涨等 ),相应的 API 也会采用向前兼容的形式进行扩充( 添加更多的可选参数,不填则设置为默认值 ),以确保这个版本或之前版本使用者的代码无需改变而可继续使用后续版本。

此外,简单的用户控制面板也会在后续版本中开发。通过提供的用户界面,使用者可以在界面上输入参数并通过按钮进行错误注入,而不再仅仅通过发送 POST 请求( 虽然底层原理还是本地请求 )。相信用户界面会在汇报演示时为导师和师兄们带来诸多便利。

小结

本项目主要以 Sidecar 的方式开发了一个用于错误注入的实验镜像,并通过在 docker 和 k8s 上运行从而达到对微服务单元注入故障的目标,为研究集群自动扩缩容、微服务自动扩缩容等课题提供了前提保障和研究条件。

致谢

感谢您的阅读,如果您对这个项目有什么更好的建议,或指出哪里设计有问题,我都会非常欢迎,洗耳恭听。非常希望于读完本文的您进行交流,欢迎您在下方留言。

如果您的科研团队也有类似需求,也非常欢迎与我们进行合作,并对针对本项目提出宝贵的改进意见。


推荐阅读
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 本文详细介绍了如何利用go-zero框架从需求分析到最终部署至Kubernetes的全过程,特别聚焦于微服务架构中的网关设计与实现。项目采用了go-zero及其生态组件,涵盖了从API设计到RPC调用,再到生产环境下的监控与维护等多方面内容。 ... [详细]
  • Ralph的Kubernetes进阶之旅:集群架构与对象解析
    本文深入探讨了Kubernetes集群的架构和核心对象,详细介绍了Pod、Service、Volume等基本组件,以及更高层次的抽象如Deployment、StatefulSet等,帮助读者全面理解Kubernetes的工作原理。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 本文探讨了领域驱动设计(DDD)的核心概念、应用场景及其实现方式,详细介绍了其在企业级软件开发中的优势和挑战。通过对比事务脚本与领域模型,展示了DDD如何提升系统的可维护性和扩展性。 ... [详细]
  • 本文探讨了MariaDB在当前数据库市场中的地位和挑战,分析其可能面临的困境,并提出了对未来发展的几点看法。 ... [详细]
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • 本文深入探讨了Kubernetes中Pod的基础概念及其分类,旨在帮助读者更好地理解和利用这一核心组件。通过详细的解析,我们将了解Pod如何作为最小的部署单元在Kubernetes集群中工作。 ... [详细]
  • 深入解析 RuntimeClass 及多容器运行时应用
    本文旨在探讨RuntimeClass的起源、功能及其在多容器运行时环境中的实际应用。通过详细的案例分析,帮助读者理解如何在Kubernetes集群中高效管理不同类型的容器运行时。 ... [详细]
  • 探索电路与系统的起源与发展
    本文回顾了电路与系统的发展历程,从电的早期发现到现代电子器件的应用。文章不仅涵盖了基础理论和关键发明,还探讨了这一学科对计算机、人工智能及物联网等领域的深远影响。 ... [详细]
  • 深入探讨配置文件的管理与优化
    尽管配置文件的重要性不言而喻,但其管理和安全性问题却常被忽视。本文将详细讨论配置文件的不同管理策略及其优缺点。 ... [详细]
author-avatar
520文雅_293
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有