写点什么

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

  • 2019-07-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-07-29 08:4211881
用户头像

发布了 564 篇内容, 共 407.5 次阅读, 收获喜欢 730 次。

关注

评论

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

为什么中国出了这么多厉害的互联网公司,但没有自己设计过编程语言?

代码制造者

编程语言 低代码 企业信息化 零代码 编程开发

Woman、man、camera、TV:如何做一个完整的深度学习应用

LeanCloud

学习 程序员 互联网 容器 LeanCloud

区块链是一个有去无返的奇幻旅程

CECBC

区块链

Android |《看完不忘系列》之dagger

哈利迪

android

难以遏制的人因差错-Go的日志工具之痛

田晓亮

微服务 Go 语言

面经手册 · 第7篇《ArrayList也这么多知识?一个指定位置插入就把谢飞机面晕了!》

小傅哥

Java 数据结构 面试 小傅哥 ArrayList

零代码简史

明道云

SaaS

CRM企业到底该不该做PaaS?

ToB行业头条

PaaS SaaS CRM

科普小知识:区块链与分布式系统

CECBC

区块链 分布式

使用 K8s 进行作业调度实战分享

后端进阶

学习 Kubernetes 容器 k8s 调度式分布

OPPO互联网DevSecOps实践

OPPO安全

DevOps 安全

甲方日常2

句子

工作 随笔杂谈 日常

Redis系列(一):Redis简介及环境安装

简爱W

Redis系列(二):Redis的5种数据结构及其常用命令

简爱W

Flink-键值分区状态-10

小知识点

scala 大数据 flink

解决数据指数级增长挑战,英特尔如何又快又好提供领导力产品?

最新动态

迎接物联网时代,区块链大有可为

CECBC

云计算 大数据 区块链技术

前端智能化的加速时刻:华为机器视觉的创新方程式

脑极体

聊聊微服务

炜娓道来程序人生

架构 微服务 SOA

Apache Pulsar 2.6.1 版本正式发布:2.6.0 功能增强版,新增 OAuth2 支持

Apache Pulsar

消息队列 Apache Pulsar 消息系统 消息中间件

第11周总结+作业

林毋梦

Docker 镜像构建之 Dockerfile

哈喽沃德先生

Docker 容器 微服务

性能相关,内存

Linuxer

性能

面试官再问你Http请求过程,怼回去!

架构师修行之路

HTTP TCP/IP

Java | 你知道快速搭建一个spring boot项目该怎么做吗?

简爱W

炒股不要看K线图(分享最近学习投资的一点心得)

Nick

投资 理财

《搞定1》读书笔记

超超不会飞

月度工作汇报,为什么要全球直播?

赵新龙

TGO鲲鹏会 技术社区 开源社区

【Elasticsearch 技术分享】—— ES 查询检索数据的过程,是什么样子的?

程序员小航

Java elasticsearch 搜索 ES Lucene Elastic Search

有选择才会有困惑

escray

学习 面试

Luajit字节码分析之KSTR

whosemario

lua

混沌工程实践:使用SMI和Linkerd进行故障注入_文化 & 方法_Alex Leong_InfoQ精选文章