GMTC深圳站本周日开幕,14大专题全部上线,完整日程>> 了解详情
写点什么

混沌工程实践:使用 SMI 和 Linkerd 进行故障注入

  • 2019 年 7 月 29 日
  • 本文字数:2687 字

    阅读完需:约 9 分钟

混沌工程实践:使用SMI和Linkerd进行故障注入

应用程序故障注入是混沌工程的一种形式,在微服务应用程序中人为地增加某些服务的错误率,以查看它对整个系统的影响。传统上,需要在服务代码中添加某种类型的故障注入库,才能对应用程序进行故障注入,值得庆幸的是,服务网格提供了一种无需修改或重构服务的应用程序故障注入方法。



结构良好的微服务应用程序有一个特点,它可以优雅地容忍单点服务故障。当这些故障以服务崩溃的形式出现时,Kubernetes 在修复服务崩溃故障方面做的非常好,它可以通过创建新的 Pods 替换崩溃的 Pods 的方式来修复这些故障。然而,故障也可能更加微妙,如导致服务返回的错误率升高。对于这种类型的故障,Kubernetes 就不能自动修复了,仍然会导致部分功能丧失。


使用流量分割 SMI API 注入错误

使用服务网格接口(Service Mesh Interface,SMI)的流量分割API(Traffic Split API)可以轻松实现应用程序故障注入。这是一种与实现无关且跨服务网格的故障注入方式。


为了实现这种形式的故障注入,首先,我们部署一个只返回错误的新服务。它既可以是一个简单的服务,比如一个配置成返回 HTTP 500 的 NGINX 服务,也可以是一个更复杂的服务,返回我们为了测试某些条件而专门设计的错误。其次,我们创建一个流量分割资源,用该资源来指导服务网格将目标服务流量按照百分比发送到错误服务上。例如,通过将 10%的服务流量发送到错误服务上,来人为地实现向该服务注入 10%的错误率。


我们一起看一个使用 Linkerd 作为服务网格实现的示例。


示例

首先,我们安装 Linkerd CLI,并将它部署到 Kubernetes 集群上:


> curl https://run.linkerd.io/install | sh> export PATH=$PATH:$HOME/.linkerd2/bin> linkerd install | kubectl apply -f -> linkerd check
复制代码


然后,我们安装一个“booksapp”示例应用程序:


> linkerd inject https://run.linkerd.io/booksapp.yml | kubectl apply -f -
复制代码


该应用程序的某个服务已经配置了错误率,但这个示例是为了说明,我们不需要任何支持也可以在应用程序中注入错误,所以,需要删除应用程序中配置的错误率:


> kubectl edit deploy/authors# Find and remove these lines:#        - name: FAILURE_RATE#          value: "0.5"
复制代码


我们看到应用程序可以正常运行了:


> linkerd stat deployNAME             MESHED   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONNauthors             1/1   100.00%   6.6rps           3ms          58ms          92ms          6books               1/1   100.00%   8.0rps           4ms          81ms         119ms          6traffic             1/1         -        -             -             -             -          -webapp              3/3   100.00%   7.7rps          24ms          91ms         117ms          9
复制代码


现在,我们创建一个错误服务。在此,我使用配置成返回 HTTP 500 状态代码的 NGINX,创建一个名为 error-injector.yaml 的文件:


apiVersion: apps/v1kind: Deploymentmetadata:  name: error-injector  labels:    app: error-injectorspec:  selector:    matchLabels:      app: error-injector  replicas: 1  template:    metadata:      labels:        app: error-injector    spec:      containers:        - name: nginx          image: nginx:alpine          ports:          - containerPort: 80            name: nginx            protocol: TCP          volumeMounts:            - name: nginx-config              mountPath: /etc/nginx/nginx.conf              subPath: nginx.conf      volumes:        - name: nginx-config          configMap:            name: error-injector-config---apiVersion: v1kind: Servicemetadata:  labels:    app: error-injector  name: error-injectorspec:  clusterIP: None  ports:  - name: service    port: 7002    protocol: TCP    targetPort: nginx  selector:    app: error-injector  type: ClusterIP---apiVersion: v1data: nginx.conf: |2
events { worker_connections 1024; }
http { server { location / { return 500; } } }kind: ConfigMapmetadata: name: error-injector-config
复制代码


部署 error-injector.yaml 文件 :


> kubectl apply -f error-injector.yaml
复制代码


现在,我们创建一个流量分割资源,它会将 10%的流量从“books”服务重定向到“error-injector”错误服务。该资源文件命名为 error-split.yaml:


apiVersion: split.smi-spec.io/v1alpha1kind: TrafficSplitmetadata:  name: error-splitspec:  service: books  backends:  - service: books    weight: 900m  - service: error-injector    weight: 100m
复制代码


部署 error-split.yaml 文件:


