前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用服务网格接口和Linkerd进行故障注入

使用服务网格接口和Linkerd进行故障注入

作者头像
CNCF
发布2019-12-04 16:27:17
1.1K0
发布2019-12-04 16:27:17
举报
文章被收录于专栏:CNCF

作者:Alex Leong

应用程序故障注入(failure injection)是混沌工程(chaos engineering)的形式之一,我们在其中人为地增加微服务应用程序中某些服务的错误率,以查看这对整个系统有什么影响。传统上,你需要在服务代码中添加某种类型的故障注入库,以便进行应用程序故障注入。值得庆幸的是,服务网格为我们提供了一种注入应用程序故障的方法,而无需修改或重新构建我们的服务。

结构良好的微服务应用程序的一个特点,是它能够优雅地容忍单个服务的失败。当这些故障以服务崩溃的形式出现时,Kubernetes通过创建新的pod来替换已经崩溃的pod,在治愈这些故障方面做得非常好。然而,失败也可能更加微妙,导致服务返回更高的错误率。这些类型的故障不能由Kubernetes自动修复,但仍然会导致功能损失。

使用流量分割SMI API注入故障

通过使用服务网格接口(Service Mesh Interface)的流量分割API(Traffic Split API),我们可以很容易地注入应用程序故障。这允许我们以一种与实现无关、跨服务网格工作的方式进行故障注入。

为此,我们首先部署一个只返回错误的新服务。这可以像配置为返回HTTP 500响应的NGINX服务一样简单,也可以是更复杂的服务,返回专门设计的错误,以执行你希望测试的某些条件。然后,我们创建一个流量分割资源,该资源指示服务网格将目标服务流量的百分比发送到错误服务。例如,通过将服务流量的10%发送给错误服务,我们向该服务注入了一个人工的10%故障率。

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

例子

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

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

现在我们将安装booksapp示例应用程序:

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

此应用程序中的一个服务配置了错误率。这个演示的重点,是表明我们可以在应用程序中不需要任何支持就可以注入故障,所以让我们删除配置的故障率:

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

我们现在应该看到应用程序是健康的:

代码语言:javascript
复制
> linkerd stat deploy
NAME             MESHED   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONN
authors             1/1   100.00%   6.6rps           3ms          58ms          92ms          6
books               1/1   100.00%   8.0rps           4ms          81ms         119ms          6
traffic             1/1         -        -             -             -             -          -
webapp              3/3   100.00%   7.7rps          24ms          91ms         117ms          9

现在我们可以创建错误服务了。在这里,我将使用NGINX配置为只响应HTTP状态码500。创建一个名为error-injector.yaml的文件:

代码语言:javascript
复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: error-injector
  labels:
    app: error-injector
spec:
  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: v1
kind: Service
metadata:
  labels:
    app: error-injector
  name: error-injector
spec:
  clusterIP: None
  ports:
  - name: service
    port: 7002
    protocol: TCP
    targetPort: nginx
  selector:
    app: error-injector
  type: ClusterIP
---
apiVersion: v1
data:
 nginx.conf: |2


    events {
        worker_connections  1024;
    }


    http {
        server {
            location / {
                return 500;
            }
        }
    }
kind: ConfigMap
metadata:
  name: error-injector-config

和部署它:

代码语言:javascript
复制
> kubectl apply -f error-injector.yaml

现在我们可以创建一个流量分割资源,它将把10%的图书服务定向到错误服务。创建一个名为error-split.yaml的文件:

代码语言:javascript
复制
apiVersion: split.smi-spec.io/v1alpha1
kind: TrafficSplit
metadata:
  name: error-split
spec:
  service: books
  backends:
  - service: books
    weight: 900m
  - service: error-injector
    weight: 100m

和部署它:

代码语言:javascript
复制
> kubectl apply -f error-split.yaml

我们现在可以看到从webapp调用到书籍10%的故障率:

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

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

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

看起来其实不太好!如果刷新页面几次,有时会看到内部服务器错误页面。

我们学习了一些有价值的东西,关于我们的应用程序如何面对服务错误。让我们恢复我们的应用程序,只需删除流量分割资源:

代码语言:javascript
复制
> kubectl delete trafficsplit/error-split

总结

在本文中,通过使用SMI API(由Linkerd提供)将一部分流量动态重定向到一个简单的“总是失败”目的地,我们演示了在服务级别进行故障注入的快速而简单的方法。这种方法的美妙之处在于,我们能够完全通过SMI API来完成它,而不需要更改任何应用程序代码。

当然,故障注入是一个广泛的主题,还有许多更复杂的方法来注入故障,包括某些路由故障、只匹配特定条件的请求故障或在整个应用程序拓扑中传播单个“毒丸”请求。这些类型的故障注入将需要比这篇文章所涵盖的更多的设定。

Linkerd是一个社区项目,由CNCF(Cloud Native Computing Foundation,云原生计算基金会)托管。如果你有功能需求、问题或评论,我们欢迎你加入我们快速增长的社区!Linkerd代码托管在GitHub上,我们在Slack、Twitter和邮件列表上都有一个蓬勃发展的社区。来一起玩吧!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CNCF 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档