Linkerd 2.10(Step by Step)—混沌工程之注入故障

398 阅读4分钟

Linkerd 2.10 系列

Linkerd 2.10 中文手册持续修正更新中:

使用 Service Mesh InterfaceTraffic Split API 很容易将故障注入应用程序。 TrafficSplit 允许您将一定比例的流量重定向到特定后端。 这个后端是完全灵活的,可以返回任何你想要的响应——500 秒、超时甚至疯狂的有效载荷。

books demo 是展示这种行为的好方法。整体拓扑如下:

21-topology.png

在本指南中,您将把一些请求从 webapp 拆分到 books。 大多数请求最终会到达正确的 books 目的地,但其中一些将被重定向到有问题的后端。 此后端将为每个请求返回 500 秒并将错误注入 webapp 服务。 不需要更改代码,并且由于此方法是配置驱动(configuration driven)的, 因此可以将其添加到集成测试和 CI 管道中。 如果你真的过着混沌工程(chaos engineering)的 lifestyle,甚至可以在生产中使用故障注入。

先决条件

要使用本指南,您需要在集群上安装 Linkerd 及其 Viz 扩展。

设置服务

首先,将 books 示例应用程序添加到您的集群:

kubectl create ns booksapp && \
  linkerd inject https://run.linkerd.io/booksapp.yml | \
  kubectl -n booksapp apply -f -

由于此清单在其他地方用作 demo,因此已配置错误率(error rate)。 为了展示故障注入的工作原理,需要去除错误率,以便有一个可靠的基线(reliable baseline)。 要将 bookapp 的成功率提高到 100%,请运行:

kubectl -n booksapp patch deploy authors \
  --type='json' \
  -p='[{"op":"remove", "path":"/spec/template/spec/containers/0/env/2"}]'

过了一会儿,统计数据会显示 100% 的成功率。您可以通过运行以下命令来验证这一点:

linkerd viz -n booksapp stat deploy

输出最终看起来有点像:

NAME      MESHED   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONN
authors      1/1   100.00%   7.1rps           4ms          26ms          33ms          6
books        1/1   100.00%   8.6rps           6ms          73ms          95ms          6
traffic      1/1         -        -             -             -             -          -
webapp       3/3   100.00%   7.9rps          20ms          76ms          95ms          9

创建有问题的后端

将错误注入到 booksapp 中需要一个配置为返回错误的服务。 为此,您可以启动 NGINX 并通过运行将其配置为返回 500s:

cat <<EOF | linkerd inject - | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: error-injector
  namespace: booksapp
data:
 nginx.conf: |-
    events {}
    http {
        server {
          listen 8080;
            location / {
                return 500;
            }
        }
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: error-injector
  namespace: booksapp
  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
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/nginx.conf
              subPath: nginx.conf
      volumes:
        - name: nginx-config
          configMap:
            name: error-injector
---
apiVersion: v1
kind: Service
metadata:
  name: error-injector
  namespace: booksapp
spec:
  ports:
  - name: service
    port: 8080
  selector:
    app: error-injector
EOF

注入故障

随着 booksapp 和 NGINX 的运行,现在是时候在现有的后端(backend)、books 和 新创建的 error-injector 之间部分地分割流量了。 这是通过向集群添加 TrafficSplit 配置来实现的:

cat <<EOF | kubectl apply -f -
apiVersion: split.smi-spec.io/v1alpha1
kind: TrafficSplit
metadata:
  name: error-split
  namespace: booksapp
spec:
  service: books
  backends:
  - service: books
    weight: 900m
  - service: error-injector
    weight: 100m
EOF

当 Linkerd 看到流向 Books 服务的流量时, 它会向原始服务发送 9⁄10 个请求,向错误注入器(error injector)发送 1⁄10 个请求。 您可以通过运行 stat 并显式过滤来自 webapp 的请求来查看它的样子:

linkerd viz -n booksapp routes deploy/webapp --to service/books

与之前的 stat 命令只查看服务器收到的请求不同, 这个 routes 命令过滤到所有由 webapp 发出的 发往 books 服务本身的请求。输出应显示 90% 的成功率:

ROUTE       SERVICE   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99
[DEFAULT]     books    90.08%   2.0rps           5ms          69ms          94ms

在这种情况下,您正在查看 service 而不是 deployment。 如果你运行这个命令并查看 deploy/books,成功率仍然是 100%。 这样做的原因是 error-injector 是一个完全独立的 deployment, 并且流量正在服务级别(service level)转移。 请求永远不会到达 books pod,而是重新路由到错误注入器的 pod。

清理

要从集群中删除本指南中的所有内容,请运行:

kubectl delete ns booksapp
我是为少
微信:uuhells123
公众号:黑客下午茶
加我微信(互相学习交流),关注公众号(获取更多学习资料~)