> kubectl apply -f error-split.yaml
复制代码


现在,我们可以看到从 webapp 到 books 的调用错误率为 10%:


> linkerd routes deploy/webapp --to service/booksROUTE       SERVICE   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99[DEFAULT]     books    90.66%   6.6rps           5ms          80ms          96ms
复制代码


我们还可以看到应用程序是如何优雅地处理这些故障:


> kubectl port-forward deploy/webapp 7000 &> open http://localhost:7000
复制代码


如果多刷几次页面,我们有时会看到内部服务错误页面。



关于应用程序是如何处理服务错误的,我们已经学到了一些有价值的东西,现在,我们通过简单的删除流量分割资源,来恢复我们的应用程序:


> kubectl delete trafficsplit/error-split
复制代码


结论

在本文中,通过使用 SMI API(由 Linkerd 提供支持)动态地将一部分流量重定向到简单的“始终失败”的目标服务,我们演示了一种在服务级别快速简便地进行故障注入的方式。这种方式的优势在于,我们仅通过 SMI API 就可实现故障注入,而无需更改任何应用程序代码。


当然,故障注入是一个很泛的话题,还有很多更复杂的故障注入方式,包括路由失败、让匹配特定条件的请求失败、或者在整个应用程序拓扑中传播单个“毒丸”请求。这些类型的故障注入需要比本文所涵盖内容更多的支持机制。


Linkerd 是一个由云原生计算基金会(Cloud Native Computing Foundation,CNCF)托管的社区项目。Linkerd 托管在GitHub上,在SlackTwittermailing lists上社区也很活跃,感兴趣的开发者可以下载试用。


原文链接:


https://linkerd.io/2019/07/18/failure-injection-using-the-service-mesh-interface-and-linkerd/index.html


2019 年 7 月 29 日 08:4211116
用户头像

发布了 153 篇内容, 共 64.5 次阅读, 收获喜欢 402 次。

关注

评论

发布
暂无评论
发现更多内容

一个34岁出来面试还被拒绝的Android程序员有多惨?

android 程序员 移动开发

【淘系技术】超详解析Flutter渲染引擎_业务想创新,不了解底层原理怎么行

android 程序员 移动开发

【技术漫谈】Android高手进阶,这个必须要学 !

android 程序员 移动开发

一次面试被问到ArrayMap,原理及源码分析详解

android 程序员 移动开发

一直认为Android不好找工作的同学,你的问题在这里!

android 程序员 移动开发

一种清晰, 便于扩展android项目架构方案

android 程序员 移动开发

【干货】Android 一线互联网面试题汇总,13模块200

android 程序员 移动开发

【CSS Master】选择器四种基本类型

devpoint

CSS CSS语法 11月日更

【透镜系列】看穿 _ 触摸事件分发 _

android 程序员 移动开发

一位30多岁已婚已育没有车贷男程序员的不安

android 程序员 移动开发

【建议收藏】面试没亮点?给你一份Android热门三方库源码面试宝典及学习笔记

android 程序员 移动开发

【基础01】Android 开发到底是做什么?

android 程序员 移动开发

【整理篇】Flutter 常用第三方库、插件

android 程序员 移动开发

【自学Android】使用DataBinding,ViewModel,LiveData完成点赞小功能

android 程序员 移动开发

【自学Flutter】18 TabBar、TabBarView

android 程序员 移动开发

快速创建一个Django项目,Python环境也给你安排了

老表

Python django 个人博客 web开发 11月日更

一篇文章教你搞清楚——Kotlin-进阶---不变型、协变

程序员 移动开发

【Java转Android】34

android 程序员 移动开发

【干货推荐】Android市场今非昔比,Android开发者该学习哪些东西提高竞争力

android 程序员 移动开发

【面试总结】Android-开发者值得深入思考的几个面试问答分享

android 程序员 移动开发

【Java转Android】50

android 程序员 移动开发

一波Android面试(附答案)

android 程序员 移动开发

一位Android大牛的BAT面试心得与经验总结

android 程序员 移动开发

【自学Flutter】3

android 程序员 移动开发

一个自学Android-人的第三年的面经分享

android 程序员 移动开发

一款Android开发者神器,从此不怕Show case

android 程序员 移动开发

【Flutter桌面篇】Flutter&Windows应用尝鲜

android 程序员 移动开发

【自学Flutter】20

android 程序员 移动开发

一个简单强大且灵活的 MVP 框架。

android 程序员 移动开发

一封给Android开发者 UI 自动化测试上手指南

android 程序员 移动开发

解构服务风险治理

方勇(gopher)

微服务 OLAP SRE 服务治理

2021星空论坛:破局创新,论道数字化转型

2021星空论坛:破局创新,论道数字化转型

混沌工程实践:使用SMI和Linkerd进行故障注入-InfoQ