硬核干货——《中小企业 AI 实战指南》免费下载! 了解详情
写点什么

混沌工程实践:使用 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:4211825
用户头像

发布了 538 篇内容, 共 383.2 次阅读, 收获喜欢 717 次。

关注

评论

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

发展靠扩大人力规模,而不是技术研发创新,国内软件行业如何破局?

龙归科技

开源项目 Idaas 龙归科技 统一软件市场 ArkID

阿里的职级是如何上升的,是工作经验还是能力?(附阿里面试题)

程序知音

Java 阿里巴巴 java面试 后端技术 八股文

LCD液晶屏和LED显示屏有什么区别?

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家

1对1直播源码:运行多个任务,资源如何切换?

开源直播系统源码

软件开发 一对一直播源码 直播系统源码 语音连麦app

「GitLab篇」如何用Git平台账号登录建木CI

Jianmu

开源 持续集成 CI/CD 持续部署 流水线

内网场景 Dubbo 微服务接入观测云

观测云

从入门到高手,数据从业者的成长一般都要经过哪些阶段?

雨果

数据工程师必备技能

太强了!字节大佬的《设计模式宝典》越读越有意思!

退休的汤姆

Java、 面经 社招 Java工程师 秋招

自动化元数据管理的“七宗最”?

雨果

元数据

IntelliJ IDEA 设置 IBM Semeru JDK

HoneyMoose

IPQ4019 IPQ4029 ,wallys ,802.11ac Outdoor Metal Waterproof Enclosure Metal Outdoor

wallys-wifi6

教育行业运维审计用什么堡垒机好?有什么作用?

行云管家

网络安全 教育 堡垒机 IT运维 运维审计

科创人·望繁信创始人索强:中国版流程挖掘注定有完全不同的活法

科创人

ArkID 企业级开源 IDaaS/IAM 统一身份认证授权管理解决方案

龙归科技

开源项目 iam SSO Idaas

开源一夏 |企业内部应用接入钉钉获取部门及人员信息

六月的雨在InfoQ

开源 钉钉 API 钉钉开放平台 8月月更

2022年中国生鲜电商年度综合分析

易观分析

电商 生鲜

什么样的数据架构可以彻底解决企业数据孤岛的问题?

雨果

数据孤岛

所有人!把膝盖准备好,这份“保姆级”的RabbitMQ笔记,你不服不行

退休的汤姆

面试 RabbitMQ 社招 Java工程师 秋招

NFTScan 与 Bulletime 在 NFT 底层数据方面达成战略合作

NFT Research

区块链 NFT 合作伙伴

零故障支持数百场重大会议成功举办,HW云会议做了这些事

科技怪咖

技术开发人员:一款远超Hue的SQL工具!

雨果

sql

IBM Semeru Windows 下的安装

HoneyMoose

云会议玩法升级

sofiya

Hadoop与数据湖是什么关系?终于有人说明白了!

雨果

hadoop 数据湖

如何完美的进行数字化转型?

雨果

数字化转型

大型软件团队协作中的常见难题和避坑策略|ONES 研发管理大师课

万事ONES

阿里资深架构师熬夜纯手写的238页微服务容器化开发实战笔记

退休的汤姆

面试 微服务 社招 Java工程师 秋招

【IT运维】Linux运维需要掌握哪些技能?

行云管家

Linux 运维 linux运维 IT运维

MAUI + Masa Blazor 开发带自动更新功能的安卓App

MASA技术团队

.net blazor MASA MAUI Xamarin

一箭双雕!刷完阿里P8架构师spring学习笔记+源码剖析,涨薪8K

退休的汤姆

Java 面试 阿里 Java工程师 spring、

Node js 开发入门 —UDP 编程,小白也能轻松学会

CRMEB

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