资讯专栏INFORMATION COLUMN

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

X1nFLY / 3323人阅读

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

</>复制代码

  1. “故障注入 Sidecar“——为您的微服务注入故障以验证集群性能! 由于导师和实验室师兄们的科研需要,本人专门以 Sidecar
    的模式设计了一个用于错误注入的微服务模块。该模块可以与任何微服务应用共同部署运行,为其模拟cpu、内存等错误。 本项目的 Github
    地址: https://github.com/iscas-micr...
    我的联系方式: leontian1024@gmail.com || 或直接留言 欢迎您提出问题批评指点!
项目背景

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

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

知识储备

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

</>复制代码

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

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

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

</>复制代码

  1. 上图: Sidecar ,中文意思为摩托车的跨斗,不由赞叹命名的非常生动
主要设计思想 架构设计

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

</>复制代码

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

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

多进程模拟故障产生

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

</>复制代码

  1. 上图: 该程序的主要运行流程-以 “A 进程监听服务端口”的状态为起点
使用说明( 故障注入的方法 ) 启动服务

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

</>复制代码

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

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

</>复制代码

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

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

1.注入 CPU 故障

</>复制代码

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

2. 注入内存故障

</>复制代码

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

3.注入磁盘故障

</>复制代码

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

4.注入网络故障

</>复制代码

  1. # fault_type=net 指定错误故障类型(此处为 net 类型)
  2. # net_port=100
  3. 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 ):

</>复制代码

  1. ---
  2. # 为 fault injection 创建 service 分配端口 #
  3. ---
  4. apiVersion: v1
  5. kind: Service
  6. metadata:
  7. name: single-fault-injection
  8. namespace: default
  9. spec:
  10. selector:
  11. # deployment identifier
  12. # 这个标签要与 deployment 中相对应
  13. app: fault-injection
  14. ports:
  15. - protocol: TCP
  16. port: 5000 # 容器内端口为 5000
  17. nodePort: 30050 # 映射至主机的 30050 端口
  18. type: NodePort # 映射方式为 NodePort
  19. ---
  20. # 将该模块作为一个独立的 Pod 在 K8s 上进行部署 #
  21. ---
  22. apiVersion: extensions/v1beta1
  23. kind: Deployment
  24. metadata:
  25. name: single-fault-injection
  26. namespace: default
  27. spec:
  28. replicas: 1
  29. template:
  30. metadata:
  31. labels:
  32. # svc identifier
  33. # 这个标签要与 service 中相对应
  34. app: fault-injection
  35. spec:
  36. containers:
  37. # 错误注入模块的 container
  38. - name: fault-injection-container
  39. image: xinyaotian/micro-fault-injection:1.0.0
  40. imagePullPolicy: IfNotPresent
  41. ports:
  42. - containerPort: 5000
  43. # 该容器的资源限制, 错误注入可使其达到峰值 #
  44. resources:
  45. limits:
  46. cpu: "0.4"
  47. memory: 128Mi

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

</>复制代码

  1. ---
  2. # 为 fault injection 创建 service 分配端口 #
  3. ---
  4. apiVersion: v1
  5. kind: Service
  6. metadata:
  7. name: your-microapp-with-faultinjection
  8. namespace: default
  9. spec:
  10. selector:
  11. # deployment identifier
  12. # 这个标签要与 deployment 中相对应
  13. app: sidecar-fault-injection
  14. ports:
  15. - protocol: TCP
  16. port: 5000
  17. nodePort: 30050
  18. type: NodePort
  19. ---
  20. # 相应的 deployment 配置( 与原应用配置在一起 )
  21. ---
  22. apiVersion: extensions/v1beta1
  23. kind: Deployment
  24. metadata:
  25. name: your-microapp-with-faultinjection
  26. namespace: default
  27. spec:
  28. replicas: 1
  29. template:
  30. metadata:
  31. labels:
  32. # svc identifier
  33. # 这个标签要与 service 中相对应
  34. app: sidecar-fault-injection
  35. spec:
  36. containers:
  37. # 你原来应用的 container 信息
  38. - name: your-micro-app
  39. image: your-docker-name/project:1.0
  40. imagePullPolicy: IfNotPresent
  41. env:
  42. - name: PATH_VALUE
  43. value: "example"
  44. ports:
  45. - containerPort: 80
  46. # ------------------- #
  47. # Sidecar 错误注入模块的 container
  48. - name: fault-injection-sidecar
  49. image: xinyaotian/micro-fault-injection:1.0.0
  50. imagePullPolicy: IfNotPresent
  51. ports:
  52. - containerPort: 5000
  53. # ------------------- #
  54. ---

在我自己的实验集群上,利用 Istio 启动该服务,并对其注入内存故障后,可以在 Grafana 监控面板上清晰地看到微服务 Pod 的内存忽高忽低,非常有趣。 错误注入的结果如下图所示。

</>复制代码

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

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

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

小结

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

致谢

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/33011.html

相关文章

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

    摘要:故障注入为您的微服务注入故障以验证集群性能由于导师和实验室师兄们的科研需要,本人专门以的模式设计了一个用于错误注入的微服务模块。 故障注入 Sidecar——为您的微服务注入故障以验证集群性能! 由于导师和实验室师兄们的科研需要,本人专门以 Sidecar的模式设计了一个用于错误注入的微服务模块。该模块可以与任何微服务应用共同部署运行,为其模拟cpu、内存等错误。 本项目的 Githu...

    waterc 评论0 收藏0
  • 结合 Google quicklink,react 项目实现页面秒开

    摘要:最后,状态管理与同构实战这本书由我和前端知名技术大佬颜海镜合力打磨,凝结了我们在学习实践框架过程中的积累和心得。 对于前端资讯比较敏感的同学,可能这两天已经听说了 GoogleChromeLabs/quicklink这个项目:它由 Google 公司著名开发者 Addy Osmani 发起,实现了:在空闲时间预获取页面可视区域内的链接,加快后续加载速度。如果你没有听说过 Addy Os...

    warkiz 评论0 收藏0
  • React 进阶设计与控制权问题

    摘要:盘点一下,模式反应了典型的控制权问题。异步状态管理与控制权提到控制权话题,怎能少得了这样的状态管理工具。状态管理中的控制主义和极简主义了解了异步状态中的控制权问题,我们再从全局角度进行分析。 控制权——这个概念在编程中至关重要。比如,轮子封装层与业务消费层对于控制权的争夺,就是一个很有意思的话题。这在 React 世界里也不例外。表面上看,我们当然希望轮子掌控的事情越多越好:因为抽象层...

    superw 评论0 收藏0

发表评论

0条评论

X1nFLY

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<